Skip to content

Instantly share code, notes, and snippets.

@OrangeTide
Created April 25, 2015 04:56
Show Gist options
  • Save OrangeTide/fbe703b80d143983361f to your computer and use it in GitHub Desktop.
Save OrangeTide/fbe703b80d143983361f to your computer and use it in GitHub Desktop.
Drawing a cube in OpenGL using VBOs. (required SDL2)
/* cube_vbo.c - demo of drawing a cube in GL using VBOs.
*
* PUBLIC DOMAIN - Jon Mayo - April 24, 2015
*
* Requires SDL2
*
* To build:
* gcc -Wall -W -o cube_vbo cube_vbo.c `pkg-config --libs --cflags sdl2 gl`
*
*/
#include <stdio.h>
#include <stdbool.h>
#define GL_GLEXT_PROTOTYPES
#include <SDL.h>
#include <GL/gl.h>
#include <GL/glext.h>
static GLuint tri_vbo; /* the VBO id for vertex data */
static GLuint tri_color_vbo; /* the VBO id for color data */
static unsigned tri_vbo_elem; /* number of elements in this one */
#define check_gl_error() do { \
GLenum e##__LINE__ = glGetError(); \
if (e##__LINE__ != GL_NO_ERROR) \
fprintf(stderr,"ERROR:%d:glerr=%d\n", __LINE__, e##__LINE__); \
} while(0)
static void initialize_scene(void)
{
SDL_Window *win = SDL_GL_GetCurrentWindow();
/* black screen */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapWindow(win);
/* setup projection matrix */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* hacky way to correct for aspect ratio */
int width, height;
SDL_GetWindowSize(win, &width, &height);
double aspect_root = sqrt((double)width / (double)height);
double nearest = 0.125; /* how close you can get before it's clipped. */
glFrustum(-nearest * aspect_root, nearest * aspect_root,
-nearest / aspect_root, nearest / aspect_root,
nearest, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
check_gl_error();
}
static void paint_scene(void)
{
SDL_Window *win = SDL_GL_GetCurrentWindow();
static float angle_x = 0.0, angle_y = 0.0, angle_z = 0.0;
glClearColor(0.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(angle_x, 1.0, 0.0, 0.0);
glRotatef(angle_y, 0.0, 1.0, 0.0);
glRotatef(angle_z, 0.0, 0.0, 1.0);
angle_x += 2.0;
angle_y += 3.0;
angle_z += 4.0;
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
glVertexPointer(3, GL_FLOAT, 0, (void*)(0));
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, tri_color_vbo);
glColorPointer(3, GL_FLOAT, 0, (void*)(0));
glBindBuffer(GL_ARRAY_BUFFER, 0); /* release binding */
glDrawArrays(GL_TRIANGLES, 0, tri_vbo_elem);
check_gl_error();
glDisableClientState(GL_VERTEX_ARRAY);
glFlush();
SDL_GL_SwapWindow(win);
check_gl_error();
}
int main()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
return EXIT_FAILURE;
#if 0
/* configure the OpenGL version to use. */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);
#endif
/* create a window suitable for OpenGL. */
SDL_Window *mainwin = SDL_CreateWindow("Cube VBO demo",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
850, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (!mainwin) {
fprintf(stderr, "ERROR:%s\n", SDL_GetError());
goto failure;
}
/* create a context. */
SDL_GLContext glctx = SDL_GL_CreateContext(mainwin);
if (!glctx) {
fprintf(stderr, "ERROR:%s\n", SDL_GetError());
goto cleanup;
}
SDL_GL_SetSwapInterval(1);
/* initialize the scene and create the VBO */
initialize_scene();
float tri_data[] = {
/* face 1 */
1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
/* face 2 */
-1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
/* face 3 */
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
/* face 4 */
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
/* face 5 */
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, -1.0,
1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
/* face 6 */
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
};
float tri_color[] = {
/* face 1 */
0.0, 0.7, 1.0,
0.0, 0.7, 1.0,
0.0, 0.7, 1.0,
0.0, 0.7, 1.0,
0.0, 0.7, 1.0,
0.0, 0.7, 1.0,
/* face 2 */
0.9, 1.0, 0.0,
0.9, 1.0, 0.0,
0.9, 1.0, 0.0,
0.9, 1.0, 0.0,
0.9, 1.0, 0.0,
0.9, 1.0, 0.0,
/* face 3 */
0.2, 0.2, 1.0,
0.2, 0.2, 1.0,
0.2, 0.2, 1.0,
0.2, 0.2, 1.0,
0.2, 0.2, 1.0,
0.2, 0.2, 1.0,
/* face 4 */
0.9, 0.1, 0.1,
0.9, 0.1, 0.1,
0.9, 0.1, 0.1,
0.9, 0.1, 0.1,
0.9, 0.1, 0.1,
0.9, 0.1, 0.1,
/* face 5 */
0.1, 0.7, 0.1,
0.1, 0.7, 0.1,
0.1, 0.7, 0.1,
0.1, 0.7, 0.1,
0.1, 0.7, 0.1,
0.1, 0.7, 0.1,
/* face 6 */
0.7, 0.0, 0.7,
0.7, 0.0, 0.7,
0.7, 0.0, 0.7,
0.7, 0.0, 0.7,
0.7, 0.0, 0.7,
0.7, 0.0, 0.7,
};
/* vertex buffer ... */
glGenBuffers(1, &tri_vbo);
glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(tri_data), tri_data,
GL_STATIC_DRAW);
tri_vbo_elem = sizeof(tri_data) / sizeof(*tri_data) / 3;
glBindBuffer(GL_ARRAY_BUFFER, 0); /* release binding */
/* color buffer */
glGenBuffers(1, &tri_color_vbo);
glBindBuffer(GL_ARRAY_BUFFER, tri_color_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(tri_color), tri_color,
GL_STATIC_DRAW);
if (tri_vbo_elem != (sizeof(tri_color) / sizeof(*tri_color) / 3)) {
fprintf(stderr, "ERROR:tri_color[] does not have the same number of elements as tri_data[]\n");
// TODO: bail
}
glBindBuffer(GL_ARRAY_BUFFER, 0); /* release binding */
/* Event Loop */
bool quit = false;
while (1) {
SDL_Event ev;
/* process events until timeout occurs */
while (SDL_WaitEventTimeout(&ev, 15)) {
switch (ev.type) {
case SDL_QUIT:
quit = true;
goto bail;
}
}
paint_scene();
}
bail:
SDL_DestroyWindow(mainwin);
SDL_Quit();
return 0;
cleanup:
SDL_DestroyWindow(mainwin);
failure:
SDL_Quit();
return EXIT_FAILURE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment