Какой лучший способ нарисовать полноэкранный квад в OpenGL 3.2? - PullRequest
21 голосов
/ 07 апреля 2010

Я занимаюсь приведением лучей в фрагментный шейдер. Я могу придумать пару способов нарисовать полноэкранный квад для этой цели. Либо нарисуйте квад в пространстве клипа с матрицей проекции, установленной на единичную матрицу, либо используйте геометрический шейдер, чтобы превратить точку в треугольную полосу. Первый использует немедленный режим, устарел в OpenGL 3.2. Последний я использую из новизны, но он все еще использует немедленный режим, чтобы нарисовать точку.

Ответы [ 5 ]

17 голосов
/ 07 апреля 2010

Вы можете отправить два треугольника, создавая квад, с их атрибутами вершины, равными -1/1 соответственно.

Вам не нужно умножать их на какую-либо матрицу в вершинном / фрагментном шейдере.

Вот несколько примеров кода, как это просто:)

Вершинный шейдер:

const vec2 madd=vec2(0.5,0.5);
attribute vec2 vertexIn;
varying vec2 textureCoord;
void main() {
   textureCoord = vertexIn.xy*madd+madd; // scale vertex attribute to [0-1] range
   gl_Position = vec4(vertexIn.xy,0.0,1.0);
}

Фрагмент шейдера:

varying vec2 textureCoord;
void main() {
   vec4 color1 = texture2D(t,textureCoord);
   gl_FragColor = color1;
}
12 голосов
/ 18 февраля 2012

Для вывода полноэкранного четырехугольного геометрического шейдера можно использовать:

#version 330 core

layout(points) in;
layout(triangle_strip, max_vertices = 4) out;

out vec2 texcoord;

void main() 
{
    gl_Position = vec4( 1.0, 1.0, 0.5, 1.0 );
    texcoord = vec2( 1.0, 1.0 );
    EmitVertex();

    gl_Position = vec4(-1.0, 1.0, 0.5, 1.0 );
    texcoord = vec2( 0.0, 1.0 ); 
    EmitVertex();

    gl_Position = vec4( 1.0,-1.0, 0.5, 1.0 );
    texcoord = vec2( 1.0, 0.0 ); 
    EmitVertex();

    gl_Position = vec4(-1.0,-1.0, 0.5, 1.0 );
    texcoord = vec2( 0.0, 0.0 ); 
    EmitVertex();

    EndPrimitive(); 
}

Вершинный шейдер просто пуст:

#version 330 core

void main()
{
}

Чтобы использовать этот шейдер, вы можете использовать пустую команду рисования с пустым VBO:

glDrawArrays(GL_POINTS, 0, 1);
6 голосов
/ 14 октября 2011

Подсказка Чистофа Риччо:

Большой треугольник более эффективен по причине, которую я иллюстрировал в видео:

http://www.youtube.com/watch?v=WFx6StqpRdY

http://www.youtube.com/watch?v=WnUS8kzA3dI&feature=related

3 голосов
/ 01 августа 2018

Нет необходимости использовать геометрический шейдер, VBO или любую память вообще.

Вершинный шейдер может генерировать квад.

layout(location = 0) out vec2 uv;

void main() 
{
    float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u); 
    float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u); 

    gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f);
    uv = vec2(x, y);
}

Привязать пустой VAO. Отправьте вызов на 6 вершин.

2 голосов
/ 13 октября 2011

Следующее происходит из функции draw класса, которая рисует текстуры fbo в квадрате с выравниванием по экрану.

Gl.glUseProgram(shad);      

Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo);           
Gl.glEnableVertexAttribArray(0);
Gl.glEnableVertexAttribArray(1);
Gl.glVertexAttribPointer(0, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, voff);
Gl.glVertexAttribPointer(1, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, coff);  

Gl.glActiveTexture(Gl.GL_TEXTURE0);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, fboc);
Gl.glUniform1i(tileLoc, 0);

Gl.glDrawArrays(Gl.GL_QUADS, 0, 4);

Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0); 

Gl.glUseProgram(0); 

Сам фактический квад и координаты получены из:

private float[] v=new float[]{  -1.0f, -1.0f, 0.0f,
                                1.0f, -1.0f, 0.0f,
                                1.0f, 1.0f, 0.0f,
                                -1.0f, 1.0f, 0.0f,

                                0.0f, 0.0f,
                                1.0f, 0.0f,
                                1.0f, 1.0f,
                                0.0f, 1.0f
};

Связывание и настройка VBO, которые я оставляю вам.

Вершинашейдер:

#version 330

layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 coord;

out vec2 coords;

void main() {
    coords=coord.st;
    gl_Position=vec4(pos, 1.0);
}

Поскольку позиция является необработанной, то есть не умноженной ни на одну матрицу, -1, -1 :: 1, 1 квада вписываются в область просмотра.Ищите учебник Альфонса, связанный со всеми его постами на openGL.org.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...