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

时间:2013-10-23 14:56:44

标签: c++ opengl indices

我正在从.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

似乎其中一个也在另一个方向,在最右边,但我现在想它可能与同一个问题有关。

1 个答案:

答案 0 :(得分:0)

我简化了这一部分:

         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。 这会导致&#34; top&#34;两个顶点都沿着一列移动。您可能没有注意到网格中的偏移量,正如您所指出的那样,它们在高度变化之前不可见。

此外,返回new GLsizei(counter)似乎有点圆了。为什么不直接传入GLsizei& counter

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