OpenGL 将纹理绑定到顶点缓冲区对象(使用 CG 着色器)
OpenGL binding textures to vertex buffer objects (with CG Shaders)
我会直奔主题:
我为我的顶点创建了一个结构:
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);
- 获取错误
- 搜索奇怪的消息
- 仔细检查内存中的顶点缓冲区(从字面上遍历 elemnt 并交叉比较 *.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),所以我根据它改变了一般描述。
解决方案编辑
非常感谢评论中的几个小伙子,他们打开了我的思维,从不同的角度看待问题,并实际上做了更多的阅读。这是解决方案:
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 着色器并且它们正在工作,因此是字典。无论如何,现在已经解决了。
glBindTexture(GL_TEXTURE_2D, 3);
我会谨慎地在 OpenGL 上强制使用纹理对象 ID。 从技术上讲,它应该可以工作,但使用 glGenTextures()
获取纹理 ID 是一个更好的主意。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++:TypeDef使用元组
- 使用std::multimap迭代器创建std::list
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用Google Mock来模拟gettimeofday()
- 如何使用默认参数等选择模板专业化
- 为什么使用 "this" 指针调用派生成员函数?
- 使用新行和不使用新行读取文件
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 如何确定我已使用非编码文件到达 EOF?
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 使用CMake创建QML插件
- 使用strcpy将char数组的元素复制到另一个数组
- 在c++中使用nlohmann从类到json的转换
- 使用指针从C++中的数组中获取最大值
- OpenGL 将纹理绑定到顶点缓冲区对象(使用 CG 着色器)