0

我目前正在开发一种程序行星生成工具,该工具通过获取一个立方体,将其映射到一个球体,然后将高度图应用于每个面以生成地形。

我为使用以下方法创建的每个面使用 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 附带的示例纹理管理器。

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

4

2 回答 2

1

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

非常具体地描述您所看到的行为,或者更好地将 URL 附加到屏幕截图,在尝试解决图形问题时大有帮助。

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

尽管您故意省略了索引缓冲区对象的定义,但您的 VBO / 绘制元素状态看起来很合理,因此我们相信您正在将真实索引发送到 glDrawElements() 调用。对于完整性检查,使用原始索引指针执行 glDrawElements() 调用,而不是为元素绑定 VBO。

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

最后,我猜论坛上的大多数人都不知道“免费图片”,我相信这就是您所说的用于加载纹理的内容。如果存在纹理问题,由于使用此 3rd 方库代表您设置纹理的不透明性质,因此无法看到。

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

要排除故障,只需使用库进行纹理加载并使用它们提供的纹理 ID。然后自己设置过滤模式和纹理环境。故障排除时关闭 mipmap。不完整的 mipmap 链是纹理时非常常见的错误。

您还可以关闭按片段操作以简化故障排除。禁用混合、深度测试和剪切。

假设您的纹理是二维的幂或您的实现支持 NPOT,请在绘制之前立即尝试这些设置:

glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_SCISOR_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);

于 2010-11-07T21:22:30.433 回答
1
glClientActiveTexture(GL_TEXTURE0+textueIDs[0]);

你想在这里做什么?

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

于 2010-11-07T21:53:09.397 回答