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