在 OpenGL 中绘制二维四边形
Draw a 2D Quad in OpenGL
每当我认为我了解一些关于 openGL 的东西时,我发现我什么都不懂。
我不明白我做错了什么。
四边形未渲染。
这是我初始化数据的方式
std::vector<glm::vec3> vertices;
vertices.resize(6);
// first triangle
vertices[0] = glm::vec3(x+w, y, 0.0f); // top right
vertices[1] = glm::vec3(x+w, y+h, 0.0f); // bottom right
vertices[2] = glm::vec3(x, y, 0.0f); // top left
// second triangle
vertices[3] = glm::vec3(x+w, y+h, 0.0f); // bottom right
vertices[4] = glm::vec3(x, y+h, 0.0f); // bottom left
vertices[5] = glm::vec3(x, y, 0.0f); // top left
其中 (x, y) 是像素屏幕位置左上角的坐标,(w, h) 是四边形的边长
这就是我在 GPU 中设置数据的方式
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
我是这样渲染的
glBindVertexArray(vao);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
这些是我的顶点和片段着色器
#version 330 core
layout (location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
#version 330 core
out vec4 outColor;
void main() {
outColor = vec4(1.0);
}
更新
Rabbit76 如何指出:我没有看到矩形,因为它在视图之外。如果不使用投影矩阵,顶点坐标必须在 [-1.0, 1.0] 范围内。如果要使用“window”坐标,则必须使用正交投影
所以我按以下方式更改了顶点着色器,一切正常!
#version 330 core
layout (location = 0) in vec3 position;
uniform vec2 viewport; //Width and Height of the viewport
void main() {
// From pixels to 0-1
vec2 coord = position.xy / viewport;
// Flip Y so that 0 is top
coord.y = (1.0-coord.y);
// Map to NDC -1,+1
coord.xy = coord.xy * 2.0 - 1.0;
gl_Position = vec4(coord.xy, 0.0, 1.0);
}
您看不到矩形,因为它不在视野范围内。如果您不使用投影矩阵,则顶点坐标必须在 [-1.0, 1.0] 范围内。如果要使用“window”坐标,则必须使用 Orthographic projection.
您需要通过投影矩阵对顶点坐标进行变换。这通常在顶点着色器中完成。但是,也可以在 CPU 上变换顶点坐标。使用glm::ortho
定义正交投影矩阵并对顶点进行变换:
glm::mat4 projection = glm::ortho(0.0f, window_width, window_height, 0.0f, -1.0f, 1.0f);
for (auto &vertex : vertices)
vertex = glm::vec3(projection * glm::vec4(vertex, 1.0f));
每当我认为我了解一些关于 openGL 的东西时,我发现我什么都不懂。
我不明白我做错了什么。
四边形未渲染。
这是我初始化数据的方式
std::vector<glm::vec3> vertices;
vertices.resize(6);
// first triangle
vertices[0] = glm::vec3(x+w, y, 0.0f); // top right
vertices[1] = glm::vec3(x+w, y+h, 0.0f); // bottom right
vertices[2] = glm::vec3(x, y, 0.0f); // top left
// second triangle
vertices[3] = glm::vec3(x+w, y+h, 0.0f); // bottom right
vertices[4] = glm::vec3(x, y+h, 0.0f); // bottom left
vertices[5] = glm::vec3(x, y, 0.0f); // top left
其中 (x, y) 是像素屏幕位置左上角的坐标,(w, h) 是四边形的边长
这就是我在 GPU 中设置数据的方式
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
我是这样渲染的
glBindVertexArray(vao);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
这些是我的顶点和片段着色器
#version 330 core
layout (location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
#version 330 core
out vec4 outColor;
void main() {
outColor = vec4(1.0);
}
更新
Rabbit76 如何指出:我没有看到矩形,因为它在视图之外。如果不使用投影矩阵,顶点坐标必须在 [-1.0, 1.0] 范围内。如果要使用“window”坐标,则必须使用正交投影
所以我按以下方式更改了顶点着色器,一切正常!
#version 330 core
layout (location = 0) in vec3 position;
uniform vec2 viewport; //Width and Height of the viewport
void main() {
// From pixels to 0-1
vec2 coord = position.xy / viewport;
// Flip Y so that 0 is top
coord.y = (1.0-coord.y);
// Map to NDC -1,+1
coord.xy = coord.xy * 2.0 - 1.0;
gl_Position = vec4(coord.xy, 0.0, 1.0);
}
您看不到矩形,因为它不在视野范围内。如果您不使用投影矩阵,则顶点坐标必须在 [-1.0, 1.0] 范围内。如果要使用“window”坐标,则必须使用 Orthographic projection.
您需要通过投影矩阵对顶点坐标进行变换。这通常在顶点着色器中完成。但是,也可以在 CPU 上变换顶点坐标。使用glm::ortho
定义正交投影矩阵并对顶点进行变换:
glm::mat4 projection = glm::ortho(0.0f, window_width, window_height, 0.0f, -1.0f, 1.0f);
for (auto &vertex : vertices)
vertex = glm::vec3(projection * glm::vec4(vertex, 1.0f));