我会直言不讳:
我为我的顶点创建了一个结构:
struct Vertex3D
{
Vector3D position;
Vector2D textureCoordinate;
Vector3D normal;
}
然后我导入一个特定的* .dae文件并将其绑定到OpenGL顶点缓冲区,该缓冲区由Vertex3D结构化顶点列表构成。一切顺利,网格导入并显示,我可以使用着色器操作它,但我有一个问题。
我还做的是加载并为其指定纹理。后来我试图以这种方式显示它:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, this->_entries[i].VB);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), 0); // Vertices
glVertexAttribPointer(8,2, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)sizeof(RomCommon::Vector3D)); // Supposed texture position
glVertexAttribPointer(2,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)(sizeof(RomCommon::Vector2D) + sizeof(RomCommon::Vector3D))); // Supposed normal position
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->_entries[i].IB);
glBindTexture(GL_TEXTURE_2D, 3);
glDrawElements(GL_TRIANGLES, this->_entries[i]._indexCount, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(8);
glDisableVertexAttribArray(2);
我的问题是没有显示纹理。只分配纹理第一个像素的颜色(在我的例子中是蓝色)。我已经使用gDEBugger调试整个过程,我可以看出VertexBuffer似乎设置正确,纹理图像正确加载,但不会显示。
我尝试过搜索并尝试调试的不同方面,其中包括:
修改
我正在使用CG Shaders。这是Vertex计划:
struct vsOutput {
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
float3 color : COLOR;
};
vsOutput VS_Main( float4 position : POSITION,
float2 texCoord : TEXCOORD0,
float3 color : COLOR,
uniform float4x4 ModelViewProj
)
{
vsOutput OUT;
OUT.position = mul(ModelViewProj, position);
OUT.texCoord = texCoord;
OUT.color = color;
return OUT;
}
片段计划:
struct fsOutput {
float4 color : COLOR;
};
fsOutput FS_Main(
float2 texCoord : TEXCOORD0,
uniform sampler2D decal : TEX0
)
{
fsOutput OUT;
OUT.color = tex2D(decal,texCoord);
return OUT;
}
如果有必要的话,我可以添加关于我的项目的更多细节,但是根据我的追踪,问题似乎在渲染顶点缓冲区的某个地方。
修改
我还发现因为我使用的是CG,所以vertexAttribPointers应该是不同的(8代表TEXCOORD0),所以我根据它改变了一般描述。
解决方案编辑
非常感谢评论中的几个人,他们开始考虑从不同的角度看问题并实际做更多的阅读。这是解决方案:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, this->_entries[i].VB);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), 0); // Vertices
glVertexAttribPointer(8,2, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)sizeof(RomCommon::Vector3D)); // Supposed texture position
glVertexAttribPointer(2,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)(sizeof(RomCommon::Vector2D) + sizeof(RomCommon::Vector3D))); // Supposed normal position
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->_entries[i].IB);
/* Solution start */
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(RomCommon::Vertex3D), (const GLvoid*)12);
glBindTexture(GL_TEXTURE_2D, 3);
glDrawElements(GL_TRIANGLES, this->_entries[i]._indexCount, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
/* Solution end */
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(8);
glDisableVertexAttribArray(2);
我的问题是我只是将纹理坐标传递给着色器,但没有将它推送到OpenGL状态机(如果这是一个很好的表达式)。 我认为这与我使用CG着色器而不是GLSL着色器这一事实有关,尽管我可能错了。代码基于我阅读的一些示例和解释,但它们都是基于GLSL着色器而且它们正在工作,因此是一种解决方案。 无论如何,它现在已经解决了。
答案 0 :(得分:1)
glBindTexture(GL_TEXTURE_2D, 3);
我要警惕在OpenGL上强制纹理对象ID。从技术上讲,应该工作,但使用glGenTextures()
获取纹理ID是一个更好的主意。