如何在OpenGL中绘制一组坐标?
how to draw a set of coordinates in OpenGL?
我正在尝试用 C++ 制作 Conway 的生命游戏,并且正在使用 OpenGL(但是我对 OpenGL 还很陌生)因为它支持负坐标,因此支持无限世界。
我有一个名为 GameOfLife`` 的 class,它处理整个世界,并将活细胞作为向量中的 [x, y] 坐标。因此,我将在整个活细胞坐标中使用 for 循环,并为每个坐标渲染一个像素。
但是,无论我尝试了什么,无论我做什么,屏幕上都没有出现。下面是带有空 glBegin
和 glEnd
函数的代码。我应该在它们之间放置什么才能渲染。
我试过了:
将每个坐标除以 400 得到 1 个像素的 float
.
将第三边和第四边的 x 和 y 都增加 1/400。
#include "gol.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main()
{
std::vector<std::vector<int>> dupl;
std::ifstream infile { "test.rle" };
std::string file_contents { std::istreambuf_iterator<char>(infile), std::istreambuf_iterator<char>() };
parse_rle(file_contents, 0, dupl);
GameOfLife gol;
gol.place_cells(dupl);
//gol.update();
GLFWwindow* window;
if (!glfwInit())
return 1;
int width = 400;
window = glfwCreateWindow(width, width, "Window", NULL, NULL);
if (!window) {
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
if(glewInit()!=GLEW_OK)
std::cout<<"Error"<<std::endl;
glEnable(GL_DEPTH_TEST);
while(!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
for(std::vector<int> i : gol.alive)
{
glBegin(GL_QUADS);
glEnd();
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
如果您正在绘制四边形 (GL_QUADS
),那么您应该使用要绘制的四边形每个角的坐标对 glVertex2f
进行 4 次调用。对于三角形,使用 GL_TRIANGLES
和 3 次调用。对于积分,GL_POINTS
和 1 个电话。
用 glColor3f
设置颜色也有帮助。
例如,如果我没记错的话,这会将屏幕的左半部分染成红色:
glBegin(GL_QUADS);
glColor3f(1, 0, 0);
glVertex2f(-1, -1);
glVertex2f(-1, 1);
glVertex2f( 0, 1);
glVertex2f( 0, -1);
glEnd();
此外,您不需要 2D 图形的深度缓冲区。
此外,"because it supports negative coordinates" 是使用 OpenGL 的荒谬理由。这并不意味着整个无限世界将一次适合屏幕 - 屏幕坐标仅从 -1 到 1。
由于顶点坐标的类型是整数数据类型
std::vector<std::vector<int>> dupl;
你必须使用 glVertex2i()
.
顶点坐标必须在规范化设备 space 范围内,对于所有 3 个分量 (x, y,z) 都是 [-1, 1]。要 "project" 您的顶点坐标在此范围内,您必须使用投影矩阵。
定义一个大于顶点坐标的范围并设置一个正交投影矩阵(在绘制几何之前参见glMatrixMode
) by glOrtho
。
double min_x = ..., min_y = ..., max_x = ..., max_y = ...;
glMatrixMode(GL_PROJECTION);
glOrtho(min_x, max_x, min_y, max_y, -1.0, 1.0);
while(!glfwWindowShouldClose(window) {
// [...]
}
请注意,正交投影还应考虑视口的纵横比。
例如顶点坐标在 [0, 400] 范围内,视口的纵横比为 16.0/9.0:
glOrtho(0.0, 400.0*16.0/9.0, 0.0, 400.0, -1.0, 1.0);
如果您更喜欢使用 window 坐标并且 window 的大小是例如800x600:
glOrtho(0.0, 800.0, 0.0, 600.0, -1.0, 1.0);
glBegin
/glEnd
has to enclose at least the vertex coordinates for one Primitive。 GL_QUADS
图元由 4 个顶点坐标组成。
但是您可以根据需要将任意数量的四边形封装为 1 个序列。所以 for
循环必须在 glBegin
和 glEnd
之间:
glBegin(GL_QUADS);
for(std::vector<int> &v : gol.alive)
{
glVertex2i(v[0], v[1]);
}
glEnd();
我正在尝试用 C++ 制作 Conway 的生命游戏,并且正在使用 OpenGL(但是我对 OpenGL 还很陌生)因为它支持负坐标,因此支持无限世界。
我有一个名为 GameOfLife`` 的 class,它处理整个世界,并将活细胞作为向量中的 [x, y] 坐标。因此,我将在整个活细胞坐标中使用 for 循环,并为每个坐标渲染一个像素。
但是,无论我尝试了什么,无论我做什么,屏幕上都没有出现。下面是带有空 glBegin
和 glEnd
函数的代码。我应该在它们之间放置什么才能渲染。
我试过了:
将每个坐标除以 400 得到 1 个像素的 float
.
将第三边和第四边的 x 和 y 都增加 1/400。
#include "gol.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main()
{
std::vector<std::vector<int>> dupl;
std::ifstream infile { "test.rle" };
std::string file_contents { std::istreambuf_iterator<char>(infile), std::istreambuf_iterator<char>() };
parse_rle(file_contents, 0, dupl);
GameOfLife gol;
gol.place_cells(dupl);
//gol.update();
GLFWwindow* window;
if (!glfwInit())
return 1;
int width = 400;
window = glfwCreateWindow(width, width, "Window", NULL, NULL);
if (!window) {
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
if(glewInit()!=GLEW_OK)
std::cout<<"Error"<<std::endl;
glEnable(GL_DEPTH_TEST);
while(!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
for(std::vector<int> i : gol.alive)
{
glBegin(GL_QUADS);
glEnd();
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
如果您正在绘制四边形 (GL_QUADS
),那么您应该使用要绘制的四边形每个角的坐标对 glVertex2f
进行 4 次调用。对于三角形,使用 GL_TRIANGLES
和 3 次调用。对于积分,GL_POINTS
和 1 个电话。
用 glColor3f
设置颜色也有帮助。
例如,如果我没记错的话,这会将屏幕的左半部分染成红色:
glBegin(GL_QUADS);
glColor3f(1, 0, 0);
glVertex2f(-1, -1);
glVertex2f(-1, 1);
glVertex2f( 0, 1);
glVertex2f( 0, -1);
glEnd();
此外,您不需要 2D 图形的深度缓冲区。
此外,"because it supports negative coordinates" 是使用 OpenGL 的荒谬理由。这并不意味着整个无限世界将一次适合屏幕 - 屏幕坐标仅从 -1 到 1。
由于顶点坐标的类型是整数数据类型
std::vector<std::vector<int>> dupl;
你必须使用 glVertex2i()
.
顶点坐标必须在规范化设备 space 范围内,对于所有 3 个分量 (x, y,z) 都是 [-1, 1]。要 "project" 您的顶点坐标在此范围内,您必须使用投影矩阵。
定义一个大于顶点坐标的范围并设置一个正交投影矩阵(在绘制几何之前参见glMatrixMode
) by glOrtho
。
double min_x = ..., min_y = ..., max_x = ..., max_y = ...;
glMatrixMode(GL_PROJECTION);
glOrtho(min_x, max_x, min_y, max_y, -1.0, 1.0);
while(!glfwWindowShouldClose(window) {
// [...]
}
请注意,正交投影还应考虑视口的纵横比。
例如顶点坐标在 [0, 400] 范围内,视口的纵横比为 16.0/9.0:
glOrtho(0.0, 400.0*16.0/9.0, 0.0, 400.0, -1.0, 1.0);
如果您更喜欢使用 window 坐标并且 window 的大小是例如800x600:
glOrtho(0.0, 800.0, 0.0, 600.0, -1.0, 1.0);
glBegin
/glEnd
has to enclose at least the vertex coordinates for one Primitive。 GL_QUADS
图元由 4 个顶点坐标组成。
但是您可以根据需要将任意数量的四边形封装为 1 个序列。所以 for
循环必须在 glBegin
和 glEnd
之间:
glBegin(GL_QUADS);
for(std::vector<int> &v : gol.alive)
{
glVertex2i(v[0], v[1]);
}
glEnd();