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