我目前正在开发一个程序行星生成工具,它通过采用立方体,将其映射到球体,然后将高度图应用于每个面来生成地形。
我正在使用VBO为每个面使用以下方法创建:
void Planet::setVertexBufferObject()
{
Vertex* vertices;
int currentVertex;
Vertex* vertex;
for(int i = 0; i < 6; i++)
{
// bottom face
if(i == 0)
{
glBindBuffer(GL_ARRAY_BUFFER, bottomVBO);
}
// top face
else if(i == 1)
{
glBindBuffer(GL_ARRAY_BUFFER, topVBO);
}
// front face
else if(i == 2)
{
glBindBuffer(GL_ARRAY_BUFFER, frontVBO);
}
// back face
else if(i == 3)
{
glBindBuffer(GL_ARRAY_BUFFER, backVBO);
}
// left face
else if(i == 4)
{
glBindBuffer(GL_ARRAY_BUFFER, leftVBO);
}
// right face
else
{
glBindBuffer(GL_ARRAY_BUFFER, rightVBO);
}
vertices = (Vertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
currentVertex = 0;
for(int x = 0; x < size; x++)
{
for(int z = 0; z < size; z++)
{
currentVertex = z * size + x;
vertex = &vertices[currentVertex];
vertex->xTextureCoord = (x * 1.0f) / 512.0f;
vertex->zTextureCoord = (z * 1.0f) / 512.0f;
Vector3 normal;
vertex->xNormal = normal.x;
vertex->yNormal = normal.y;
vertex->zNormal = normal.z;
vertex->x = heightMapCubeFace[i][x][z][0];
vertex->y = heightMapCubeFace[i][x][z][1];
vertex->z = heightMapCubeFace[i][x][z][2];
vertex->x *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
vertex->y *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
vertex->z *= (1.0f +((heightMaps[i][z][x]/256.0f) * 0.1));
}
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
我省略了setIndexBufferObject()方法,因为它工作正常。
然后我使用这种方法渲染球体:
void Planet::render()
{
// bottom face
glBindBuffer(GL_ARRAY_BUFFER, bottomVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bottomIBO);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(6 * sizeof(float)));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(3 * sizeof(float)));
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
TextureManager::Inst()->BindTexture(textueIDs[0]);
glClientActiveTexture(GL_TEXTURE0+textueIDs[0]);
glDrawElements(GL_TRIANGLE_STRIP, numberOfIndices, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// next face and so on...
正在使用免费图像加载纹理,正如您从上面的代码中可以看到的,我只是使用了带有freeimage的示例纹理管理器。
为什么绑定纹理不起作用?
答案 0 :(得分:1)
为什么绑定纹理不起作用?
非常具体地描述您所看到的行为,或者更好地将网址附加到屏幕截图,在尝试解决图形问题时会有很长的路要走。
接下来,如果glGetError()没有返回GL_NO_ERROR,则需要包含gl错误状态或者至少在代码中证明你正在检查和失败。
你的VBO / draw元素状态看起来很合理,虽然你故意省略了索引缓冲区对象的定义,所以我们会相信你正在向glDrawElements()调用发送真正的索引。对于完整性检查,使用原始索引指针执行glDrawElements()调用,而不是为元素绑定VBO。
您还省略了Vertex的类型定义,这需要知道您为glTexCoordPointer()提供的偏移量是否与结构定义一致。
最后,我猜测论坛上的大多数人都不知道“免费图片”,我相信这就是你所说的用于加载纹理的内容。如果出现纹理问题,则无法看到,因为使用此第三方库代表您设置纹理的不透明性。
如果他们混淆了纹理ID,请设置不支持的包装模式,不要将缩小过滤器设置为与预期的mipmapping(开/关)一致,不启用纹理,或者设置纹理环境模式,使得使用基本几何颜色的调制并不像您期望的那样 - 所有这些都会使纹理不起作用/看起来不起作用。
要进行故障排除,只需使用库进行纹理加载,并使用它们提供的纹理ID。然后自己设置过滤模式和纹理环境。在排除故障时关闭mipmapping。纹理化时,不完整的mipmap链是一个非常常见的错误。
您还可以关闭每个片段操作以简化故障排除。禁用混合,深度测试和剪裁。
假设您的纹理是二维的力量或您的实现支持NPOT,请在绘制前立即尝试这些设置:
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST);
glColor4f(1.0f,1.0f,1.0f,1.0f);
glBindTexture(GL_TEXTURE_2D,texID);
glTexEnvi(GL_TEXTURE_ENV_MODE,GL_REPLACE); //关闭调制
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //关闭mipmapping
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); //关闭重复
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
答案 1 :(得分:1)
glClientActiveTexture(GL_TEXTURE0+textueIDs[0]);
你想在这做什么?
活动纹理单元与随机纹理对象无关。