/* cubiverse.c - SDL2/OpenGL doohickey
* by Pegasus Epsilon <pegasus@pimpninjas.org>
* Distribute Unmodified
*/
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_opengl.h>
#undef main /* fucking SDL */
void gluPerspective (GLdouble fov, GLdouble aspect, GLdouble zNear, GLdouble zFar) {
GLdouble xmin, xmax, ymin, ymax;
ymin = zNear * tan(fov * M_PI / 360.0);
ymax = -ymin;
xmin = ymin * -aspect;
xmax = ymax * -aspect;
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
typedef struct { GLubyte red, grn, blu; } GLubyteColor;
typedef struct { GLint x, y, z; } GLintCoord;
void loadCube (GLuint *cube) {
GLintCoord vertices[] = {
/* skybox version
{1,1,1},{-1,1, 1},{1,-1,1},{-1,-1, 1},{-1,-1,-1},{-1,1, 1},{-1,1,-1},
{1,1,1},{ 1,1,-1},{1,-1,1},{ 1,-1,-1},{-1,-1,-1},{ 1,1,-1},{-1,1,-1}
*/
{1,1,-1},{-1,1,-1},{1,-1,-1},{-1,-1,-1},{-1,-1,1},{-1,1,-1},{-1,1,1},
{1,1,-1},{ 1,1, 1},{1,-1,-1},{ 1,-1, 1},{-1,-1,1},{ 1,1, 1},{-1,1,1}
};
GLubyteColor colors[] = {
{255,255,255},{0,255,255},{255,0,255},{0,0,255},{0,0,0},{0,255,255},{0,255,0},
{255,255,255},{255,255,0},{255,0,255},{255,0,0},{0,0,0},{255,255,0},{0,255,0}
};
*cube = glGenLists(1);
glNewList(*cube, GL_COMPILE);
glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i < 14; i++) {
glColor3ub(colors[i].red, colors[i].grn, colors[i].blu);
glVertex3i(vertices[i].x, vertices[i].y, vertices[i].z);
}
glEnd();
glEndList();
}
void resize (int width, int height) {
GLdouble aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 0.1, 40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* FIXME: this breaks normals and does not belong here. */
/*glScalef(.5,.5,.5);*/
glTranslatef(0,0,-4);
}
void init (void) {
/* antialias, son! */
//glEnable(GL_POINT_SMOOTH);
//glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glShadeModel(GL_FLAT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//glPointSize((GLfloat)1.1);
//glLineWidth(2);
/* yay lines */
glPolygonMode(GL_FRONT, GL_LINE);
/* ??? yay cargo
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
*/
}
void renderFrame (SDL_Window *window, GLuint list) {
glClearColor(.0,.0,.0,.0);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(list);
glFlush();
glFinish();
SDL_GL_SwapWindow(window);
}
int main (void) {
SDL_Surface *screen;
SDL_Window *window;
SDL_GLContext deviceContext;
GLuint cube;
window = SDL_CreateWindow(
"SDL2/OpenGL Demo", 0, 0, 800, 600,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE |
SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_MAXIMIZED
);
if (0 > SDL_ShowCursor(0)) return 1;
if (NULL == (screen = SDL_GetWindowSurface(window))) return 2;
deviceContext = SDL_GL_CreateContext(window);
resize(screen->w, screen->h);
init();
/* walk a cube as a single triangle strip -- fuck yeah */
/* no normals yet */
loadCube(&cube);
for (;;) { /* ever */
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION:
/* move the object
glTranslatef(0,0,0);
*/
/* rotate the object */
glRotatef(1, (float)event.motion.yrel, 0, (float)event.motion.xrel);
SDL_WarpMouseInWindow(NULL, screen->w/2, screen->h/2);
/* there's a function that's supposed to let us ignore the warp event
* but it doesn't seem to work. So instead, we eat the warp event.
*/
SDL_PollEvent(&event);
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
SDL_GL_DeleteContext(deviceContext);
return 0;
break;
}
break;
}
}
renderFrame(window, cube);
}
}