opengl-VAO也存储Texrture单元调用

opengl- does VAO store texrture unit calls as well

本文关键字:单元 调用 Texrture 存储 opengl-VAO      更新时间:2023-10-16

创建 VAO、VBO 和应用纹理的最基本基础是这样的:

unsigned int VBO, VAO, EBO;   //#1
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);    //#2

对于创建纹理:

unsigned int texture1, texture2;  
// texture 1
// ---------
glGenTextures(1, &texture1); //#3
glBindTexture(GL_TEXTURE_2D, texture1); //#4
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
unsigned char *data = stbi_load(FileSystem::getPath("resources/textures/container.jpg").c_str(), &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);  

//some more code , inside the render loop
glActiveTexture(GL_TEXTURE0);   #5
glBindTexture(GL_TEXTURE0, texture1);   #6
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE0, texture1);
glDrawElements(...);
glfwSwapBuffers(...);
//end of render loop

根据我从learnopengl的理解,从第#1行到第#2行,调用存储在VAO这就是为什么我们不必一遍又一遍地编写这些东西,我们只需要切换VAO进行绘图。
但是,从第#3行到第#6行的代码是否也存储在VAO中?如果是,那我们为什么不直接在第#35 行之后写 #99 行呢?如果不是,如果我们使用多个VAOs,我们如何将特定的纹理单元链接到特定的VAO

编辑:

在 glBindTexture(GL_TEXTURE_2D, texture1( 之后,继续进行的纹理调用会影响当前绑定的纹理,不是吗?那么这是否意味着glActiveTexture(...(也会影响当前绑定的纹理? 为什么我们在使用 glBindTexture(...( 激活纹理后再次绑定纹理?

第 1 行和第 2 行"存储在 VAO 中"的原因是因为这些函数就是这样做的。这些函数在当前绑定的顶点数组对象中设置状态。

顶点数组对象,顾名思义,是处理顶点数组的对象。纹理管理、纹理存储和使用纹理进行渲染与顶点数组无关。因此,这些函数都不会以任何方式影响 VAO 状态,就像修改vector<int>的内容不会修改某些list<float>对象的内容一样。

如果我们使用多个 VAO,我们如何将特定的纹理单元链接到特定的 VAO?

同样,VAO 处理顶点数据。纹理不是顶点数据,因此 VAO 不关心它们,反之亦然。您不会链接纹理和 VAO。

您可以使用 VAO 和纹理(以及其他内容(来执行渲染。VAO 和纹理在渲染过程中各自执行不同的操作,因此彼此之间没有直接关系。