当前位置: 首页 > news >正文

openGL 三:矩阵和向量

1.使用glm数学库进行矩阵和向量的计算
2.位置坐标可以看做一个向量
3.向量的移动,缩放,旋转,都是可以通过和矩阵的计算得出
4.向量的缩放=乘一个44的矩阵
5.注意事项(有些版本的glm::mat4 不是默认构建一个单位4
4的矩阵),这个时候需要手动赋值,glm::mat4 matval = glm::mat4(1.0f);

#include "GL/glew.h"
#include "glfw3.h"
#include "SOIL2.h"
//glfw :graphics library framework 图形库框架
// 作用:1.用于创建和管理跨平台的窗口; 2. 处理输入,鼠标键盘等 ; 3.用于创建和管理opengl上下文//glew:opengl extension Wrangler 用于管理opengl 扩展的开源库
// 作用: 1.用于加载扩展函数,2.查询扩展支持
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"#include <stdio.h>
#include <iostream>//顶点着色器源码 glsl
const GLchar* vertexSource = "#version 330 core \n \layout(location=0) in vec3 position;\layout(location=1) in vec3 color;\layout(location=2) in vec2 texcoodr;\out vec4 outcolor;\out vec2 outtexcoodr;\uniform mat4 transformkk;\
void main()\
{\
gl_Position=transformkk*vec4(position, 1.0f); outcolor=vec4(color,1.0f); outtexcoodr=texcoodr;\
}";//GLSL 语言: mix, texture, sampler2D 采样器变量
const GLchar* fragmentSource = "#version 330 core \n \in vec4 outcolor;\in vec2 outtexcoodr;\out vec4 color;\uniform sampler2D ourtexture;\uniform sampler2D ourtexture2;\uniform float mixval;\void main(){\vec2 coord = vec2(outtexcoodr.x , 1.0f - outtexcoodr.y);\color = mix(texture(ourtexture,outtexcoodr),texture(ourtexture2,coord),mixval);\}";GLfloat mixval = 0.2f;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{if (key == GLFW_KEY_UP && action == GLFW_PRESS){mixval += 0.1f;if (mixval >= 1.0f){mixval = 1.0f;}}else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS){mixval -= 0.1f;if (mixval <= 0.0f){mixval = 0.0f;}}
}
int main()
{//初始化使用到的 glfw库glfwInit();//创建窗口GLFWwindow* window = glfwCreateWindow(600, 500, "opengl texture exercise", nullptr, nullptr);//指定当前上下文glfwMakeContextCurrent(window);//初始化opengl 扩展库glewInit();//创建目标着色器以及管线管理程序GLuint vertexShader, fragmentShader, program;GLint succeed;GLchar buff[512];//顶点着色器vertexShader = glCreateShader(GL_VERTEX_SHADER);//加载顶点着色器源码glShaderSource(vertexShader, 1, &vertexSource, (GLint*)0);//第三个参数,是指向一个整数数组,数组每个字符串的长度glCompileShader(vertexShader);//编译着色器源码glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &succeed);if (!succeed){glGetShaderInfoLog(vertexShader, 512, NULL, buff);//第三个参数:返回日志的实际长度,null表示不用返回}//片段着色器fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentSource, (GLint*)0);glCompileShader(fragmentShader);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &succeed);if (!succeed){glGetShaderInfoLog(fragmentShader, 512, NULL, buff);}//创建着色器程序program = glCreateProgram();glAttachShader(program, vertexShader);glAttachShader(program, fragmentShader);glLinkProgram(program);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//定义数据数组 ,矩形 == 两个三角形组成, 四个点,每个点对于的颜色值,和纹理坐标位置//GLfloat vertexArray[] = {//	/* 点位置				颜色				纹理坐标*///	0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f,//	0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f,//	-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,//	-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 2.0f,//};GLfloat vertexArray[] = {// Positions          // Colors           // Texture Coords0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f  // Top Left };//GLfloat vertexArray[] = {//	0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f,   0.51f, 0.51f,//	0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.51f, 0.49f,//	-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.49f, 0.49f,//	-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.49f, 0.51f,//};//元素数组三角形的点的数组索引GLuint eArray[] = {0, 1, 3,1, 2, 3};//创建顶点数组对象 VAO, 顶点缓存对象 VBO, 元素缓存对象EBOGLuint VAO, VBO, EBO;//创建顶点数组对象,用于管理和封装顶点缓存数组,以及数据解析方式。 一个顶点数组对象可以管理好几个数据缓存对象的配置信息//顶点属性指针,顶点缓存保存glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);//创建vboglGenBuffers(1, &VBO);//绑定顶点缓存对象glBindBuffer(GL_ARRAY_BUFFER, VBO);//在GPU创建缓和初始化 VBO 的数据存储,glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray), vertexArray, GL_STATIC_DRAW);//创建EBOglGenBuffers(1, &EBO);//绑定元素缓存对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//加载数据到CPU缓存glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(eArray), eArray, GL_STATIC_DRAW);//配置顶点属性指针:如何解析数据输入到顶点着色器里面,类似顶点着色器输入参数的一种数据格式//					顶点属性数组的索引, 个数, 类型, 是否标准化, 步长stride, 偏移量glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);//使能顶点属性数组:索引值glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);//解绑 顶点数组对象glBindBuffer(GL_ARRAY_BUFFER, 0);//纹理============================================================================================//1.0 创建纹理对象GLuint texture1, texture2;glGenTextures(1, &texture1);//2.0 绑定纹理对象glBindTexture(GL_TEXTURE_2D, texture1);//3.0 设置纹理配置参数值glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//超出纹理坐标的纹理如何处理:纹理环绕方式,x 轴== s 轴glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//超出纹理坐标的纹理如何处理:纹理环绕方式,Y 轴== T 轴glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //纹理过滤方式, 最近glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//线性//4.0 根据图片生成纹理图形int width, height;unsigned  char *image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);//设置2d纹理图像数据glGenerateMipmap(GL_TEXTURE_2D);//生成纹理的所有级别的缩放图像SOIL_free_image_data(image);glBindTexture(GL_TEXTURE_2D, 0); //相当于保存该纹理配置,不会弄乱/*GL_REPEAT	对纹理的默认行为。重复纹理图像。GL_MIRRORED_REPEAT	和GL_REPEAT一样,但每次重复图片是镜像放置的。GL_CLAMP_TO_EDGE	纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。GL_CLAMP_TO_BORDER	超出的坐标为用户指定的边缘颜色。*/glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);glGenerateMipmap(GL_TEXTURE_2D);//设置纹理缩放图像SOIL_free_image_data(image2);glBindTexture(GL_TEXTURE_2D, 0);//设置鼠标事件回调glfwSetKeyCallback(window, key_callback);while (!glfwWindowShouldClose(window)){glm::vec4 vect(1.0f, 1.0f, 0.0f, 1.0f);glm::mat4 transformkk = glm::mat4(1.0f); // ({ 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f });glfwPollEvents();glClearColor(0.5f, 0.5f, 0.2f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//清除缓存区: 颜色缓存区glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture1);glUniform1i(glGetUniformLocation(program, "ourtexture"), 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture2);glUniform1i(glGetUniformLocation(program, "ourtexture2"), 1);transformkk = glm::rotate(transformkk, (GLfloat)glfwGetTime()*5.0f, glm::vec3(0.0, 0.0, 1.0));transformkk = glm::translate(transformkk, glm::vec3(0.5, 0.5, 0.5));glUniformMatrix4fv(glGetUniformLocation(program, "transformkk"), 1, GL_FALSE, glm::value_ptr(transformkk));glUniform1f(glGetUniformLocation(program, "mixval"), mixval);//使能着色器程序glUseProgram(program);glBindBuffer(GL_ARRAY_BUFFER, VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glm::mat4 transformdd = glm::mat4(1.0f);transformdd = glm::translate(transformdd, glm::vec3(-0.5, 0.5, 0.0));transformdd = glm::scale(transformdd, glm::vec3(sin((GLfloat)glfwGetTime()), sin((GLfloat)glfwGetTime()), 1.0));glUniformMatrix4fv(glGetUniformLocation(program, "transformkk"), 1, GL_FALSE, glm::value_ptr(transformdd));glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glBindBuffer(GL_ARRAY_BUFFER, 0);glfwSwapBuffers(window);}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glfwTerminate();return 0;
};

