【发布时间】:2013-01-13 01:42:04
【问题描述】:
我会直奔主题:
我已经为我的顶点创建了一个结构:
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似乎设置正确,纹理图像加载正确,但它不会显示。
我已经尝试搜索和尝试调试的不同方面,这包括:
- 确保已设置 glEnable(GL_TEXTURE_2D);
- 添加 glEnable(GL_LIGHTING) 和 glDisable(GL_LIGHTING);
- 使用 glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND);和 glDisable(GL_SCISSOR_TEST);在绑定纹理之前
- 提取错误
- 搜索奇怪的消息
- 仔细检查内存中的顶点缓冲区(实际上是遍历元素并交叉比较 *.dae 文件中的内容)
编辑
我正在使用 CG 着色器。这是顶点程序:
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),所以我在此基础上更改了一般描述。
解决方案编辑
非常感谢 cmets 中的几位小伙子,他们让我开阔了思路,从不同的角度看待问题,并实际进行了更多阅读。这是解决方案:
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 和 2),但没有赋予它们任何意义。哦,你不会将纹理绑定到 VBO;您将它们绑定到纹理单元并在 GLSL 中作为
uniform sampler*变量访问。 -
我有着色器,但没有在描述中指定它们(如果需要,我可以添加顶点和片段着色器功能)。它们在 glEnableVertexAttribArray(0); 之前启用。并在 glDisableVertexAttribArray(2) 之后禁用;我也在使用 CG 着色器,但它们的工作方式与我推测的相似。
-
您是否尝试将 UV 渲染为颜色?
-
请原谅我的无知,我不太擅长这些事情。如何再次将 UV 渲染为颜色?
-
@karmalis:只需将纹理坐标指定为输出颜色。我也有点不确定 Cg 如何将顶点属性位置分配给 VS_Main 参数。使用 GLSL,您要么必须使用 glGetAttributeLocation 根据其名称检索位置索引,要么在布局中显式分配它。
标签: c++ opengl rendering texture-mapping vertex-buffer