examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

gl-3d.c (4053B)


      1 #include <GLFW/glfw3.h>
      2 #include <assert.h>
      3 #include <math.h>
      4 
      5 #define DEFAULT_W 800
      6 #define DEFAULT_H 450
      7 
      8 #define ENABLE_GUARD(x)  glEnable(x); for (int i = 1; i--; glDisable(x))
      9 #define MATRIX_GUARD glPushMatrix(); for (int i = 1; i--; glPopMatrix())
     10 #define PROJECTION_GUARD glMatrixMode(GL_PROJECTION); for (int i = 1; i--; glMatrixMode(GL_MODELVIEW))
     11 
     12 char const* __asan_default_options() { return "detect_leaks=0"; }
     13 
     14 struct vertex
     15 {
     16 	float colour[3];
     17 	float vertex[3];
     18 } const octahedron_vertices[6] =
     19 {
     20 	{{0,0,1}, {0  ,0  , .5}},
     21 	{{0,1,0}, {0  , .5,  0}},
     22 	{{0,1,1}, {-.5,0  ,  0}},
     23 	{{1,0,1}, {0  ,-.5,  0}},
     24 	{{1,0,0}, { .5,  0,  0}},
     25 	{{1,1,0}, {0  ,0  ,-.5}},
     26 };
     27 
     28 unsigned char const octahedron_indices[] =
     29 {
     30 	0,1,2,3,4,1,
     31 	5,4,3,2,1,4,
     32 };
     33 
     34 static void draw_octahedron()
     35 {
     36 	glInterleavedArrays(GL_C3F_V3F, 0, octahedron_vertices);
     37 	glDrawElements(GL_TRIANGLE_FAN, 6, GL_UNSIGNED_BYTE, octahedron_indices + 0);
     38 	glDrawElements(GL_TRIANGLE_FAN, 6, GL_UNSIGNED_BYTE, octahedron_indices + 6);
     39 }
     40 
     41 float const duv = 1./32;
     42 
     43 struct vertex_t2v3
     44 {
     45 	float texcoord[2];
     46 	float vertex[3];
     47 } const plane_vertices[] =
     48 {
     49 	{{duv,duv}, {-.5,-.5,0.5}},
     50 	{{1-duv,duv}, { .5,-.5,0}},
     51 	{{duv,1-duv}, {-.5, .5,0}},
     52 	{{1-duv,1-duv}, { .5, .5,0}},
     53 };
     54 
     55 static void draw_plane()
     56 {
     57 
     58 	glEnable(GL_TEXTURE_2D);
     59 	glEnable(GL_POINT_SPRITE);
     60 	glColor3f(1,1,1);
     61 	
     62 	glInterleavedArrays(GL_V3F, sizeof(struct vertex_t2v3), plane_vertices->vertex);
     63 	glPointSize(64);
     64 	glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
     65 	glDrawArrays(GL_POINTS, 0, 4);
     66 	glDisable(GL_POINT_SPRITE);
     67 	glDisable(GL_TEXTURE_2D);
     68 }
     69 
     70 static void key_cb(GLFWwindow* w, int key, int /*scancode*/, int action, int /*mods*/)
     71 {
     72 	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
     73 		glfwSetWindowShouldClose(w, GLFW_TRUE);
     74 }
     75 
     76 static void set_frustum_size(int w, int h)
     77 {
     78 	double fru_horz = w / sqrt(w*w + h*h);
     79 	double fru_vert = h / sqrt(w*w + h*h);
     80 
     81 	PROJECTION_GUARD
     82 	{
     83 		glLoadIdentity();
     84 		glFrustum(-fru_horz, fru_horz, -fru_vert, fru_vert, 1.5, 8);
     85 		glTranslated(0, 0, -5);
     86 	}
     87 }
     88 
     89 static void fb_resize_cb(GLFWwindow*, int w, int h)
     90 {
     91 	glViewport(0, 0, w, h);
     92 	set_frustum_size(w, h);
     93 }
     94 
     95 static struct rgb {
     96 	unsigned char r,g,b;
     97 } tex[16*16*3];
     98 
     99 int main(int, char* argv[])
    100 {
    101 	struct rgb grey = {32,32,32};
    102 	for (unsigned i = 0; i < 16*16; ++i)
    103 	{
    104 		tex[i].r = i % 16 * 17;
    105 		tex[i].g = i / 16 * 17;
    106 		tex[i].b = 255-i;
    107 		tex[i] = grey;
    108 	};
    109 	struct rgb black = {0,0,0};
    110 	struct rgb green = {0,255,0};
    111 	for (unsigned i = 0; i < 16; ++i)
    112 	{
    113 		tex[i] = tex[15+i*16] = black;
    114 		tex[i*16] = tex[i+15*16] = green;
    115 	};
    116 	assert(glfwInit());
    117 	GLFWwindow* window = glfwCreateWindow(DEFAULT_W, DEFAULT_H, argv[0], NULL, NULL);
    118 	assert(window);
    119 	glfwMakeContextCurrent(window);
    120 	set_frustum_size(DEFAULT_W, DEFAULT_H);
    121 	glfwSetKeyCallback(window, key_cb);
    122 	glfwSetFramebufferSizeCallback(window, fb_resize_cb);
    123 	glfwSwapInterval(1);
    124 	glClearColor(0.2, 0.2, 0.2, 1);
    125 	glEnable(GL_CULL_FACE);
    126 	glEnable(GL_DEPTH_TEST);
    127 
    128 	glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, tex);
    129 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    130 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    131 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    132 
    133 	while (!glfwWindowShouldClose(window))
    134 	{
    135 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    136 
    137 		double t = glfwGetTime() / 8;
    138 		double turns = t * 6.283185307;
    139 		double deg = t * 360;
    140 
    141 		glLoadIdentity();
    142 		glTranslated(0, -.2, 0);
    143 		glRotated(-60, 1, 0, 0);
    144 		glRotated(deg / 7, 0, 0, 1);
    145 
    146 		MATRIX_GUARD
    147 		{
    148 			glRotated(deg, 0, 0, 1);
    149 			draw_octahedron();
    150 		}
    151 
    152 		MATRIX_GUARD
    153 		{
    154 			glTranslated(0, 0, 1);
    155 			glRotated(90, 0, 0, 1);
    156 			draw_octahedron();
    157 		}
    158 
    159 		MATRIX_GUARD
    160 		{
    161 			glTranslated(0, 0, -1);
    162 			glRotated(-90, 0, 0, 1);
    163 			draw_octahedron();
    164 		}
    165 
    166 		MATRIX_GUARD
    167 		{
    168 			glTranslated(sin(2*turns), cos(2*turns), sin(turns));
    169 			glRotated(180+deg, 0, 0, 1);
    170 			draw_plane();
    171 		}
    172 
    173 		glfwSwapBuffers(window);
    174 		glfwPollEvents();
    175 	}
    176 	glfwTerminate(); /* Implicit window destroy */
    177 }