I'm trying to make Conway's Game of Life in C++, and am using OpenGL (However I'm pretty new to OpenGL) because it supports negative coordinates and therefore an infinite world.
I have a class called GameOfLife`` which handles the entire world, and has the alive cells as [x, y] coordinates in an vector. Therefore I'm going to use a for loop throughout the alive cells coordinate and render a single pixel for each coordinate.
However whatever I have tried nothing appears on the screen no matter what I do. Below is the code with an empty glBegin
and glEnd
function. What should I put between these in order for it to render.
I have tried :
dividing each coordinate by 400 to get float
for 1 pixel .
adding 1/400 to both x and y for the third and fourth side.
#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();
}
Since the type of the vertex coordinates is an integral data type
std::vector<std::vector<int>> dupl;
you have to use glVertex2i()
.
The vertex coordinates have to be in the rage of normalized device space, which is [-1, 1] for all 3 components (x, y,z). To "project" your vertex coordinates to this range you've to use a projection matrix.
Define a range wich is grater than the vertex coordinates and set an orthographic projection matrix (see glMatrixMode
) by glOrtho
, before you draw the geometry.
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) {
// [...]
}
Note, that the orthographic projection should als take into account the aspect ration of the viewport.
e.g. The vertex coordinates are in rage [0, 400] and the aspect ration of the viewport is 16.0/9.0:
glOrtho(0.0, 400.0*16.0/9.0, 0.0, 400.0, -1.0, 1.0);
If you prefer to use window coordinates and the size of the window is e.g. 800x600:
glOrtho(0.0, 800.0, 0.0, 600.0, -1.0, 1.0);
The glBegin
/glEnd
has to enclose at least the vertex coordinates for one Primitive. A GL_QUADS
primitive consists of 4 vertex coordinates.
But you can encapsulate as many quads to 1 sequence as you want. So the for
-loop has to be in between glBegin
and glEnd
:
glBegin(GL_QUADS);
for(std::vector<int> &v : gol.alive)
{
glVertex2i(v[0], v[1]);
}
glEnd();