OpenGL GLSL 纹理函数总是返回 vec4(1,1,1,1),白色三角形
OpenGL GLSL texture function always returning vec4(1,1,1,1), white triangle
我正在尝试将 2D 纹理映射到三角形。但是目前,我只能得到一个没有任何纹理的具有渐变颜色的三角形。这意味着,我在 glsl 中的纹理函数总是 return vec4(1,1,1,1) 并且我的 textCoords 正在工作。我该如何解决?任何建议都会对尝试有所帮助!
顺便说一句,已经为此工作了 3 天。
纹理class:
构造函数:
Texture::Texture(const std::string& fileName){
int width, height, numComponents;
//float* imageData = stbi_loadf(fileName.c_str(), &width, &height, &numComponents, 4);
unsigned char* imageData = stbi_load(fileName.c_str(), &width, &height, &numComponents, 4);
if(imageData == NULL){
cerr << "Texture loading failed for "<<fileName<< endl;
}
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
stbi_image_free(imageData);
}
纹理绑定函数:
void Texture::Bind(){
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture);
}
在我的 main.cpp:
m_shader.generateProgramObject();
m_shader.attachVertexShader( getAssetFilePath("VertexShader.vs").c_str() );
m_shader.attachFragmentShader( getAssetFilePath("FragmentShader.fs").c_str() );
m_shader.link();
// texture created here
texture = Texture("Assets/bricks.jpg");
// enable vertex attribute indices
glGenVertexArrays(1, &m_vao_triangle);
glBindVertexArray(m_vao_triangle);
// Enable the attribute index location for "position" when rendering.
GLint positionAttribLocation = m_shader.getAttribLocation( "position" );
glEnableVertexAttribArray(positionAttribLocation);
GLint textCoordLocation = m_shader.getAttribLocation( "atextCoord" );
glEnableVertexAttribArray(textCoordLocation);
// Restore defaults
glBindVertexArray(0);
CHECK_GL_ERRORS;
上传三角形数据到缓冲区
vec3 triangleVertices[] = {
// Construct equalaterial triangle
vec3(0.0f, 0.0f, 0.0f),
vec3(0.25f, 1.0f, 0.0),
vec3(0.5f, 0.0f, 0.0f)
};
vec2 textCoords[] = {
vec2(1.0f, 0.0f),
vec2(0.25f, 1.0f),
vec2(0.5f, 0.0f)};
// Generate a vertex buffer object to hold the triangle's vertex data.
glGenBuffers(1, &m_vbo_triangle);
//-- Upload triangle vertex data to the vertex buffer:
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_triangle);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERRORS;
//====generate buffer for holding texture coordinates====
glGenBuffers(1, &m_uv_triangle);
glBindBuffer(GL_ARRAY_BUFFER, m_uv_triangle);
glBufferData(GL_ARRAY_BUFFER, sizeof(textCoords), textCoords,
GL_STATIC_DRAW);
// Unbind the target GL_ARRAY_BUFFER, now that we are finished using it.
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERRORS;
将缓冲区数据映射到着色器
glBindVertexArray(m_vao_triangle);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_triangle);
GLint positionAttribLocation = m_shader.getAttribLocation( "position" );
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, m_uv_triangle);
GLint textCoordLocation = m_shader.getAttribLocation( "atextCoord" );
glVertexAttribPointer(textCoordLocation,2, GL_FLOAT, GL_FALSE, 0, nullptr);
//-- Unbind target, and restore default values:
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
CHECK_GL_ERRORS;
上传统一到着色器
m_shader.enable();
...
GLint uniformLocation_diffuse = m_shader.getUniformLocation("diffuse");
glUniform1i(uniformLocation_diffuse, 0);
CHECK_GL_ERRORS;
m_shader.disable();
CHECK_GL_ERRORS;
在我的绘制函数中:
glBindVertexArray(m_vao_triangle);
// below I tried, but didn't work
// glClear(GL_STENCIL_BUFFER_BIT);
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glEnable(GL_DEPTH_TEST);
texture.Bind();
// do these below:
// glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, texture.m_texture);
m_shader.enable();
glDrawArrays(GL_TRIANGLES, 0, 3);
m_shader.disable();
// Restore defaults
glBindVertexArray(0);
CHECK_GL_ERRORS;
这里我也会附上我的着色器
顶点着色器:
#version 330
in vec3 position;
in vec2 atextCoord;
uniform mat4 transform;
out vec2 textCoord;
void main() {
gl_Position = transform * vec4(position, 1.0);
textCoord = atextCoord;
}
还有我的片段着色器:
#version 330
uniform sampler2D diffuse;
out vec4 fragColor;
in vec2 textCoord;
void main() {
fragColor = vec4(texture(diffuse, textCoord).rgb,1.0) * vec4(textCoord,0.0,1.0);
// texture(...) shows vec4(1,1,1,1)
// radiant colour can only prove my textCoord is working
// fragColor = texture(diffuse, textCoord); <- only shows a default texture
}
here is the running result
Here is the texture image
我找到了一种让它起作用的方法。
我复制纹理构造函数中的每一行并将其粘贴到 draw(),而不是调用 texture.Bind()。
看起来我在准备绘制几何图形之前制作了纹理,这种方式有效。
但我仍然必须知道为什么会这样。对于编码风格,我仍然必须将我的代码放在 Texture class 中。您介意提供解决方案吗?
it looks like this right now
我正在尝试将 2D 纹理映射到三角形。但是目前,我只能得到一个没有任何纹理的具有渐变颜色的三角形。这意味着,我在 glsl 中的纹理函数总是 return vec4(1,1,1,1) 并且我的 textCoords 正在工作。我该如何解决?任何建议都会对尝试有所帮助!
顺便说一句,已经为此工作了 3 天。
纹理class:
构造函数:
Texture::Texture(const std::string& fileName){
int width, height, numComponents;
//float* imageData = stbi_loadf(fileName.c_str(), &width, &height, &numComponents, 4);
unsigned char* imageData = stbi_load(fileName.c_str(), &width, &height, &numComponents, 4);
if(imageData == NULL){
cerr << "Texture loading failed for "<<fileName<< endl;
}
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
stbi_image_free(imageData);
}
纹理绑定函数:
void Texture::Bind(){
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture);
}
在我的 main.cpp:
m_shader.generateProgramObject();
m_shader.attachVertexShader( getAssetFilePath("VertexShader.vs").c_str() );
m_shader.attachFragmentShader( getAssetFilePath("FragmentShader.fs").c_str() );
m_shader.link();
// texture created here
texture = Texture("Assets/bricks.jpg");
// enable vertex attribute indices
glGenVertexArrays(1, &m_vao_triangle);
glBindVertexArray(m_vao_triangle);
// Enable the attribute index location for "position" when rendering.
GLint positionAttribLocation = m_shader.getAttribLocation( "position" );
glEnableVertexAttribArray(positionAttribLocation);
GLint textCoordLocation = m_shader.getAttribLocation( "atextCoord" );
glEnableVertexAttribArray(textCoordLocation);
// Restore defaults
glBindVertexArray(0);
CHECK_GL_ERRORS;
上传三角形数据到缓冲区
vec3 triangleVertices[] = {
// Construct equalaterial triangle
vec3(0.0f, 0.0f, 0.0f),
vec3(0.25f, 1.0f, 0.0),
vec3(0.5f, 0.0f, 0.0f)
};
vec2 textCoords[] = {
vec2(1.0f, 0.0f),
vec2(0.25f, 1.0f),
vec2(0.5f, 0.0f)};
// Generate a vertex buffer object to hold the triangle's vertex data.
glGenBuffers(1, &m_vbo_triangle);
//-- Upload triangle vertex data to the vertex buffer:
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_triangle);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERRORS;
//====generate buffer for holding texture coordinates====
glGenBuffers(1, &m_uv_triangle);
glBindBuffer(GL_ARRAY_BUFFER, m_uv_triangle);
glBufferData(GL_ARRAY_BUFFER, sizeof(textCoords), textCoords,
GL_STATIC_DRAW);
// Unbind the target GL_ARRAY_BUFFER, now that we are finished using it.
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERRORS;
将缓冲区数据映射到着色器
glBindVertexArray(m_vao_triangle);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_triangle);
GLint positionAttribLocation = m_shader.getAttribLocation( "position" );
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, m_uv_triangle);
GLint textCoordLocation = m_shader.getAttribLocation( "atextCoord" );
glVertexAttribPointer(textCoordLocation,2, GL_FLOAT, GL_FALSE, 0, nullptr);
//-- Unbind target, and restore default values:
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
CHECK_GL_ERRORS;
上传统一到着色器
m_shader.enable();
...
GLint uniformLocation_diffuse = m_shader.getUniformLocation("diffuse");
glUniform1i(uniformLocation_diffuse, 0);
CHECK_GL_ERRORS;
m_shader.disable();
CHECK_GL_ERRORS;
在我的绘制函数中:
glBindVertexArray(m_vao_triangle);
// below I tried, but didn't work
// glClear(GL_STENCIL_BUFFER_BIT);
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glEnable(GL_DEPTH_TEST);
texture.Bind();
// do these below:
// glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, texture.m_texture);
m_shader.enable();
glDrawArrays(GL_TRIANGLES, 0, 3);
m_shader.disable();
// Restore defaults
glBindVertexArray(0);
CHECK_GL_ERRORS;
这里我也会附上我的着色器 顶点着色器:
#version 330
in vec3 position;
in vec2 atextCoord;
uniform mat4 transform;
out vec2 textCoord;
void main() {
gl_Position = transform * vec4(position, 1.0);
textCoord = atextCoord;
}
还有我的片段着色器:
#version 330
uniform sampler2D diffuse;
out vec4 fragColor;
in vec2 textCoord;
void main() {
fragColor = vec4(texture(diffuse, textCoord).rgb,1.0) * vec4(textCoord,0.0,1.0);
// texture(...) shows vec4(1,1,1,1)
// radiant colour can only prove my textCoord is working
// fragColor = texture(diffuse, textCoord); <- only shows a default texture
}
here is the running result
Here is the texture image
我找到了一种让它起作用的方法。
我复制纹理构造函数中的每一行并将其粘贴到 draw(),而不是调用 texture.Bind()。 看起来我在准备绘制几何图形之前制作了纹理,这种方式有效。
但我仍然必须知道为什么会这样。对于编码风格,我仍然必须将我的代码放在 Texture class 中。您介意提供解决方案吗?
it looks like this right now