我要绘制具有两个纹理的对象矩形和仅具有一个纹理的三角形。我关注这个网站
LearnOpenGL.com - Textrues
https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.2.textures_combined/textures_combined.cpp
使用绘制三角形,我实现如下:
Shader ourShaderTriangle("vshader.glsl", "fshader.glsl");
float firstTriangle[] = {
// positions // colors //textcoord
-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom right
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 1.0f, // bottom left
-0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f // top
};//first
unsigned int VBO1, VAO1;
glGenVertexArrays(1, &VAO1);
glGenBuffers(1, &VBO1);
glBindVertexArray(VAO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
//position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//color
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
//textCoord
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
片段:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D textureTriangle;
void main()
{
FragColor = texture(textureTriangle, TexCoord);
}
加载纹理:我使用其他纹理“ container2.png”。我将其存储在“ texture3”中
glGenTextures(1, &texture3);
glBindTexture(GL_TEXTURE_2D, texture3);
// 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
data = stbi_load(FileSystem::getPath("resources/textures/container2.png").c_str(), &width, &height, &nrChannels, 0);
if (data)
{
// note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
在绘图功能中:
//bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
// render container
ourShader.use();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//
ourShaderTriangle.use();
glBindTexture(GL_TEXTURE_2D, texture3);
glBindVertexArray(VAO1);
glDrawArrays(GL_TRIANGLES, 0, 3);
//
但是三角形仍在使用纹理单位0(GL_TEXTURE0)。不使用我想要的纹理
我尝试使用“ glDisable”和“ glDeleteTextures”,但是它不起作用。
你能帮我吗?
答案 0 :(得分:1)
OpenGL是一个状态引擎。由glActiveTexture
设置的当前纹理单位是全局状态。因此,以下对glBindTexture
的所有调用都将纹理绑定到纹理单元1。
如果要将texture3
绑定到纹理单元0,则必须在将纹理绑定到纹理目标之前更改纹理单元:
ourShaderTriangle.use();
glActiveTexture(GL_TEXTURE0); // <---
glBindTexture(GL_TEXTURE_2D, texture3);
glBindVertexArray(VAO1);
glDrawArrays(GL_TRIANGLES, 0, 3);
如果要使用其他纹理单位,则必须更改纹理采样器制服的绑定点。
这可以通过Binding point Layout Qualifier在着色器代码中完成(为此,至少必须使用GLSL 4.20版)。例如1表示纹理单元1:
#version 420 core
layout(binding = 1) uniform sampler2D textureTriangle;
另一种方法是在通过glUseProgram
安装程序之后,将纹理单元(1)分配给纹理采样器统一:
GLuint program = // program "ourShaderTriangle"
GLint texTriLoc = glGetUniformLocation(program, "textureTriangle");
// ...
glActiveTexture(GL_TEXTURE1);
// ...
ourShaderTriangle.use();
glUniform1i(texTriLoc, 1); // <----
glBindTexture(GL_TEXTURE_2D, texture3);
glBindVertexArray(VAO1);
glDrawArrays(GL_TRIANGLES, 0, 3);