openGL drawElements - 一个额外的三角形,使用索引数组



我正在从.bmp文件中生成一个地形,作为策略游戏的早期前身。在我的代码中,我将BMP文件加载为openGL纹理,然后使用双循环生成坐标(x,y redChannel)。然后,我通过再次双重循环并生成 (x,y) 到 (x+1, y+1) 之间的正方形三角形来创建索引。但是,当我运行代码时,我最终会得到一个额外的三角形,从一行的末尾到下一行的开头,我似乎无法解决。只有当我使用不同的高度和足够大的地图时,或者至少在其他情况下它不可见时,才会发生这种情况。

这是代码:

void Map::setupVertices(GLsizei* &sizeP, GLint * &vertexArray, GLubyte* &colorArray){
    //textureNum is the identifier generated by glGenTextures
    GLuint textureNum = loadMap("heightmap.bmp");
    //Bind the texture again, and extract the needed data
    glBindTexture(GL_TEXTURE_2D, textureNum);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
    GLint i = height*width;
    GLubyte * imageData = new GLubyte[i+1];
    glGetTexImage(GL_TEXTURE_2D,0,GL_RED, GL_UNSIGNED_BYTE, &imageData[0]);
    //Setup varibles: counter (used for counting vertices)
    //VertexArray: pointer to address for storing the vertices. Size: 3 ints per point, width*height points total
    //ColorArray: pointer to address for storing the color data. 3 bytes per point.
    int counter = 0;
    vertexArray = new GLint[height*width*3];
    colorArray = new GLubyte[height*width*3];
    srand(time(NULL));
    //Loop through rows
    for (int y = 0; y < height; y++){
        //Loop along the line
        for (int x=0; x < width; x++){
            //Add vertices: x, y, redChannel
            //Add colordata: the common-color.
            colorArray[counter] = imageData[x+y*width];
            vertexArray[counter++] = x;
            colorArray[counter] = imageData[x+y*width];
            vertexArray[counter++] = y;
            colorArray[counter] =  imageData[x+y*width];//(float) (rand() % 255);
            vertexArray[counter++] = (float)imageData[x+y*width] /255 * maxHeight;
        }
    }
    //"Return" total vertice amount
    sizeP = new GLsizei(counter);
}
void Map::setupIndices(GLsizei* &sizeP, GLuint* &indexArray){
    //Pointer to location for storing indices. Size: 2 triangles per square, 3 points per triangle, width*height triangles
    indexArray = new GLuint[width*height*2*3];
    int counter = 0;
    //Loop through rows, don't go to top row (because those triangles are to the row below)
    for (int y = 0; y < height-1; y++){
        //Loop along the line, don't go to last point (those are connected to second last point)
        for (int x=0; x < width-1; x++){
            //
            //  TL___TR
            //  |  /  |
            //  LL___LR
             int lowerLeft = x + width*y;
             int lowerRight = lowerLeft+1;
             int topLeft = lowerLeft + width+1;
             int topRight =  topLeft + 1;
             indexArray[counter++] = lowerLeft;
             indexArray[counter++] = lowerRight;
             indexArray[counter++] = topLeft;
             indexArray[counter++] = topLeft;
             indexArray[counter++] = lowerRight;
             indexArray[counter++] = topRight;
        }
    }
    //"Return" the amount of indices
    sizeP = new GLsizei(counter);
}

我最终用这段代码绘制了这个:

void drawGL(){
    glPushMatrix();
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3,GL_INT,0,mapHeight);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(3,GL_UNSIGNED_BYTE,0,mapcolor);
    if (totalIndices != 0x00000000){
        glDrawElements(GL_TRIANGLES, *totalIndices, GL_UNSIGNED_INT, indices);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glPopMatrix();
}

这是结果的图片:

http://s22.postimg.org/k2qoru3kx/open_GLtriangles.gif

只有蓝线和黑色背景。http://s21.postimg.org/5yw8sz5mv/triangle_Error_Blue_Line.gif

似乎还有一个朝另一个方向发展,在最边缘的右边,但我现在假设它可能与同一个问题有关。

我会简化这部分:

         int lowerLeft = x + width * y;
         int lowerRight = (x + 1) + width * y;
         int topLeft = x + width * (y + 1);
         int topRight = (x + 1) + width * (y + 1);

问题看起来topLeft有一个额外的+ 1,当它应该只有+ width时。这会导致"顶部"顶点都沿一列移动。您可能不会注意到网格内的偏移量,并且正如您所指出的,在高度更改之前,它们不可见。

此外,返回new GLsizei(counter)似乎有点圆。为什么不直接通过GLsizei& counter.

这些可能也值得一看。对于许多过程对象,您可以使用条带基元来保存相当多的数据:

  • 生成带有三角形条带的平面
  • 三角形带用于网格结构

最新更新