C++ 显示OpenGL纯色而不是纹理
所以,我在这个网站和其他网站上查看了所有类似的问题,但我没有找到为什么我的纹理无法加载的答案。我确信纹理是正确读取的,但是,它只是没有正确应用。这是我的密码: 获取纹理:C++ 显示OpenGL纯色而不是纹理,c++,opengl,mapping,textures,C++,Opengl,Mapping,Textures,所以,我在这个网站和其他网站上查看了所有类似的问题,但我没有找到为什么我的纹理无法加载的答案。我确信纹理是正确读取的,但是,它只是没有正确应用。这是我的密码: 获取纹理: glGenTextures(NumTextures, textures); glActiveTexture( GL_TEXTURE0 ); // load and bind tree texture readPPM6("textures/tree_trunk.pbm", treeTex); glBindTexture(
glGenTextures(NumTextures, textures);
glActiveTexture( GL_TEXTURE0 );
// load and bind tree texture
readPPM6("textures/tree_trunk.pbm", treeTex);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB,
GL_UNSIGNED_BYTE, treeTex);
绑定对象:
// VAO[Tree]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vElements[TreeE]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*treeIndices.size(), treeIndices.data(), GL_STATIC_DRAW);
glBindVertexArray(vArrays[TreeA]);
glBindBuffer(GL_ARRAY_BUFFER, vBuffers[TreeB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*treeVertices.size() + sizeof(vec2) * 90, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat)*treeVertices.size(), treeVertices.data());
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat)*treeVertices.size(), sizeof(vec2)*90,
treeTexCoords);
glUseProgram( texture );
vPosition = glGetAttribLocation( texture, "vPosition" );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vPosition);
vTexCoord = glGetAttribLocation( texture, "vTexCoord" );
glVertexAttribPointer( vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
(const void*) ((sizeof(GLfloat) * treeVertices.size())));
glEnableVertexAttribArray( vTexCoord );
glUniform1i(glGetUniformLocation(texture, "texture"), 0);
glBindVertexArray(0);
绘制树:
glUseProgram(texture);
proj_loc = glGetUniformLocation(texture, "projection");
model_view_loc = glGetUniformLocation(texture, "modelview");
glUniformMatrix4fv(proj_loc, 1, GL_TRUE, projmat);
glUniformMatrix4fv(model_view_loc, 1, GL_TRUE, modelmat);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(0xFFFF);
glBindVertexArray(vArrays[TreeA]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vElements[TreeE]);
glEnable(GL_TEXTURE_2D);
glActiveTexture( GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawElements(GL_TRIANGLE_STRIP, treeIndices.size(), GL_UNSIGNED_SHORT, NULL);
glDisable(GL_PRIMITIVE_RESTART);
glDisable(GL_TEXTURE_2D);
glUseProgram(0);
glBindVertexArray(0);
创建树的方式:
getCylinderVertices(treeVertices, 10.0, 3.0, 10);
getCylinderIndices(treeIndices, 10);
getConeVertices(treeVertices, 10.0, 15.0, 6.0, 10);
for (int i = 0; i < 10; i++)
{
treeIndices.push_back(60+i*3);
treeIndices.push_back(60+i*3+1);
treeIndices.push_back(60+i*3+2);
treeIndices.push_back(0xFFFF);
}
treeTexCoords = new vec2[90];
for (int i = 0; i < 10; i++)
{
treeTexCoords[i*6] = vec2(0.0, 0.0);
treeTexCoords[i*6+1] = vec2(0.0, 0.2);
treeTexCoords[i*6+2] = vec2(0.0, 0.0);
treeTexCoords[i*6+3] = vec2(1.0, 0.2);
treeTexCoords[i*6+4] = vec2(1.0, 0.0);
treeTexCoords[i*6+5] = vec2(0.0, 0.0);
}
for (int i = 0; i < 30; i++)
{
treeTexCoords[60+i] = vec2(0.0,0.0);
}
片段着色器:
#version 330 core
in vec2 texCoord;
uniform sampler2D texture;
void main()
{
gl_FragColor = texture2D(texture, texCoord);
}
在解决了缓冲区子数据分配问题后,现在的树是这样的:
作为参考,这是我正在使用的图像:
我已经解决了最后一个问题,读者正在阅读一个作为图像一部分的结束线,因此所有内容都被转移到下一种颜色。谢谢大家的帮助。我很惊讶这段代码没有导致崩溃,
sizeof(vec2)*90
是第二次调用glBufferSubData(…)
时应该使用的,因为纹理坐标数组中的浮点组件数量是顶点位置数组中组件数量的一半。当用数据填充缓冲区时,VBO的存储和客户端内存中的纹理坐标数组都已溢出
sizeof(treeTexCoords)
绝对不是您想要的,因为您已经动态分配了该阵列!如果您尝试使用分配给new
的内存指针来获取静态大小数组的大小,则可以使用sizeof(…)
来获取该数组的大小,但只会得到指针本身的大小。因此,在您的系统上,sizeof(treeTexCoords)
可能是4或8
glBindVertexArray (vArrays [TreeA]);
glBindBuffer (GL_ARRAY_BUFFER, vBuffers [TreeB]);
//
// @CORRECTION #1
//
glBufferData (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size () +
sizeof (vec2) * 90,
NULL, GL_STATIC_DRAW);
glBufferSubData (GL_ARRAY_BUFFER, 0,
sizeof (GLfloat) * treeVertices.size (),
treeVertices.data ());
//
// @CORRECTION #2
//
glBufferSubData (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size (),
sizeof (vec2) * 90,
treeTexCoords);
更正#1分配适当的存储量(而不是足够存储所有顶点+1个指针)
更正#2只读取到treeTexCoords
的末尾,而不是溢出
根据
treeVertices
的声明方式,可能还有其他问题-您能否编辑问题以显示treeVertices
的声明?我假设它类似于std::vector
如果更改tree\u trunk.pbm图像,树的颜色是否会改变?以确保文件本身已加载并在着色器中使用)。另外,尝试更改片段着色器以显示uv,以确保正确设置texCoords:gl_FragColor=vec4(texCoord.x,texCoord.y,1.0,1.0);图像改变时,颜色也会改变。当我按照你的建议改变碎片的颜色时,一切都变成蓝色。所以,不知怎的,我猜所有的u,v都被设置为0.0,0.0,或者纹理坐标没有被创建。如何确保坐标设置正确?您是否尝试过从着色器中删除未使用的“顶点”和“法线”属性?是的,我昨天意识到了这个问题并解决了它,是的,treeVertices是一个向量,我将发布我现在得到的图像,可能我阅读图像时确实有问题。
glBindVertexArray (vArrays [TreeA]);
glBindBuffer (GL_ARRAY_BUFFER, vBuffers [TreeB]);
//
// @CORRECTION #1
//
glBufferData (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size () +
sizeof (vec2) * 90,
NULL, GL_STATIC_DRAW);
glBufferSubData (GL_ARRAY_BUFFER, 0,
sizeof (GLfloat) * treeVertices.size (),
treeVertices.data ());
//
// @CORRECTION #2
//
glBufferSubData (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size (),
sizeof (vec2) * 90,
treeTexCoords);