1

所以在我的程序中,我使用 OpenGL/GLSL 来构建一个正方形并对其进行纹理化。

它是现代的OpenGL 4.0+,所以不使用glBegin/glEnd等。

我的正方形由 2 个三角形组成,使用glDrawArrays(GL_TRIANGLES, 0, 6);

正如您在下面的函数中看到的那样,它创建了 2 个三角形。我在一个数组中使用了 18 个顶点,而实际上我只需要 12 个来创建一个正方形,因为其中 6 个用于两个三角形。它与 24 种颜色和 8 个文本坐标相同。

void Ground::constructGeometry(Shader* myShader)
{
    //Triangle 1 (x,y,z)
    vert[0]  =-dimY;  vert[1] = dimX;  vert[2] = dimZ; //Point 2
    vert[3]  =-dimY;  vert[4] =-dimX;  vert[5] = dimZ; //Point 1
    vert[6]  = dimY;  vert[7] =-dimX;  vert[8] = dimZ; //Point 4
    //Triangle 2 (x,y,z)
    vert[9]  = dimY; vert[10] =-dimX; vert[11] = dimZ; //Point 4
    vert[12] = dimY; vert[13] = dimX; vert[14] = dimZ; //Point 3
    vert[15] =-dimY; vert[16] = dimX; vert[17] = dimZ; //Point 2
    //Colours 1 (r,g,b,a)
    col[0]  = 1.0f;   col[1] = 0.0f;   col[2] = 0.0f;  col[3] = 1.0f;
    col[4]  = 1.0f;   col[5] = 0.0f;   col[6] = 0.0f;  col[7] = 1.0f;
    col[8]  = 1.0f;   col[9] = 0.0f;  col[10] = 0.0f; col[11] = 1.0f;
    //Colours 2 (r,g,b,a)
    col[12] = 1.0f;  col[13] = 0.0f;  col[14] = 0.0f; col[15] = 1.0f;
    col[16] = 1.0f;  col[17] = 0.0f;  col[18] = 0.0f; col[19] = 1.0f;
    col[20] = 1.0f;  col[21] = 0.0f;  col[22] = 0.0f; col[23] = 1.0f;

    //(s,t) coords for Tri 1
    tex[0] = 0.0;   tex[1] = 1.0;
    tex[2] = 0.0;   tex[3] = 0.0;
    tex[4] = 1.0;   tex[5] = 0.0;
    //(s,t) coords for Tri 2
    tex[6]  = 1.0;  tex[7] = 0.0;
    tex[8]  = 1.0;  tex[9] = 1.0;
    tex[10] = 0.0; tex[11] = 1.0;

    glGenVertexArrays(2, &m_vaoID[0]);
    glBindVertexArray(m_vaoID[0]);

    glGenBuffers(3, m_vboID);

    GLint vertexLocation= glGetAttribLocation(myShader->handle(), "in_Position");
    GLint colorLocation= glGetAttribLocation(myShader->handle(), "in_Color");
    GLint texCoordLocation = glGetAttribLocation(myShader->handle(), "in_TexCoord");
    glUniform1i(glGetUniformLocation(myShader->handle(), "DiffuseMap"), 0);

    glBindBuffer(GL_ARRAY_BUFFER, m_vboID[0]);
    glBufferData(GL_ARRAY_BUFFER, totalVerts *sizeof(GLfloat), vert, GL_STATIC_DRAW);
    glEnableVertexAttribArray(vertexLocation);
    glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, m_vboID[1]);
    glBufferData(GL_ARRAY_BUFFER, totalCols *sizeof(GLfloat), col, GL_STATIC_DRAW);
    glEnableVertexAttribArray(colorLocation);
    glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, m_vboID[2]);
    glBufferData(GL_ARRAY_BUFFER, totalTexs *sizeof(GLfloat), tex, GL_STATIC_DRAW);

    glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0,0);
    glEnableVertexAttribArray(texCoordLocation);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glEnableVertexAttribArray(0);
    glBindVertexArray(0);
}

怎样才能提高效率,所以在制作第二个三角形时,我可以使用已经使用过的 vert[x] 而不是再次声明相同的(第 4 点和第 2 点)?颜色也一样?

这对我下面的渲染功能有何影响?

void Ground::render(GLuint texName, Shader* myShader)                                   
{
    glUseProgram(myShader->handle());       //find shader passed
    glBindTexture(GL_TEXTURE_2D, texName);  //blending needed to use alpha channel
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindVertexArray(m_vaoID[0]);          //select first VAO
    glDrawArrays(GL_TRIANGLES, 0, 6);       //draw first object 0-3, then second 3-6

    glDisable(GL_BLEND);
    glUseProgram(0);
    glBindVertexArray(0);                   //unbind the vertex array object
}

显然,我想我只对 2 个三角形这样做是可以的,但是如果出于某种原因,我突然想要一大堆三角形,我不想写出数百个顶点......

4

3 回答 3

3

如果您想重用顶点,请使用glDrawElements()而不是。glDrawArrays()

glDrawElements接受一个索引数组参数,它允许您指定顶点数组中顶点的索引,从而可以多次使用它们。

于 2013-11-11T23:10:01.383 回答
2

作为使用 的(正确)答案的替代方法glDrawElements,您可以使用glDrawArrayswithGL_TRIANGLE_FAN而不是GL_TRIANGLES。一个扇形使用前三个顶点绘制一个三角形,然后每个后续顶点将使用新顶点、最后一个顶点和第一个顶点生成一个三角形。现在您的数组中只需要四个顶点(逆时针排列),调用如下所示:

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
于 2013-11-12T14:10:40.010 回答
1

您要求的称为索引渲染。基本思想是提供一个索引缓冲区,这些元素引用顶点数组中的顶点 ID。因此,对于共享一条边的两个三角形,您可以只定义 4 个角顶点,并且可以使用和索引数组,如{0,1,2, 2,1,3}. 你将不得不使用glDrawElements()来绘制。

您可能还想查看此 wiki 页面以了解现代 GL 中可用的绘图路径的概述。

于 2013-11-11T23:12:48.620 回答