如何在 Opengl 中使用多个纹理解决此问题

How to fix this issue with multiple textures in Opengl

本文关键字:纹理 解决 问题 Opengl      更新时间:2023-10-16

我想将多个纹理发送到片段着色器,然后在那里混合它们。 但是由于某种原因,当我运行此代码时,仅显示纹理2。在我的片段着色器中,即使我只写 color=color1;比我也看到了Texure2。

我的片段着色器:

static const char* fragmentShaderSource = "n
#version 150 coren
in vec2 Texcoord;n
uniform sampler2D tex0;n
uniform sampler2D tex1;n
out vec4 color;n
void main(){n
vec4 color1=texture(tex0,Texcoord);n
vec4 color2=texture(tex1,Texcoord);n
color=mix(color1,color2,0.5);n
//color=color1;n
}n
";

我的多纹理代码:

GLuint textures[2];
glGenTextures(2, textures);
int width, height;
unsigned char* image;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE0, textures[0]);
image = SOIL_load_image("1.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(program, "tex0"), 0);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE1, textures[1]);
image = SOIL_load_image("2.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(program, "tex1"), 1);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

这是我的窗口循环:

while (!glfwWindowShouldClose(window)) {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
if (glfwGetKey(window, GLFW_KEY_E)) {
break;
}
glfwSwapBuffers(window);
glfwPollEvents();
}

如果需要,这是我的全部代码:

#define GLEW_STATIC
#include<glglew.h>
#include<GLFWglfw3.h>
#include<iostream>
#include<SOIL.h>
//////////////////////////////////////
static const char* vertexShaderSource = "n
#version 150 coren
in vec2 position;n
in vec3 inColor;n
in vec2 texcoord;n
out vec2 Texcoord;n
out vec3 Color;                                                              
void main(){n
Color=inColor;n
Texcoord=texcoord;n
gl_Position=vec4(position,0,1);n
}n";
static const char* fragmentShaderSource = "n
#version 150 coren
//uniform vec4 fragmentColor;n
in vec3 Color;n
in vec2 Texcoord;n
uniform sampler2D tex0;n
uniform sampler2D tex1;n
out vec4 color;n
void main(){n
vec4 color1=texture(tex0,Texcoord);n
vec4 color2=texture(tex1,Texcoord);n
color=mix(color1,color2,0.5);n
//color=color1;n
}n
";
//////////////////////////////////////

int main() {
if (!glfwInit())
return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(1024, 620, "Window", nullptr, nullptr);

glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;

if (glewInit() != GLEW_OK)
return -1;
GLfloat triangleVertices[] = {
0.5f,0.5f,1,0,0,1,0,
0.5f,-0.5f,0,1,0,1,1,
-0.5f,-0.5f,0,0,1,0,1,
-0.5f,0.5f,0,0,0,0,0
};
GLuint vao; 
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
GLuint elements[] = { 0,1,2 ,3,0,2};
GLuint ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
////////////////////////////////////////////////////////
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
GLint statusVertex;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &statusVertex);
if (!statusVertex) {
char buffer[1024];
glGetShaderInfoLog(vertexShader, 1024, NULL, buffer);
std::cout << "Error Compiling vertexShader:" << buffer << std::endl;
}

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
GLint statusFrag;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &statusFrag);
if (!statusFrag) {
char buffer[1024];
glGetShaderInfoLog(fragmentShader, 1024, NULL, buffer);
std::cout << "Error Compiling fragmentShader:" << buffer << std::endl;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindFragDataLocation(program, 0, "color");
glLinkProgram(program);//making connection
glUseProgram(program);
//////////////////////////////////////////////////////////



GLint positionAttrib = glGetAttribLocation(program, "position");
glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), nullptr);
glEnableVertexAttribArray(positionAttrib);
GLint colorAttrib = glGetAttribLocation(program, "inColor");
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), (void*)(2 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(colorAttrib);
GLint texAttrib = glGetAttribLocation(program, "texcoord");
glVertexAttribPointer(texAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), (void*)(5 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(texAttrib);
GLuint textures[2];
glGenTextures(2, textures);
int width, height;
unsigned char* image;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE0, textures[0]);
image = SOIL_load_image("1.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(program, "tex0"), 0);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE1, textures[1]);
image = SOIL_load_image("2.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(program, "tex1"), 1);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

/////////////////////////////////////////////////////////////
while (!glfwWindowShouldClose(window)) {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
if (glfwGetKey(window, GLFW_KEY_E)) {
break;
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

glBindTexture采用纹理目标而不是单位

目标是:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D、GL_TEXTURE_CUBE_MAP、GL_TEXTURE_1D_ARRAY、GL_TEXTURE_2D_ARRAY(以及扩展特定目标(。

纹理单元传递给glActiveTexture,这些单元是GL_TEXTURE0、GL_TEXTURE1等,也是采样器制服的设置。


将代码更改为

glActiveTexture(GL_TEXTURE0);
--- glBindTexture(GL_TEXTURE_2D, textures[0]);
+++ glBindTexture(GL_TEXTURE_2D, textures[0]);

glActiveTexture(GL_TEXTURE1);
--- glBindTexture(GL_TEXTURE_2D, textures[1]);
+++ glBindTexture(GL_TEXTURE_2D, textures[1]);