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 }