[英]how to draw a set of coordinates in OpenGL?
我正在尝试用C ++制作Conway的《生命游戏》,并且正在使用OpenGL(但是我对OpenGL很陌生),因为它支持负坐标,因此支持无限的世界。
我有一个名为GameOfLife的类,该类可以处理整个世界,并且具有作为[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图形的深度缓冲区。
另外,“因为它支持负坐标”是使用OpenGL的荒谬理由。 这并不意味着整个无限世界都会一次显示在屏幕上-屏幕坐标只能从-1到1。
由于顶点坐标的类型是整数数据类型
std::vector<std::vector<int>> dupl;
您必须使用glVertex2i()
。
顶点坐标必须在归一化设备空间的范围内,对于所有3个分量(x,y,z)均为[-1,1]。 要将顶点坐标“投影”到此范围,必须使用投影矩阵。
在绘制几何图形之前,通过glOrtho
定义比顶点坐标更glOrtho
,并设置正交投影矩阵(请参见glMatrixMode
)。
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);
如果您更喜欢使用窗口坐标,并且窗口的大小为800x600,例如:
glOrtho(0.0, 800.0, 0.0, 600.0, -1.0, 1.0);
glBegin
/ glEnd
必须至少包含一个基本体的顶点坐标。 GL_QUADS
图元由4个顶点坐标组成。
但是,您可以根据需要封装任意数量的四合一序列。 因此, for
循环必须在glBegin
和glEnd
之间:
glBegin(GL_QUADS);
for(std::vector<int> &v : gol.alive)
{
glVertex2i(v[0], v[1]);
}
glEnd();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.