相关文章:

openGL 三:矩阵和向量

1.使用glm数学库进行矩阵和向量的计算 2.位置坐标可以看做一个向量 3.向量的移动&#xff0c;缩放&#xff0c;旋转&#xff0c;都是可以通过和矩阵的计算得出 4.向量的缩放乘一个44的矩阵 5.注意事项&#xff08;有些版本的glm::mat4 不是默认构建一个单位44的矩阵&#xff09…...

Socket和Http的通讯原理,遇到攻击会受到哪些影响以及如何解决攻击问题。

德迅云安全-领先云安全服务与解决方案提供商 Socket和HTTP通信原理&#xff1a; Socket通信原理&#xff1a; Socket是一种应用程序编程接口&#xff08;API&#xff09;&#xff0c;用于在单个进程或多个进程之间进行通信。它提供了一种灵活的、异步的通信方式&#xff0c;使…...

【springboot】整合redis

1.前提条件:docker安装好了redis确定redis可以访问 可选软件: 2.测试代码 (1)redis依赖 org.springframework.boot spring-boot-starter-data-redis (2)配置redis &#xff08;3&#xff09; 注入 Resource StringRedisTemplate stringRedisTemplate; 对键进行操作 –o…...

回溯和分支算法

状态空间图 “图”——状态空间图 例子&#xff1a;农夫过河问题——“图”状态操作例子&#xff1a;n后问题、0-1背包问题、货郎问题(TSP) 用向量表示解&#xff0c;“图”由解向量扩张得到的解空间树。 ——三种图&#xff1a;n叉树、子集树、排序树 ​ 剪枝 不满住条件的…...

