使用屏幕坐标(像素位置)绘制矩形作为OpenGL 3.0+的输入吗?

时间:2019-06-18 14:47:33

标签: c++ opengl opengl-3

我正在尝试通过使用OpenGL版本3.3将矩形的最小和最大点作为输入(在屏幕坐标中)来实现一个简单的API在屏幕上绘制矩形。 例如

void Rect(xmin, ymin, xmax, ymax);

OpenGL 2.x Rect()提供的类似API

我假设屏幕坐标不过是像素位置,其原点位于屏幕的左上角。 (OpenGL的原点在左下方)

通常,我们在顶点着色器中将局部空间点转换为NDC(通过世界,摄影机并最终裁剪空间),

gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * pointInLocalSpace;

我将矩形的最小和最大点(屏幕坐标,在我的情况下实际上是鼠标光标的位置)作为着色器中的均匀变量,以方便使用此API。

我当前的实现方式假定我们传递屏幕点时,它们在视图空间中(如果我错了,请纠正我)。并且我仅应用投影矩阵将其转换为NDC,

gl_Position = ProjectionMatrix * vec4(screen.x, screen.y, 0.0, 1.0);

我正在使用透视投影,并且正在准备线条以在几何着色器中绘制矩形。我在VBO中仅设置了一个顶点(0,0,0),并且没有在任何地方使用它。 (这种方法不是问题,因为我已经在其他情况下成功实现了该方法。)

问题是,我没有在屏幕上绘制任何矩形。

如果坐标转换不正确或我做错了什么,请问有人可以帮助我理解坐标转换吗? 不用着色器就可以画出这么简单的东西吗?

以下是我正在处理的代码段。

顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos, 1.0);
}

几何着色器

#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 8) out;

out vec3 fColor;

uniform mat4 Projection;
uniform vec4 rect; // min.x = rect.x, min.y = rect.y, max.x = rect.z, max.y = rect.w  

void main() 
{
    vec4 position = gl_in[0].gl_Position;

    fColor = vec3(0.80, 0.0, 0.0);
    gl_Position = Projection * vec4(rect.x, rect.y, 1.0, 1.0);
    EmitVertex();
    gl_Position = Projection * vec4(rect.z, rect.y, 1.0, 1.0);
    EmitVertex();
    EndPrimitive();

    gl_Position = Projection * vec4(rect.z, rect.y, 1.0, 1.0);
    EmitVertex();
    gl_Position = Projection * vec4(rect.z, rect.w, 1.0, 1.0);
    EmitVertex();
    EndPrimitive();

    gl_Position = Projection * vec4(rect.z, rect.w, 1.0, 1.0);
    EmitVertex();
    gl_Position = Projection * vec4(rect.x, rect.w, 1.0, 1.0);
    EmitVertex();
    EndPrimitive();

    gl_Position = Projection * vec4(rect.x, rect.w, 1.0, 1.0);
    EmitVertex();
    gl_Position = Projection * vec4(rect.x, rect.y, 1.0, 1.0);
    EmitVertex();
    EndPrimitive();
}

片段着色器

#version 330 core
out vec4 FragColor;

in vec3 fColor;

void main()
{
    FragColor = vec4(fColor, 1.0);
}

Cpp

// set up opengl


float points[] = {0.0f, 0.0f, 0.0f};

unsigned int VAO, VBO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindVertexArray(0);

.
.
//read and compile shaders (_rectangleDrawShader)
.
.

glm::mat4 projectionMatrix = glm::perspective(glm::radians(45.0), (float)width / (float)height, 0.1f, 100.0f);

while (!glfwWindowShouldClose(window))
{
    .
    .
    // some stuff to clear the color, depth buffers.
    .
    .

    glm::vec2 min(50,50), max(150, 150)
   _rectangleDrawShader->use();
   _rectangleDrawShader->setMat4("Projection", projectionMatrix);
   _rectangleDrawShader->setVec4("rect", glm::vec4(min.x, min.y, max.x, max.y));
   glBindVertexArray(VAO);
   glDrawArrays(GL_POINTS, 0, 1);

   glfwSwapBuffers(window);
   glfwPollEvents();
}

0 个答案:

没有答案