I am trying to implement an open-source OpenGL implementation of a 3D Rubik's Cube. The compilation of the code works in my non-mac machines, but when run in max, it runs into:
freeglut (./OpenGL): failed to open display ''
Libraries I used: GLUT (freeglut), GLFW, GLM
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#include <vector>
using namespace std;
struct cube_rotate
{
GLfloat angle, x, y, z;
};
GLfloat angle, fAspect, cube_size;
GLint rot_x, rot_y, crement, x_0, x_k, y_0, y_k, z_0, z_k, gap, gap_crement;
// cube_rotate cube_rotations[3][3][3];
vector<cube_rotate> cube_rotations[3][3][3];
void load_visualization_parameters(void);
void apply_rotation(GLfloat angle)
{
vector<cube_rotate> face[3][3];
int index;
cube_rotate rotation;
// copy face to be rotated
// apply rotation to face
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
{
index = 2 - j % 3;
if (x_0 == x_k)
{
rotation = {angle, 1.0, 0.0, 0.0};
face[index][i] = cube_rotations[x_k][i][j];
}
if (y_0 == y_k)
{
rotation = {angle, 0.0, 1.0, 0.0};
face[index][i] = cube_rotations[j][y_k][i];
}
if (z_0 == z_k)
{
rotation = {-1 * angle, 0.0, 0.0, 1.0};
face[index][i] = cube_rotations[j][i][z_k];
}
face[index][i].push_back(rotation);
}
// copy back rotated face
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
{
if (x_0 == x_k)
cube_rotations[x_k][i][j] = face[i][j];
if (y_0 == y_k)
cube_rotations[j][y_k][i] = face[i][j];
if (z_0 == z_k)
cube_rotations[j][i][z_k] = face[i][j];
}
}
// reset face selection parameters
void reset_selected_face()
{
x_0 = 0;
x_k = 2;
y_0 = 0;
y_k = 2;
z_0 = 0;
z_k = 2;
}
void set_camera()
{
gluLookAt(0, 80, 200, 0, 0, 0, 0, 1, 0);
}
// draw a cube
void draw_cube(int x, int y, int z)
{
vector<cube_rotate> lrot = cube_rotations[x][y][z];
glPushMatrix();
// translate to final position
glTranslatef((x - 1) * cube_size + x * gap, (y - 1) * cube_size + y * gap, (z - 1) * cube_size + z * gap);
// rotate cube to correct position
for (int i = lrot.size() - 1; i >= 0; --i)
glRotatef(lrot[i].angle, lrot[i].x, lrot[i].y, lrot[i].z);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS); // front
glNormal3f(0.0, 0.0, 1.0); // face normal
glVertex3f(cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(-cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(-cube_size / 2, -cube_size / 2, cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, cube_size / 2);
glEnd();
glColor3f(1.0f, 0.5f, 0.0f);
glBegin(GL_QUADS); // back
glNormal3f(0.0, 0.0, -1.0); // face normal
glVertex3f(cube_size / 2, cube_size / 2, -cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(-cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(-cube_size / 2, cube_size / 2, -cube_size / 2);
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); // left
glNormal3f(-1.0, 0.0, 0.0); // face normal
glVertex3f(-cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(-cube_size / 2, cube_size / 2, -cube_size / 2);
glVertex3f(-cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(-cube_size / 2, -cube_size / 2, cube_size / 2);
glEnd();
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS); // right
glNormal3f(1.0, 0.0, 0.0); // face normal
glVertex3f(cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(cube_size / 2, cube_size / 2, -cube_size / 2);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS); // top
glNormal3f(0.0, 1.0, 0.0); // face normal
glVertex3f(-cube_size / 2, cube_size / 2, -cube_size / 2);
glVertex3f(-cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(cube_size / 2, cube_size / 2, cube_size / 2);
glVertex3f(cube_size / 2, cube_size / 2, -cube_size / 2);
glEnd();
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS); // bottom
glNormal3f(0.0, -1.0, 0.0); // face normal
glVertex3f(-cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, -cube_size / 2);
glVertex3f(cube_size / 2, -cube_size / 2, cube_size / 2);
glVertex3f(-cube_size / 2, -cube_size / 2, cube_size / 2);
glEnd();
glPopMatrix();
} // draw cube function
// draw function
void draw_func(void)
{
int x = -cube_size, y = -cube_size, z = -cube_size;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// reset transformations
glLoadIdentity();
// set camera position
set_camera();
// apply visualization transformations
glRotatef(rot_x, 1.0, 0.0, 0.0); // rotate in y axis
glRotatef(rot_y, 0.0, 1.0, 0.0); // rotate in x axis
for (int i = 0; i < 3; ++i) // step through x axis
for (int j = 0; j < 3; ++j) // step through y axis
for (int k = 0; k < 3; ++k)
{ // step through z axis
// draw a single cube
draw_cube(i, j, k);
}
// flush opengl commands
glutSwapBuffers();
}
// init rendering parameters
void init_func(void)
{
// init parameters
cube_size = 30.0; // cuboid size
rot_x = 0.0; // view rotation x
rot_y = 0.0; // view rotation y
crement = 5; // rotation (in/de)crement
gap = 5;
gap_crement = 3;
// initialize cuboid rotations
// init lighting
GLfloat ambient_lighte[4] = {0.2, 0.2, 0.2, 1.0};
GLfloat diffuse_light[4] = {0.7, 0.7, 0.7, 1.0}; // color
GLfloat specular_light[4] = {1.0, 1.0, 1.0, 1.0}; // brightness
GLfloat light_position[4] = {0.0, 50.0, 50.0, 1.0};
// material brightness capacity
GLfloat specularity[4] = {1.0, 1.0, 1.0, 1.0};
GLint material_specularity = 60;
// black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Gouraud colorization model
glShadeModel(GL_SMOOTH);
// material reflectability
glMaterialfv(GL_FRONT, GL_SPECULAR, specularity);
// brightness concentration
glMateriali(GL_FRONT, GL_SHININESS, material_specularity);
// activate ambient light
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_lighte);
// define light parameters
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_lighte);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
// enable changing material color
glEnable(GL_COLOR_MATERIAL);
// enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// enable depth buffering
glEnable(GL_DEPTH_TEST);
angle = 45;
} // init
// specify what's shown in the window
void load_visualization_parameters(void)
{
// specify projection coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// specify projection perspective
gluPerspective(angle, fAspect, 0.4, 500);
// init model coordinate system
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// specify observer and target positions
set_camera();
} // load visualization parameters
// window reshape callback
void reshape_func(GLsizei w, GLsizei h)
{
// prevents division by zero
if (h == 0)
h = 1;
// viewport size
glViewport(0, 0, w, h);
// aspect ratio
fAspect = (GLfloat)w / (GLfloat)h;
load_visualization_parameters();
} // reshape function
// keyboard function callback
void keyboard_func(unsigned char key, int x, int y)
{
switch (key)
{
case '+':
gap += gap_crement;
break;
case '-':
gap -= gap_crement;
break;
// view rotation
// INcrement or DEcrement
case 'L': // right
case 'l':
rot_y = (rot_y - crement) % 360;
break;
case 'J': // left
case 'j':
rot_y = (rot_y + crement) % 360;
break;
case 'I': // down
case 'i':
rot_x = (rot_x + crement) % 360;
break;
case 'K': // up
case 'k':
rot_x = (rot_x - crement) % 360;
break;
// end of view rotation
// cube movements
// select cube face
// x-axis faces
case 'Q':
case 'q':
reset_selected_face();
x_0 = 0;
x_k = 0;
break;
case 'W':
case 'w':
reset_selected_face();
x_0 = 1;
x_k = 1;
break;
case 'E':
case 'e':
reset_selected_face();
x_0 = 2;
x_k = 2;
break;
// y-axis faces
case 'A':
case 'a':
reset_selected_face();
y_0 = 0;
y_k = 0;
break;
case 'S':
case 's':
reset_selected_face();
y_0 = 1;
y_k = 1;
break;
case 'D':
case 'd':
reset_selected_face();
y_0 = 2;
y_k = 2;
break;
// z-axis faces
case 'C':
case 'c':
reset_selected_face();
z_0 = 0;
z_k = 0;
break;
case 'X':
case 'x':
reset_selected_face();
z_0 = 1;
z_k = 1;
break;
case 'Z':
case 'z':
reset_selected_face();
z_0 = 2;
z_k = 2;
break;
// move selected face
case 'U': // counter-clockwise
case 'u':
apply_rotation(-90);
break;
case 'O': // clockwise
case 'o':
apply_rotation(90);
break;
// end of cube movements
default:
break;
}
glutPostRedisplay();
}
// mouse function callback
void mouse_func(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
if (state == GLUT_DOWN)
{ // Zoom-in
if (angle >= 10)
angle -= 5;
}
if (button == GLUT_RIGHT_BUTTON)
if (state == GLUT_DOWN)
{ // Zoom-out
if (angle <= 130)
angle += 5;
}
load_visualization_parameters();
glutPostRedisplay();
} // mouse function
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 350);
glutCreateWindow("Rubik's Cube!");
glutDisplayFunc(draw_func);
glutReshapeFunc(reshape_func);
glutMouseFunc(mouse_func);
glutKeyboardFunc(keyboard_func);
init_func();
glutMainLoop();
} // main
The Makefile for this code:
CC = g++
CFLAGS = -std=c++11 -Wall -Wextra
LDFLAGS = -L/opt/homebrew/Cellar/glfw/3.3.8/lib -L/opt/homebrew/Cellar/freeglut/3.4.0/lib -framework OpenGL -lglfw -lglut
INCLUDE_DIRS = -I/opt/homebrew/Cellar/glfw/3.3.8/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -I/Users/*****/Library/CloudStorage/****\ ***/include
SRC = main.cpp
OBJ = $(SRC:.cpp=.o)
EXECUTABLE = OpenGL
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -o $@ $^ $(LDFLAGS)
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -c $< -o $@
clean:
rm -f $(OBJ) $(EXECUTABLE)
I have been able to successfully output the program in Fedora Builds, but for my macOS system, after changing the libraries into proper ones, and avoiding depreciation warnings, I just can't seem to compile this code. I'm very new to OpenGL and this has been my first couple of weeks of working my way through setting up the libraries. Any help/suggestions are highly appreciated. I am putting the C++ code and makefile I used for the compilation.
I ran into the same issue running on Mac. What solved for was the installation of XQuartz.
I have no idea what it really does or how it works. But solved the issue.