C++ OpenGL-使用纹理绘制正方形的最简单方法

C++ OpenGL-使用纹理绘制正方形的最简单方法,c++,opengl,vbo,vao,C++,Opengl,Vbo,Vao,通常我会画一个有如下纹理的正方形: Vertex2D* vertex = (Vertex2D*) vbo->lock(); vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color; vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vert

通常我会画一个有如下纹理的正方形:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}
  • 创建具有4个坐标(正方形的a、B、C、D)的VBO
  • 创建一个带有4个索引(a、C、D和B、C、D)的EBO,告诉我要从2个三角形中画一个正方形
  • 使用纹理绘制此元素
没有EBO阵列难道没有最简单的方法吗?

因为它不是很方便使用。。。如果我想这样使用:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}
VAO=[-0.8f,0.5f,0.0f,…]

EBO=[0,1,3,1,2,3,…]

然后我需要从VAO中删除一个正方形。。。然后我还需要从我的EBO数组中删除索引并重新排列它。 有更好的方法吗

没有EBO阵列不是最简单的方法吗

复制顶点并使用
glDrawArrays()

没有EBO阵列不是最简单的方法吗


复制顶点并使用
gldrawArray()

您可以使用DrawArray绘制索引

大概是这样的:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}

可以使用DrawArray绘制索引

大概是这样的:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}

如果你只想画一个有纹理的正方形,你应该考虑做一个新的空VAO,只需调用<代码> GLD射线(GL3 TangangLeLead,0. 3);<代码>

顶点着色器如下所示:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}

映射变量告诉FraseTestError纹理坐标是什么。

< P>如果你只想画一个有纹理的正方形,你应该考虑做一个新的空VAO,只需调用<代码> GLD射线(GL3 TangangLeLead,0. 3);<代码>

顶点着色器如下所示:

Vertex2D* vertex = (Vertex2D*) vbo->lock();
        vertex[0].x = x[0]; vertex[0].y = y[0]; vertex[0].u = u[0]; vertex[0].v = v[0]; vertex[0].color = color;
        vertex[1].x = x[0]; vertex[1].y = y[1]; vertex[1].u = u[0]; vertex[1].v = v[1]; vertex[1].color = color;
        vertex[2].x = x[1]; vertex[2].y = y[1]; vertex[2].u = u[1]; vertex[2].v = v[1]; vertex[2].color = color;
        vertex[3].x = x[1]; vertex[3].y = y[0]; vertex[3].u = u[1]; vertex[3].v = v[0]; vertex[3].color = color;
vbo->unlock();

shader->bind();
vbo->bind();
vao->bind();
tex->bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex->unbind();
vao->unbind();
vbo->unbind();
shader->unbind();
out vec2 mapping;

void main()
{
    float size = 1.0f;

    vec2 offset;
    switch(gl_VertexID)
    {
    case 0:
        //Bottom-left
        mapping = vec2(0.0f, 0.0f);
        offset = vec2(-size, -size);
        break;
    case 1:
        //Top-left
        mapping = vec2(0.0f, 1.0f);
        offset = vec2(-size, size);
        break;
    case 2:
        //Bottom-right
        mapping = vec2(1.0, 0.0);
        offset = vec2(size, -size);
        break;
    case 3:
        //Top-right
        mapping = vec2(1.0, 1.0);
        offset = vec2(size, size);
        break;
    }

     gl_Position = vec4(offset, 0.0f, 1.0f);
}

映射变量告诉fragmentshader纹理坐标是什么。

您没有指定目标的GL版本。使用可编程管道,您可以少做这个属性,因此VBO和EBO都可能被完全跳过。不过,您仍然需要将顶点数据获取到着色器(除非它是常量),但现在还有其他可能性。您没有指定目标的GL版本。使用可编程管道,您可以少做这个属性,因此VBO和EBO都可能被完全跳过。不过,你仍然需要将顶点数据添加到着色器中(除非它是常量),但是现在还有其他的可能性。但这会给顶点带来50%的开销,对吗?这是折衷,对。但这会给顶点带来50%的开销,对吗?这是折衷,是的。这是我最喜欢的全屏四元体渲染方式。但是我想补充一点,如果你想画大量的四边形,这可能会成为一个巨大的性能问题。顶点着色器在每个顶点上做了大量的工作,甚至可能包括分支,这取决于编译器的聪明程度。当然,这也满足了问题的“简单”部分。这是我最喜欢的渲染全屏四边形的方法。但是我想补充一点,如果你想画大量的四边形,这可能会成为一个巨大的性能问题。顶点着色器在每个顶点上做了大量的工作,甚至可能包括分支,这取决于编译器的聪明程度。当然,这也满足了问题的“简单”部分。