深入理解:指针变量的解引用 与 加法运算

前言 指针变量的解引用和加法运算是非常高频的考点&#xff0c;也是难点&#xff0c;因为对初学者的不友好&#xff0c;这就导致了各大考试都很喜欢在这里出题&#xff0c;通常会伴随着强制类型转换、二维数组、数组指针等一起考查大家对指针的理解。但是不要怕&#xff0c;也许…...

Docker 镜像构建的最佳做法

一、镜像分层 使用docker image history命令&#xff0c;可以看到用于在镜像中创建每个层的命令。 1、 使用docker image history命令查看创建的入门镜像中的层。 docker image history getting-started 您应该得到如下所示的输出&#xff1a; IMAGE CREATED…...

工作上Redis安装及配置

下载redis软件 第一步&#xff1a;解压压缩包 tar -zxvf redis-7.0.14.tar.gz 第二步&#xff1a;移动redis存放目录&#xff08;结合个人需求而定&#xff01;&#xff09; redis-7.0.14&#xff1a;解压后的文件路径 /usr/local&#xff1a;移动后的文件路径 mv redis-7.0.…...

电商项目之Web实时消息推送(附源码)

文章目录 1 问题背景2 前言3 什么是消息推送4 短轮询5 长轮询5.1 demo代码 6 iframe流6.1 demo代码 7 SSE7.1 demo代码7.2 生产环境的应用 &#xff08;重要&#xff09; 8 MQTT 1 问题背景 扩宽自己的知识广度&#xff0c;研究一下web实时消息推送 2 前言 文章参考自Web 实时消…...

上机实验四 哈希表设计 西安石油大学数据结构

实验名称&#xff1a;哈希表设计 &#xff08;1&#xff09;实验目的&#xff1a;掌握哈希表的设计方法及其冲突解决方法。 &#xff08;2&#xff09;主要内容&#xff1a; 已知一个含有10个学生信息的数据表&#xff0c;关键字为学生“姓名”的拼音&#xff0c;给出此表的一…...

Ubuntu22.04 交叉编译mp4V2 for Rv1106

一、配置工具链环境 sudo vim ~/.bashrc在文件最后添加 export PATH$PATH:/opt/arm-rockchip830-linux-uclibcgnueabihf/bin 保存&#xff0c;重启机器 二、下载mp4v2 下载路径&#xff1a;MP4v2 | mp4v2 三、修改CMakeLists.txt 四、执行编译 mkdir build cd buildcmak…...

缓存穿透、击穿、雪崩

缓存穿透&#xff1a; 指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上&#xff0c;导致系统瘫痪。 解决方案&#xff1a; 通常包括使用布隆过滤器或者黑白名单等方式来过滤掉无效请求&#xff0c;以及在应用程序中加入缓存预热…...

(1w字一篇理解透Unsafe类)Java魔法类:Unsafe详解

Java魔法类 Unsafe 文章导读&#xff1a;(约12015字&#xff0c;阅读时间大约1小时)1. Unsafe介绍2. Unsafe创建3. Unsafe功能3.1内存操作3.2 内存屏障3.3 对象操作3.4 数组操作3.5 CAS操作3.6 线程调度3.7 Class操作3.8 系统信息 4. 总结 JUC源码中的并发工具类出现过很多次 …...

