rev |
line source |
nuclear@3
|
1 /*
|
nuclear@3
|
2 SaneGL - a small library to bring back sanity to OpenGL ES 2.x
|
nuclear@3
|
3 Copyright (C) 2011-2013 John Tsiombikas <nuclear@member.fsf.org>
|
nuclear@3
|
4
|
nuclear@3
|
5 This program is free software: you can redistribute it and/or modify
|
nuclear@3
|
6 it under the terms of the GNU General Public License as published by
|
nuclear@3
|
7 the Free Software Foundation, either version 3 of the License, or
|
nuclear@3
|
8 (at your option) any later version.
|
nuclear@3
|
9
|
nuclear@3
|
10 This program is distributed in the hope that it will be useful,
|
nuclear@3
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nuclear@3
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nuclear@3
|
13 GNU General Public License for more details.
|
nuclear@3
|
14
|
nuclear@3
|
15 You should have received a copy of the GNU General Public License
|
nuclear@3
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
nuclear@3
|
17 */
|
nuclear@3
|
18
|
nuclear@3
|
19 #include <stdio.h>
|
nuclear@3
|
20 #include <stdlib.h>
|
nuclear@3
|
21 #include <string.h>
|
nuclear@3
|
22 #include <math.h>
|
nuclear@3
|
23 #include <assert.h>
|
nuclear@3
|
24 #include "sanegl.h"
|
nuclear@3
|
25
|
nuclear@3
|
26 #define MAX_VERTS 512
|
nuclear@3
|
27
|
nuclear@3
|
28 static void gl_draw_immediate(void);
|
nuclear@3
|
29
|
nuclear@3
|
30 typedef struct { float x, y; } vec2_t;
|
nuclear@3
|
31 typedef struct { float x, y, z; } vec3_t;
|
nuclear@3
|
32 typedef struct { float x, y, z, w; } vec4_t;
|
nuclear@3
|
33
|
nuclear@3
|
34 static int prim = -1;
|
nuclear@3
|
35
|
nuclear@3
|
36 static vec3_t cur_normal;
|
nuclear@3
|
37 static vec4_t cur_color;
|
nuclear@3
|
38 static vec2_t cur_texcoord;
|
nuclear@3
|
39
|
nuclear@3
|
40 static vec4_t *vert_arr, *col_arr;
|
nuclear@3
|
41 static vec3_t *norm_arr;
|
nuclear@3
|
42 static vec2_t *texc_arr;
|
nuclear@3
|
43
|
nuclear@3
|
44 static int num_verts, vert_calls;
|
nuclear@3
|
45
|
nuclear@3
|
46 /* immediate mode rendering */
|
nuclear@3
|
47 void gl_begin(int p)
|
nuclear@3
|
48 {
|
nuclear@3
|
49 if(!vert_arr) {
|
nuclear@3
|
50 vert_arr = malloc(MAX_VERTS * sizeof *vert_arr);
|
nuclear@3
|
51 norm_arr = malloc(MAX_VERTS * sizeof *norm_arr);
|
nuclear@3
|
52 texc_arr = malloc(MAX_VERTS * sizeof *texc_arr);
|
nuclear@3
|
53 col_arr = malloc(MAX_VERTS * sizeof *col_arr);
|
nuclear@3
|
54 assert(vert_arr && norm_arr && texc_arr && col_arr);
|
nuclear@3
|
55 }
|
nuclear@3
|
56
|
nuclear@3
|
57 prim = p;
|
nuclear@3
|
58 num_verts = vert_calls = 0;
|
nuclear@3
|
59 }
|
nuclear@3
|
60
|
nuclear@3
|
61 void gl_end(void)
|
nuclear@3
|
62 {
|
nuclear@3
|
63 if(num_verts > 0) {
|
nuclear@3
|
64 gl_draw_immediate();
|
nuclear@3
|
65 }
|
nuclear@3
|
66 }
|
nuclear@3
|
67
|
nuclear@3
|
68 static void gl_draw_immediate(void)
|
nuclear@3
|
69 {
|
nuclear@3
|
70 int glprim;
|
nuclear@3
|
71
|
nuclear@3
|
72 glprim = prim == GL_QUADS ? GL_TRIANGLES : prim;
|
nuclear@3
|
73
|
nuclear@3
|
74 glEnableClientState(GL_VERTEX_ARRAY);
|
nuclear@3
|
75 glEnableClientState(GL_NORMAL_ARRAY);
|
nuclear@3
|
76 glEnableClientState(GL_COLOR_ARRAY);
|
nuclear@3
|
77 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@3
|
78
|
nuclear@3
|
79 glVertexPointer(4, GL_FLOAT, 0, vert_arr);
|
nuclear@3
|
80 glNormalPointer(GL_FLOAT, 0, norm_arr);
|
nuclear@3
|
81 glColorPointer(4, GL_FLOAT, 0, col_arr);
|
nuclear@3
|
82 glTexCoordPointer(2, GL_FLOAT, 0, texc_arr);
|
nuclear@3
|
83
|
nuclear@3
|
84 glDrawArrays(glprim, 0, num_verts);
|
nuclear@3
|
85
|
nuclear@3
|
86 glDisableClientState(GL_VERTEX_ARRAY);
|
nuclear@3
|
87 glDisableClientState(GL_NORMAL_ARRAY);
|
nuclear@3
|
88 glDisableClientState(GL_COLOR_ARRAY);
|
nuclear@3
|
89 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
nuclear@3
|
90 }
|
nuclear@3
|
91
|
nuclear@3
|
92 void gl_vertex2f(float x, float y)
|
nuclear@3
|
93 {
|
nuclear@3
|
94 gl_vertex4f(x, y, 0.0f, 1.0f);
|
nuclear@3
|
95 }
|
nuclear@3
|
96
|
nuclear@3
|
97 void gl_vertex3f(float x, float y, float z)
|
nuclear@3
|
98 {
|
nuclear@3
|
99 gl_vertex4f(x, y, z, 1.0f);
|
nuclear@3
|
100 }
|
nuclear@3
|
101
|
nuclear@3
|
102 void gl_vertex4f(float x, float y, float z, float w)
|
nuclear@3
|
103 {
|
nuclear@3
|
104 int i, buffer_full;
|
nuclear@3
|
105
|
nuclear@3
|
106 if(prim == GL_QUADS && vert_calls % 4 == 3) {
|
nuclear@3
|
107 for(i=0; i<2; i++) {
|
nuclear@3
|
108 col_arr[num_verts] = col_arr[num_verts - 3 + i];
|
nuclear@3
|
109 texc_arr[num_verts] = texc_arr[num_verts - 3 + i];
|
nuclear@3
|
110 norm_arr[num_verts] = norm_arr[num_verts - 3 + i];
|
nuclear@3
|
111 vert_arr[num_verts] = vert_arr[num_verts - 3 + i];
|
nuclear@3
|
112 num_verts++;
|
nuclear@3
|
113 }
|
nuclear@3
|
114 }
|
nuclear@3
|
115
|
nuclear@3
|
116 vert_arr[num_verts].x = x;
|
nuclear@3
|
117 vert_arr[num_verts].y = y;
|
nuclear@3
|
118 vert_arr[num_verts].z = z;
|
nuclear@3
|
119 vert_arr[num_verts].w = w;
|
nuclear@3
|
120
|
nuclear@3
|
121 col_arr[num_verts] = cur_color;
|
nuclear@3
|
122 norm_arr[num_verts] = cur_normal;
|
nuclear@3
|
123 texc_arr[num_verts] = cur_texcoord;
|
nuclear@3
|
124
|
nuclear@3
|
125 vert_calls++;
|
nuclear@3
|
126 num_verts++;
|
nuclear@3
|
127
|
nuclear@3
|
128 if(prim == GL_QUADS) {
|
nuclear@3
|
129 /* leave space for 6 more worst-case and don't allow flushes mid-quad */
|
nuclear@3
|
130 buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0;
|
nuclear@3
|
131 } else {
|
nuclear@3
|
132 buffer_full = num_verts >= MAX_VERTS - prim;
|
nuclear@3
|
133 }
|
nuclear@3
|
134
|
nuclear@3
|
135 if(buffer_full) {
|
nuclear@3
|
136 gl_draw_immediate();
|
nuclear@3
|
137 gl_begin(prim); /* reset everything */
|
nuclear@3
|
138 }
|
nuclear@3
|
139 }
|
nuclear@3
|
140
|
nuclear@3
|
141
|
nuclear@3
|
142 void gl_normal3f(float x, float y, float z)
|
nuclear@3
|
143 {
|
nuclear@3
|
144 cur_normal.x = x;
|
nuclear@3
|
145 cur_normal.y = y;
|
nuclear@3
|
146 cur_normal.z = z;
|
nuclear@3
|
147 }
|
nuclear@3
|
148
|
nuclear@3
|
149
|
nuclear@3
|
150 void gl_color3f(float r, float g, float b)
|
nuclear@3
|
151 {
|
nuclear@3
|
152 cur_color.x = r;
|
nuclear@3
|
153 cur_color.y = g;
|
nuclear@3
|
154 cur_color.z = b;
|
nuclear@3
|
155 cur_color.w = 1.0f;
|
nuclear@3
|
156 }
|
nuclear@3
|
157
|
nuclear@3
|
158 void gl_color4f(float r, float g, float b, float a)
|
nuclear@3
|
159 {
|
nuclear@3
|
160 cur_color.x = r;
|
nuclear@3
|
161 cur_color.y = g;
|
nuclear@3
|
162 cur_color.z = b;
|
nuclear@3
|
163 cur_color.w = a;
|
nuclear@3
|
164 }
|
nuclear@3
|
165
|
nuclear@3
|
166
|
nuclear@3
|
167 void gl_texcoord1f(float s)
|
nuclear@3
|
168 {
|
nuclear@3
|
169 cur_texcoord.x = s;
|
nuclear@3
|
170 cur_texcoord.y = 0.0f;
|
nuclear@3
|
171 }
|
nuclear@3
|
172
|
nuclear@3
|
173 void gl_texcoord2f(float s, float t)
|
nuclear@3
|
174 {
|
nuclear@3
|
175 cur_texcoord.x = s;
|
nuclear@3
|
176 cur_texcoord.y = t;
|
nuclear@3
|
177 }
|
nuclear@3
|
178
|
nuclear@3
|
179 void glu_perspective(float fov, float aspect, float nearz, float farz)
|
nuclear@3
|
180 {
|
nuclear@3
|
181 float fovrad = M_PI * fov / 180.0;
|
nuclear@3
|
182 float halfsz = tan(fovrad) * nearz;
|
nuclear@3
|
183
|
nuclear@3
|
184 glFrustumf(-halfsz * aspect, halfsz * aspect, -halfsz, halfsz, nearz, farz);
|
nuclear@3
|
185 }
|