6 #include "cgmath/cgmath.h"
15 #define MMODE_IDX(x) ((x) - GL_MODELVIEW)
16 #define MAT_STACK_SIZE 32
17 #define MAT_IDENT {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
21 static void gl_draw_immediate(void);
23 typedef struct { float x, y; } vec2_t;
24 typedef struct { float x, y, z; } vec3_t;
25 typedef struct { float x, y, z, w; } vec4_t;
27 static int mm_idx = 0;
28 static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}};
29 static int stack_top[3];
30 static float mat_mvp[16];
34 static vec3_t cur_normal = {0, 0, 1};
35 static vec4_t cur_color = {1, 1, 1, 1}, cur_attrib;
36 static vec2_t cur_texcoord;
38 static vec4_t *vert_arr, *col_arr, *attr_arr;
39 static vec3_t *norm_arr;
40 static vec2_t *texc_arr;
41 /*static unsigned int vbuf, cbuf, nbuf, tbuf, abuf;*/
42 static int vloc, nloc, cloc, tloc, aloc = -1;
44 static int num_verts, vert_calls;
48 void gl_matrix_mode(int mm)
50 mm_idx = MMODE_IDX(mm);
53 void gl_push_matrix(void)
55 int top = stack_top[mm_idx];
57 memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float));
62 void gl_pop_matrix(void)
68 void gl_load_identity(void)
70 static const float idmat[] = MAT_IDENT;
71 int top = stack_top[mm_idx];
72 float *mat = mat_stack[mm_idx][top];
74 memcpy(mat, idmat, sizeof idmat);
78 void gl_load_matrixf(const float *m)
80 int top = stack_top[mm_idx];
81 float *mat = mat_stack[mm_idx][top];
83 memcpy(mat, m, 16 * sizeof *mat);
87 #define M(i, j) ((i << 2) + j)
89 void gl_mult_matrixf(const float *m2)
91 int top = stack_top[mm_idx];
92 float *m1 = mat_stack[mm_idx][top];
98 void gl_translatef(float x, float y, float z)
101 cgm_mtranslation(mat, x, y, z);
102 gl_mult_matrixf(mat);
105 void gl_rotatef(float angle, float x, float y, float z)
108 cgm_mrotation(mat, cgm_deg_to_rad(angle), x, y, z);
109 gl_mult_matrixf(mat);
112 void gl_scalef(float x, float y, float z)
115 cgm_mscaling(mat, x, y, z);
116 gl_mult_matrixf(mat);
119 void gl_ortho(float left, float right, float bottom, float top, float znear, float zfar)
122 cgm_mortho(mat, left, right, bottom, top, znear, zfar);
123 gl_mult_matrixf(mat);
126 void gl_frustum(float left, float right, float bottom, float top, float znear, float zfar)
129 cgm_mfrustum(mat, left, right, bottom, top, znear, zfar);
130 gl_mult_matrixf(mat);
133 void glu_perspective(float vfov, float aspect, float znear, float zfar)
136 cgm_mperspective(mat, cgm_deg_to_rad(vfov), aspect, znear, zfar);
137 gl_mult_matrixf(mat);
140 void gl_apply_xform(unsigned int prog)
142 int loc, mvidx, pidx, tidx, mvtop, ptop, ttop;
144 mvidx = MMODE_IDX(GL_MODELVIEW);
145 pidx = MMODE_IDX(GL_PROJECTION);
146 tidx = MMODE_IDX(GL_TEXTURE);
148 mvtop = stack_top[mvidx];
149 ptop = stack_top[pidx];
150 ttop = stack_top[tidx];
154 if((loc = glGetUniformLocation(prog, "matrix_modelview")) != -1) {
155 glUniformMatrix4fv(loc, 1, 0, mat_stack[mvidx][mvtop]);
158 if((loc = glGetUniformLocation(prog, "matrix_projection")) != -1) {
159 glUniformMatrix4fv(loc, 1, 0, mat_stack[pidx][ptop]);
162 if((loc = glGetUniformLocation(prog, "matrix_texture")) != -1) {
163 glUniformMatrix4fv(loc, 1, 0, mat_stack[tidx][ttop]);
166 if((loc = glGetUniformLocation(prog, "matrix_normal")) != -1) {
169 nmat[0] = mat_stack[mvidx][mvtop][0];
170 nmat[1] = mat_stack[mvidx][mvtop][1];
171 nmat[2] = mat_stack[mvidx][mvtop][2];
172 nmat[3] = mat_stack[mvidx][mvtop][4];
173 nmat[4] = mat_stack[mvidx][mvtop][5];
174 nmat[5] = mat_stack[mvidx][mvtop][6];
175 nmat[6] = mat_stack[mvidx][mvtop][8];
176 nmat[7] = mat_stack[mvidx][mvtop][9];
177 nmat[8] = mat_stack[mvidx][mvtop][10];
178 glUniformMatrix3fv(loc, 1, 0, nmat);
181 if((loc = glGetUniformLocation(prog, "matrix_modelview_projection")) != -1) {
183 cgm_mcopy(mat_mvp, mat_stack[mvidx][mvtop]);
184 cgm_mmul(mat_mvp, mat_stack[pidx][ptop]);
186 glUniformMatrix4fv(loc, 1, 0, mat_mvp);
191 /* immediate mode rendering */
195 vert_arr = malloc(MAX_VERTS * sizeof *vert_arr);
196 norm_arr = malloc(MAX_VERTS * sizeof *norm_arr);
197 texc_arr = malloc(MAX_VERTS * sizeof *texc_arr);
198 col_arr = malloc(MAX_VERTS * sizeof *col_arr);
199 attr_arr = malloc(MAX_VERTS * sizeof *attr_arr);
200 assert(vert_arr && norm_arr && texc_arr && col_arr && attr_arr);
204 num_verts = vert_calls = 0;
206 glGetIntegerv(GL_CURRENT_PROGRAM, &cur_prog);
209 gl_apply_xform(cur_prog);
211 vloc = glGetAttribLocation(cur_prog, "attr_vertex");
212 nloc = glGetAttribLocation(cur_prog, "attr_normal");
213 cloc = glGetAttribLocation(cur_prog, "attr_color");
214 tloc = glGetAttribLocation(cur_prog, "attr_texcoord");
225 static void gl_draw_immediate(void)
230 fprintf(stderr, "gl_draw_immediate call with vloc == -1\n");
234 glprim = prim == GL_QUADS ? GL_TRIANGLES : prim;
236 glVertexAttribPointer(vloc, 4, GL_FLOAT, 0, 0, vert_arr);
237 glEnableVertexAttribArray(vloc);
240 glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, norm_arr);
241 glEnableVertexAttribArray(nloc);
245 glVertexAttribPointer(cloc, 4, GL_FLOAT, 1, 0, col_arr);
246 glEnableVertexAttribArray(cloc);
250 glVertexAttribPointer(tloc, 2, GL_FLOAT, 0, 0, texc_arr);
251 glEnableVertexAttribArray(tloc);
255 glVertexAttribPointer(aloc, 4, GL_FLOAT, 0, 0, attr_arr);
256 glEnableVertexAttribArray(aloc);
259 glDrawArrays(glprim, 0, num_verts);
261 glDisableVertexAttribArray(vloc);
263 glDisableVertexAttribArray(nloc);
266 glDisableVertexAttribArray(cloc);
269 glDisableVertexAttribArray(tloc);
272 glDisableVertexAttribArray(aloc);
277 void gl_vertex2f(float x, float y)
279 gl_vertex4f(x, y, 0.0f, 1.0f);
282 void gl_vertex3f(float x, float y, float z)
284 gl_vertex4f(x, y, z, 1.0f);
287 void gl_vertex4f(float x, float y, float z, float w)
291 if(prim == GL_QUADS && vert_calls % 4 == 3) {
294 attr_arr[num_verts] = attr_arr[num_verts - 3 + i];
297 col_arr[num_verts] = col_arr[num_verts - 3 + i];
300 texc_arr[num_verts] = texc_arr[num_verts - 3 + i];
303 norm_arr[num_verts] = norm_arr[num_verts - 3 + i];
305 vert_arr[num_verts] = vert_arr[num_verts - 3 + i];
310 vert_arr[num_verts].x = x;
311 vert_arr[num_verts].y = y;
312 vert_arr[num_verts].z = z;
313 vert_arr[num_verts].w = w;
316 col_arr[num_verts] = cur_color;
319 norm_arr[num_verts] = cur_normal;
322 texc_arr[num_verts] = cur_texcoord;
325 attr_arr[num_verts] = cur_attrib;
331 if(prim == GL_QUADS) {
332 /* leave space for 6 more worst-case and don't allow flushes mid-quad */
333 buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0;
335 buffer_full = num_verts >= MAX_VERTS - prim;
340 gl_begin(prim); /* reset everything */
345 void gl_normal3f(float x, float y, float z)
353 void gl_color3f(float r, float g, float b)
361 void gl_color4f(float r, float g, float b, float a)
370 void gl_texcoord1f(float s)
373 cur_texcoord.y = 0.0f;
376 void gl_texcoord2f(float s, float t)
382 void gl_vertex_attrib2f(int loc, float x, float y)
391 void gl_vertex_attrib3f(int loc, float x, float y, float z)
400 void gl_vertex_attrib4f(int loc, float x, float y, float z, float w)