Python的正则表达式使用

Python的正则表达式使用 定义使用场景查替换分割 常用的正则表达符号查原字符英文状态的句号点 .反斜杠 \英文的[]英文的()英文的?加号 星号 *英文状态的大括号 {} 案例 定义 正则表达式是指专门用于描述或刻画字符串内在规律的表达式。 使用场景 无法通过切片&#xff0c;…...

Elasticsearch:评估 RAG - 指标之旅

作者&#xff1a;Quentin Herreros&#xff0c;Thomas Veasey&#xff0c;Thanos Papaoikonomou 2020年&#xff0c;Meta发表了一篇题为 “知识密集型NLP任务的检索增强生成” 的论文。 本文介绍了一种通过利用外部数据库将语言模型 (LLM) 知识扩展到初始训练数据之外的方法。 …...

【2023.12.4练习】数据库知识点复习测试

概论 数据表&#xff1a;用于存储现实中数据的联系。 储存信息联系。 字段&#xff1a;又称列&#xff0c;如姓名、年龄、编号等。 记录&#xff1a;又称元组&#xff0c;为数据表中的一行&#xff0c;代表了一个实体的信息。 数据库&#xff08;DB&#xff09;&#xff1…...

【wvp】测试记录

ffmpeg 这是个莫名其妙的报错&#xff0c;通过排查&#xff0c;应该是zlm哪个进程引起的 会议室的性能 网络IO也就20M...

【若依框架实现上传文件组件】

若依框架中只有个人中心有上传图片组件&#xff0c;但是这个组件不适用于el-dialog中的el-form表单页面 于是通过elementui重新写了一个上传组件&#xff0c;如图是实现效果 vue代码 <el-dialog :title"title" v-model"find" width"600px"…...

玩转大数据5:构建可扩展的大数据架构

1. 引言 随着数字化时代的到来&#xff0c;大数据已经成为企业、组织和个人关注的焦点。大数据架构作为大数据应用的核心组成部分&#xff0c;对于企业的数字化转型和信息化建设至关重要。我们将探讨大数据架构的基本要素和原则&#xff0c;以及Java在大数据架构中的角色&…...

【华为数据之道学习笔记】非数字原生企业的特点

非数字原生企业的数字化转型挑战 软件和数据平台为核心的数字世界入口&#xff0c;便捷地获取和存储了大量的数据&#xff0c;并开始尝试通过机器学习等人工智能技术分析这些数据&#xff0c;以便更好地理解用户需求&#xff0c;增强数字化创新能力。部分数字原生企业引领着云计…...

Kubernetes学习笔记-Part.01 Kubernets与docker

目录 Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退 第一章 Kubernets与docker Docker是一种轻量级的容器…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...

职坐标物联网全栈开发全流程解析

物联网全栈开发涵盖从物理设备到上层应用的完整技术链路&#xff0c;其核心流程可归纳为四大模块&#xff1a;感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性&#xff0c;例如传感器选型需平衡精度与…...

iOS 项目怎么构建稳定性保障机制?一次系统性防错经验分享(含 KeyMob 工具应用)

崩溃、内存飙升、后台任务未释放、页面卡顿、日志丢失——稳定性问题&#xff0c;不一定会立刻崩&#xff0c;但一旦积累&#xff0c;就是“上线后救不回来的代价”。 稳定性保障不是某个工具的功能&#xff0c;而是一套贯穿开发、测试、上线全流程的“观测分析防范”机制。 …...

break 语句和 continue 语句

break语句和continue语句都具有跳转作用&#xff0c;可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...

Redis——Cluster配置

目录 分片 一、分片的本质与核心价值 二、分片实现方案对比 三、分片算法详解 1. ‌范围分片&#xff08;顺序分片&#xff09;‌ 2. ‌哈希分片‌ 3. ‌虚拟槽分片&#xff08;Redis Cluster 方案&#xff09;‌ 四、Redis Cluster 分片实践要点 五、经典问题解析 C…...

DOM(文档对象模型)深度解析

DOM(文档对象模型)深度解析 DOM 是 HTML/XML 文档的树形结构表示,提供了一套让 JavaScript 动态操作网页内容、结构和样式的接口。 一、DOM 核心概念 1. 节点(Node)类型 类型值说明示例ELEMENT_NODE1元素节点<div>, <p>TEXT_NODE3文本节点元素内的文字COMMEN…...