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