1

我正在尝试用 C++ 制作康威的生命游戏,并且正在使用 OpenGL(但我对 OpenGL 很陌生),因为它支持负坐标,因此支持无限的世界。
我有一个名为 GameOfLife 的类,它处理整个世界,并将活细胞作为向量中的 [x, y] 坐标。因此,我将在整个活动单元格坐标中使用 for 循环,并为每个坐标渲染一个像素。
但是,无论我做什么,屏幕上都不会出现任何我尝试过的东西。下面是带有空glBeginglEnd函数的代码。我应该在它们之间放置什么才能渲染。

我试过:
将每个坐标除以 400 得到float1 个像素。
在第三边和第四边的 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();
}
4

2 回答 2

1

如果您正在绘制四边形 ( GL_QUADS),那么您应该使用要绘制glVertex2f 的四边形每个角的坐标调用 4 次。对于三角形,使用GL_TRIANGLES和 3 次调用。为了积分,GL_POINTS1 次通话。

它也将有助于设置颜色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。

于 2019-06-18T22:10:10.987 回答
1

由于顶点坐标的类型是整数数据类型

std::vector<std::vector<int>> dupl;

你必须使用glVertex2i().

顶点坐标必须在标准化设备空间的范围内,对于所有 3 个分量 (x, y,z),它是 [-1, 1]。要将您的顶点坐标“投影”到此范围,您必须使用投影矩阵。

在绘制几何之前,定义一个大于顶点坐标的范围并设置正交投影矩阵(参见glMatrixMode) 。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);

如果您更喜欢使用窗口坐标并且窗口大小为 800x600:

glOrtho(0.0, 800.0, 0.0, 600.0, -1.0, 1.0);

glBegin/glEnd必须至少包含一个Primitive的顶点坐标。一个GL_QUADS图元由 4 个顶点坐标组成。
但是您可以根据需要封装任意数量的四边形到 1 个序列。所以for-loop 必须在glBegin和之间glEnd

glBegin(GL_QUADS);
for(std::vector<int> &v : gol.alive)
{
   glVertex2i(v[0], v[1]);
}
glEnd();
于 2019-06-19T04:58:51.383 回答