rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <math.h>
|
nuclear@11
|
4 #include <assert.h>
|
nuclear@0
|
5 #include "opengl.h"
|
nuclear@0
|
6 #include "game.h"
|
nuclear@7
|
7 #include "camera.h"
|
nuclear@10
|
8 #include "sdr.h"
|
nuclear@11
|
9 #include "sanegl.h"
|
nuclear@17
|
10 #include "texture.h"
|
nuclear@7
|
11
|
nuclear@17
|
12 static void draw_quad(float hsz, float vsz, unsigned int sdr);
|
nuclear@0
|
13
|
nuclear@0
|
14 static int win_width, win_height;
|
nuclear@9
|
15 static float win_aspect;
|
nuclear@9
|
16 static int video_width, video_height;
|
nuclear@9
|
17 static float video_aspect;
|
nuclear@17
|
18 static unsigned int sdrprog, sdrprog_test;
|
nuclear@17
|
19 static int uloc_tex, uloc_test_tex;
|
nuclear@17
|
20 static struct texture *test_tex;
|
nuclear@17
|
21
|
nuclear@17
|
22 enum { ATTR_VERTEX, ATTR_TEXCOORD };
|
nuclear@10
|
23
|
nuclear@10
|
24 static const char *vsdr_source =
|
nuclear@11
|
25 "attribute vec4 attr_vertex, attr_texcoord;\n"
|
nuclear@11
|
26 "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n"
|
nuclear@10
|
27 "varying vec4 tex_coords;\n"
|
nuclear@10
|
28 "void main()\n"
|
nuclear@10
|
29 "{\n"
|
nuclear@11
|
30 "\tmat4 mvp = matrix_projection * matrix_modelview;\n"
|
nuclear@11
|
31 "\tgl_Position = mvp * attr_vertex;\n"
|
nuclear@11
|
32 "\ttex_coords = matrix_texture * attr_texcoord;\n"
|
nuclear@10
|
33 "}\n";
|
nuclear@10
|
34
|
nuclear@17
|
35 static const char *psdr_cam_source =
|
nuclear@10
|
36 "#extension GL_OES_EGL_image_external : require\n"
|
nuclear@11
|
37 "precision mediump float;\n"
|
nuclear@10
|
38 "uniform samplerExternalOES tex;\n"
|
nuclear@10
|
39 "varying vec4 tex_coords;\n"
|
nuclear@10
|
40 "void main()\n"
|
nuclear@10
|
41 "{\n"
|
nuclear@10
|
42 "\tvec4 texel = texture2D(tex, tex_coords.xy);\n"
|
nuclear@10
|
43 "\tgl_FragColor = vec4(texel.xyz, 1.0);\n"
|
nuclear@10
|
44 "}\n";
|
nuclear@0
|
45
|
nuclear@17
|
46 static const char *psdr_tex_source =
|
nuclear@17
|
47 "precision mediump float;\n"
|
nuclear@17
|
48 "uniform sampler2D tex;\n"
|
nuclear@17
|
49 "varying vec4 tex_coords;\n"
|
nuclear@17
|
50 "void main()\n"
|
nuclear@17
|
51 "{\n"
|
nuclear@17
|
52 "\tvec4 texel = texture2D(tex, tex_coords.xy);\n"
|
nuclear@17
|
53 "\tgl_FragColor = texel;\n"
|
nuclear@17
|
54 "}\n";
|
nuclear@0
|
55
|
nuclear@0
|
56 int game_init(void)
|
nuclear@0
|
57 {
|
nuclear@17
|
58 unsigned int vsdr, psdr_cam, psdr_tex;
|
nuclear@10
|
59
|
nuclear@17
|
60 //glEnable(GL_DEPTH_TEST);
|
nuclear@0
|
61 glEnable(GL_CULL_FACE);
|
nuclear@0
|
62
|
nuclear@0
|
63 glClearColor(0.4, 0.4, 0.4, 1);
|
nuclear@8
|
64
|
nuclear@10
|
65 if(!(vsdr = create_vertex_shader(vsdr_source)))
|
nuclear@10
|
66 return -1;
|
nuclear@11
|
67 assert(glGetError() == GL_NO_ERROR);
|
nuclear@17
|
68 if(!(psdr_cam = create_pixel_shader(psdr_cam_source)))
|
nuclear@10
|
69 return -1;
|
nuclear@11
|
70 assert(glGetError() == GL_NO_ERROR);
|
nuclear@17
|
71 if(!(psdr_tex = create_pixel_shader(psdr_tex_source)))
|
nuclear@17
|
72 return -1;
|
nuclear@17
|
73 assert(glGetError() == GL_NO_ERROR);
|
nuclear@17
|
74 if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) {
|
nuclear@10
|
75 fprintf(stderr, "failed to create shader program\n");
|
nuclear@10
|
76 return -1;
|
nuclear@10
|
77 }
|
nuclear@17
|
78 if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) {
|
nuclear@17
|
79 fprintf(stderr, "failed to create test shader program\n");
|
nuclear@17
|
80 return -1;
|
nuclear@17
|
81 }
|
nuclear@17
|
82
|
nuclear@10
|
83 glUseProgram(sdrprog);
|
nuclear@17
|
84 glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex");
|
nuclear@17
|
85 glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord");
|
nuclear@11
|
86 uloc_tex = glGetUniformLocation(sdrprog, "tex");
|
nuclear@17
|
87 glLinkProgram(sdrprog);
|
nuclear@17
|
88
|
nuclear@17
|
89 glUseProgram(sdrprog_test);
|
nuclear@17
|
90 glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex");
|
nuclear@17
|
91 glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord");
|
nuclear@17
|
92 uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex");
|
nuclear@17
|
93 glLinkProgram(sdrprog_test);
|
nuclear@17
|
94
|
nuclear@17
|
95 if(!(test_tex = get_texture("data/opengl.png"))) {
|
nuclear@17
|
96 return -1;
|
nuclear@17
|
97 }
|
nuclear@10
|
98
|
nuclear@8
|
99 cam_start_video();
|
nuclear@9
|
100 cam_video_size(&video_width, &video_height);
|
nuclear@9
|
101 if(video_height) {
|
nuclear@9
|
102 video_aspect = (float)video_width / (float)video_height;
|
nuclear@9
|
103 } else {
|
nuclear@9
|
104 video_aspect = 1.0;
|
nuclear@9
|
105 }
|
nuclear@9
|
106
|
nuclear@9
|
107 printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect);
|
nuclear@0
|
108 return 0;
|
nuclear@0
|
109 }
|
nuclear@0
|
110
|
nuclear@0
|
111 void game_shutdown(void)
|
nuclear@0
|
112 {
|
nuclear@8
|
113 cam_shutdown();
|
nuclear@10
|
114 free_program(sdrprog);
|
nuclear@0
|
115 }
|
nuclear@0
|
116
|
nuclear@0
|
117 void game_display(unsigned long msec)
|
nuclear@0
|
118 {
|
nuclear@9
|
119 unsigned int tex;
|
nuclear@9
|
120 const float *tex_matrix;
|
nuclear@9
|
121 float xscale, yscale;
|
nuclear@9
|
122
|
nuclear@8
|
123 cam_update();
|
nuclear@9
|
124 tex = cam_texture();
|
nuclear@9
|
125 tex_matrix = cam_texture_matrix();
|
nuclear@7
|
126
|
nuclear@4
|
127 //float tsec = (float)msec / 1000.0f;
|
nuclear@0
|
128
|
nuclear@0
|
129 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@0
|
130
|
nuclear@11
|
131 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@11
|
132 gl_load_identity();
|
nuclear@11
|
133 gl_matrix_mode(GL_TEXTURE);
|
nuclear@11
|
134 gl_load_matrixf(tex_matrix);
|
nuclear@11
|
135
|
nuclear@10
|
136 glUseProgram(sdrprog);
|
nuclear@10
|
137 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
|
nuclear@11
|
138 if(uloc_tex >= 0) {
|
nuclear@11
|
139 glUniform1i(uloc_tex, 0);
|
nuclear@11
|
140 }
|
nuclear@7
|
141
|
nuclear@9
|
142 if(video_aspect > win_aspect) {
|
nuclear@9
|
143 xscale = 1.0;
|
nuclear@9
|
144 yscale = 1.0 / video_aspect;
|
nuclear@9
|
145 } else {
|
nuclear@9
|
146 xscale = video_aspect;
|
nuclear@9
|
147 yscale = 1.0;
|
nuclear@9
|
148 }
|
nuclear@17
|
149 draw_quad(xscale, yscale, sdrprog);
|
nuclear@17
|
150
|
nuclear@17
|
151 gl_matrix_mode(GL_TEXTURE);
|
nuclear@17
|
152 gl_load_identity();
|
nuclear@17
|
153 gl_translatef(0, 1, 0);
|
nuclear@17
|
154 gl_scalef(1, -1, 1);
|
nuclear@17
|
155 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@17
|
156 gl_load_identity();
|
nuclear@17
|
157 gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1);
|
nuclear@17
|
158
|
nuclear@17
|
159 glUseProgram(sdrprog_test);
|
nuclear@17
|
160 glBindTexture(GL_TEXTURE_2D, test_tex->texid);
|
nuclear@17
|
161 if(uloc_test_tex >= 0) {
|
nuclear@17
|
162 glUniform1i(uloc_test_tex, 0);
|
nuclear@17
|
163 }
|
nuclear@17
|
164
|
nuclear@17
|
165 glEnable(GL_BLEND);
|
nuclear@17
|
166 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
nuclear@17
|
167
|
nuclear@17
|
168 draw_quad(0.5, 0.5, sdrprog_test);
|
nuclear@17
|
169
|
nuclear@17
|
170 glDisable(GL_BLEND);
|
nuclear@7
|
171 }
|
nuclear@7
|
172
|
nuclear@17
|
173 static void draw_quad(float hsz, float vsz, unsigned int sdr)
|
nuclear@7
|
174 {
|
nuclear@7
|
175 static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
|
nuclear@9
|
176 static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
|
nuclear@7
|
177
|
nuclear@11
|
178 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@11
|
179 gl_push_matrix();
|
nuclear@11
|
180 gl_scalef(hsz, vsz, 1);
|
nuclear@11
|
181
|
nuclear@17
|
182 gl_apply_xform(sdr);
|
nuclear@7
|
183
|
nuclear@17
|
184 glEnableVertexAttribArray(ATTR_VERTEX);
|
nuclear@17
|
185 glEnableVertexAttribArray(ATTR_TEXCOORD);
|
nuclear@17
|
186 glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr);
|
nuclear@17
|
187 glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr);
|
nuclear@7
|
188
|
nuclear@8
|
189 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
nuclear@7
|
190
|
nuclear@17
|
191 glDisableVertexAttribArray(ATTR_VERTEX);
|
nuclear@17
|
192 glDisableVertexAttribArray(ATTR_TEXCOORD);
|
nuclear@11
|
193
|
nuclear@11
|
194 gl_pop_matrix();
|
nuclear@0
|
195 }
|
nuclear@0
|
196
|
nuclear@0
|
197 void game_reshape(int x, int y)
|
nuclear@0
|
198 {
|
nuclear@0
|
199 win_width = x;
|
nuclear@0
|
200 win_height = y;
|
nuclear@9
|
201 win_aspect = y ? (float)x / (float)y : 1.0;
|
nuclear@0
|
202 glViewport(0, 0, x, y);
|
nuclear@0
|
203
|
nuclear@11
|
204 gl_matrix_mode(GL_PROJECTION);
|
nuclear@11
|
205 gl_load_identity();
|
nuclear@11
|
206 gl_scalef((float)win_height / (float)win_width, 1, 1);
|
nuclear@0
|
207 }
|
nuclear@0
|
208
|
nuclear@0
|
209 void game_keyboard(int key, int pressed)
|
nuclear@0
|
210 {
|
nuclear@0
|
211 if(!pressed) return;
|
nuclear@0
|
212
|
nuclear@0
|
213 switch(key) {
|
nuclear@0
|
214 case 27:
|
nuclear@0
|
215 exit(0);
|
nuclear@0
|
216
|
nuclear@0
|
217 default:
|
nuclear@0
|
218 break;
|
nuclear@0
|
219 }
|
nuclear@0
|
220 }
|
nuclear@0
|
221
|
nuclear@0
|
222 #define MAX_TOUCH_IDS 16
|
nuclear@0
|
223 static struct {
|
nuclear@0
|
224 int bnstate[8];
|
nuclear@0
|
225 int prev_x, prev_y;
|
nuclear@0
|
226 } mstate[MAX_TOUCH_IDS];
|
nuclear@0
|
227
|
nuclear@0
|
228 void game_mouse_button(int id, int bn, int pressed, int x, int y)
|
nuclear@0
|
229 {
|
nuclear@0
|
230 if(id >= MAX_TOUCH_IDS) return;
|
nuclear@0
|
231
|
nuclear@0
|
232 mstate[id].prev_x = x;
|
nuclear@0
|
233 mstate[id].prev_y = y;
|
nuclear@0
|
234 mstate[id].bnstate[bn] = pressed;
|
nuclear@0
|
235 }
|
nuclear@0
|
236
|
nuclear@0
|
237 void game_mouse_motion(int id, int x, int y)
|
nuclear@0
|
238 {
|
nuclear@0
|
239 /*
|
nuclear@0
|
240 int dx, dy, cx, cy;
|
nuclear@0
|
241
|
nuclear@0
|
242 if(id >= MAX_TOUCH_IDS) return;
|
nuclear@0
|
243
|
nuclear@0
|
244 cx = win_width / 2;
|
nuclear@0
|
245 cy = win_height / 2;
|
nuclear@0
|
246
|
nuclear@0
|
247 dx = x - mstate[id].prev_x;
|
nuclear@0
|
248 dy = y - mstate[id].prev_y;
|
nuclear@0
|
249 mstate[id].prev_x = x;
|
nuclear@0
|
250 mstate[id].prev_y = y;
|
nuclear@0
|
251
|
nuclear@0
|
252 if(!dx && !dy) return;
|
nuclear@0
|
253
|
nuclear@0
|
254 if(mouselook || mstate[id].bnstate[0]) {
|
nuclear@0
|
255 player_turn(&player, dx * 0.5, dy * 0.5);
|
nuclear@0
|
256 }
|
nuclear@0
|
257 if(mstate[id].bnstate[2]) {
|
nuclear@0
|
258 dbg_cam_dist += 0.1 * dy;
|
nuclear@0
|
259 if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0;
|
nuclear@0
|
260 }
|
nuclear@0
|
261
|
nuclear@0
|
262 if(mouselook) {
|
nuclear@0
|
263 warping_mouse = 1;
|
nuclear@0
|
264 set_mouse_pos(cx, cy);
|
nuclear@0
|
265 mstate[id].prev_x = cx;
|
nuclear@0
|
266 mstate[id].prev_y = cy;
|
nuclear@0
|
267 }
|
nuclear@0
|
268 */
|
nuclear@0
|
269 }
|
nuclear@0
|
270
|