2010-11-07 121 views
0

我目前正在研究一个过程星球生成工具,它通过将一个立方体映射到一个球体,然后将高度贴图应用于每个面以生成地形来工作。纹理VBOs(顶点缓冲区对象)

我使用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的。

为什么绑定纹理不起作用?

回答

1

为什么绑定纹理不起作用?

描述非常具体的你看到的行为,或更好地将URL附加到屏幕截图,在尝试解决图形问题时有很长的路要走。

接下来,您需要包含gl错误状态,或者至少要证明在您检查的代码中,如果glGetError()不返回GL_NO_ERROR,那么将失败。

尽管您故意忽略了索引缓冲区对象的定义,但您的VBO /绘图元素状态看起来很合理,所以我们会相信您会发送真正的索引到您的glDrawElements()调用中。为了进行健全性检查,请使用原始索引指针调用glDrawElements()而不是为元素绑定VBO。

您还省略了Vertex的类型定义,它需要知道您提供给glTexCoordPointer()的偏移量是否与结构定义一致。

最后,我猜测论坛上的大多数人都不知道“自由图像”,我相信这是你用来加载纹理的声明。如果存在纹理问题,则由于使用此第三方库代表您设置纹理的不透明特性而无法看到。

如果他们混淆了纹理ID,请设置不支持的换行模式,不要将缩小过滤器设置为与预期的mipmapping(开/关),未启用纹理一致或设置纹理环境模式基本几何颜色的调制不如您所期望的 - 所有这些都会使纹理化不起作用/似乎正在工作。

要排除故障,只需使用该库进行纹理加载并使用它们提供的纹理ID。然后自行设置滤镜模式和纹理环境。在排除故障时关闭mipmap。纹理不完整的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
glClientActiveTexture(GL_TEXTURE0+textueIDs[0]); 

你想在这里做什么?

活动纹理单元与随机纹理对象无关。