tesspot
changeset 0:72b7f9f2eead
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 02 Dec 2012 08:23:51 +0200 |
parents | |
children | befe01bbd27f |
files | .hgignore Makefile sdr/bezier.p.glsl sdr/bezier.tc.glsl sdr/bezier.te.glsl sdr/bezier.v.glsl src/sdr.c src/sdr.h src/teapot_data.h src/test.c |
diffstat | 10 files changed, 1024 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Sun Dec 02 08:23:51 2012 +0200 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +^test$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Sun Dec 02 08:23:51 2012 +0200 2.3 @@ -0,0 +1,19 @@ 2.4 +src = $(wildcard src/*.c) 2.5 +obj = $(src:.c=.o) 2.6 +bin = test 2.7 + 2.8 +CFLAGS = -pedantic -Wall -g 2.9 +LDFLAGS = $(libgl) 2.10 + 2.11 +ifeq ($(shell uname -s), Darwin) 2.12 + libgl = -framework OpenGL -framework GLUT -lglew 2.13 +else 2.14 + libgl = -lGL -lGLU -lglut -lGLEW 2.15 +endif 2.16 + 2.17 +$(bin): $(obj) 2.18 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.19 + 2.20 +.PHONY: clean 2.21 +clean: 2.22 + rm -f $(obj) $(bin)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/sdr/bezier.p.glsl Sun Dec 02 08:23:51 2012 +0200 3.3 @@ -0,0 +1,26 @@ 3.4 +#version 410 compatibility 3.5 + 3.6 +in vec3 normal; 3.7 +in vec3 vpos; 3.8 + 3.9 +void main() 3.10 +{ 3.11 + vec3 ldir = gl_LightSource[0].position.xyz - vpos; 3.12 + 3.13 + vec3 n = normalize(normal); 3.14 + vec3 v = -normalize(vpos); 3.15 + vec3 l = normalize(ldir); 3.16 + vec3 h = normalize(l + v); 3.17 + 3.18 + float ndotl = max(dot(n, l), 0.0); 3.19 + float ndoth = max(dot(n, h), 0.0); 3.20 + 3.21 + vec3 kd = gl_FrontMaterial.diffuse.xyz; 3.22 + vec3 ks = gl_FrontMaterial.specular.xyz; 3.23 + float shin = gl_FrontMaterial.shininess; 3.24 + 3.25 + vec3 diffuse = kd * ndotl * gl_LightSource[0].diffuse.xyz; 3.26 + vec3 specular = ks * pow(ndoth, shin) * gl_LightSource[0].specular.xyz; 3.27 + 3.28 + gl_FragColor = vec4(diffuse + specular, gl_FrontMaterial.diffuse.w); 3.29 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/sdr/bezier.tc.glsl Sun Dec 02 08:23:51 2012 +0200 4.3 @@ -0,0 +1,18 @@ 4.4 +#version 410 compatibility 4.5 + 4.6 +layout(vertices = 16) out; 4.7 + 4.8 +uniform int tess_level; 4.9 + 4.10 +void main() 4.11 +{ 4.12 + gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 4.13 + 4.14 + gl_TessLevelInner[0] = tess_level; 4.15 + gl_TessLevelInner[1] = tess_level; 4.16 + 4.17 + gl_TessLevelOuter[0] = tess_level; 4.18 + gl_TessLevelOuter[1] = tess_level; 4.19 + gl_TessLevelOuter[2] = tess_level; 4.20 + gl_TessLevelOuter[3] = tess_level; 4.21 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/sdr/bezier.te.glsl Sun Dec 02 08:23:51 2012 +0200 5.3 @@ -0,0 +1,59 @@ 5.4 +#version 410 compatibility 5.5 + 5.6 +layout(quads) in; 5.7 + 5.8 +out vec3 normal; 5.9 +out vec3 vpos; 5.10 + 5.11 +vec3 bezier_patch(float u, float v); 5.12 +vec3 bezier_patch_norm(float u, float v); 5.13 +float bernstein(int i, float x); 5.14 + 5.15 +void main() 5.16 +{ 5.17 + vec3 pos = bezier_patch(gl_TessCoord.x, gl_TessCoord.y); 5.18 + normal = gl_NormalMatrix * bezier_patch_norm(gl_TessCoord.x, gl_TessCoord.y); 5.19 + 5.20 + gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0); 5.21 + vpos = (gl_ModelViewMatrix * vec4(pos, 1.0)).xyz; 5.22 +} 5.23 + 5.24 +vec3 bezier_patch(float u, float v) 5.25 +{ 5.26 + int i, j; 5.27 + vec3 res = vec3(0.0, 0.0, 0.0); 5.28 + 5.29 + for(j=0; j<4; j++) { 5.30 + for(i=0; i<4; i++) { 5.31 + float bu = bernstein(i, u); 5.32 + float bv = bernstein(j, v); 5.33 + 5.34 + res += gl_in[j * 4 + i].gl_Position.xyz * bu * bv; 5.35 + } 5.36 + } 5.37 + return res; 5.38 +} 5.39 + 5.40 +#define DT 0.0001 5.41 +vec3 bezier_patch_norm(float u, float v) 5.42 +{ 5.43 + vec3 tang = bezier_patch(u + DT, v) - bezier_patch(u - DT, v); 5.44 + vec3 bitan = bezier_patch(u, v + DT) - bezier_patch(u, v - DT); 5.45 + return cross(tang, bitan); 5.46 +} 5.47 + 5.48 +float bernstein(int i, float x) 5.49 +{ 5.50 + float invx = 1.0 - x; 5.51 + 5.52 + if(i == 0) { 5.53 + return invx * invx * invx; 5.54 + } 5.55 + if(i == 1) { 5.56 + return 3 * x * invx * invx; 5.57 + } 5.58 + if(i == 2) { 5.59 + return 3 * x * x * invx; 5.60 + } 5.61 + return x * x * x; 5.62 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/sdr/bezier.v.glsl Sun Dec 02 08:23:51 2012 +0200 6.3 @@ -0,0 +1,6 @@ 6.4 +#version 410 compatibility 6.5 + 6.6 +void main() 6.7 +{ 6.8 + gl_Position = gl_Vertex; 6.9 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/sdr.c Sun Dec 02 08:23:51 2012 +0200 7.3 @@ -0,0 +1,410 @@ 7.4 +#include <stdio.h> 7.5 +#include <stdlib.h> 7.6 +#include <string.h> 7.7 +#include <errno.h> 7.8 +#include <stdarg.h> 7.9 +#include <assert.h> 7.10 +#include <GL/glew.h> 7.11 + 7.12 +#if defined(unix) || defined(__unix__) 7.13 +#include <unistd.h> 7.14 +#include <sys/stat.h> 7.15 +#endif /* unix */ 7.16 + 7.17 +#include "sdr.h" 7.18 + 7.19 +static const char *sdrtypestr(unsigned int sdrtype); 7.20 + 7.21 +unsigned int create_vertex_shader(const char *src) 7.22 +{ 7.23 + return create_shader(src, GL_VERTEX_SHADER); 7.24 +} 7.25 + 7.26 +unsigned int create_pixel_shader(const char *src) 7.27 +{ 7.28 + return create_shader(src, GL_FRAGMENT_SHADER); 7.29 +} 7.30 + 7.31 +unsigned int create_tessctl_shader(const char *src) 7.32 +{ 7.33 + return create_shader(src, GL_TESS_CONTROL_SHADER); 7.34 +} 7.35 + 7.36 +unsigned int create_tesseval_shader(const char *src) 7.37 +{ 7.38 + return create_shader(src, GL_TESS_EVALUATION_SHADER); 7.39 +} 7.40 + 7.41 +unsigned int create_geometry_shader(const char *src) 7.42 +{ 7.43 + return create_shader(src, GL_GEOMETRY_SHADER); 7.44 +} 7.45 + 7.46 +unsigned int create_shader(const char *src, unsigned int sdr_type) 7.47 +{ 7.48 + unsigned int sdr; 7.49 + int success, info_len; 7.50 + char *info_str = 0; 7.51 + GLenum err; 7.52 + 7.53 + sdr = glCreateShader(sdr_type); 7.54 + assert(glGetError() == GL_NO_ERROR); 7.55 + glShaderSource(sdr, 1, &src, 0); 7.56 + err = glGetError(); 7.57 + assert(err == GL_NO_ERROR); 7.58 + glCompileShader(sdr); 7.59 + assert(glGetError() == GL_NO_ERROR); 7.60 + 7.61 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 7.62 + assert(glGetError() == GL_NO_ERROR); 7.63 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 7.64 + assert(glGetError() == GL_NO_ERROR); 7.65 + 7.66 + if(info_len) { 7.67 + if((info_str = malloc(info_len + 1))) { 7.68 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 7.69 + assert(glGetError() == GL_NO_ERROR); 7.70 + } 7.71 + } 7.72 + 7.73 + if(success) { 7.74 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 7.75 + } else { 7.76 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 7.77 + glDeleteShader(sdr); 7.78 + sdr = 0; 7.79 + } 7.80 + 7.81 + free(info_str); 7.82 + return sdr; 7.83 +} 7.84 + 7.85 +void free_shader(unsigned int sdr) 7.86 +{ 7.87 + glDeleteShader(sdr); 7.88 +} 7.89 + 7.90 +unsigned int load_vertex_shader(const char *fname) 7.91 +{ 7.92 + return load_shader(fname, GL_VERTEX_SHADER); 7.93 +} 7.94 + 7.95 +unsigned int load_pixel_shader(const char *fname) 7.96 +{ 7.97 + return load_shader(fname, GL_FRAGMENT_SHADER); 7.98 +} 7.99 + 7.100 +unsigned int load_tessctl_shader(const char *fname) 7.101 +{ 7.102 + return load_shader(fname, GL_TESS_CONTROL_SHADER); 7.103 +} 7.104 + 7.105 +unsigned int load_tesseval_shader(const char *fname) 7.106 +{ 7.107 + return load_shader(fname, GL_TESS_EVALUATION_SHADER); 7.108 +} 7.109 + 7.110 +unsigned int load_geometry_shader(const char *fname) 7.111 +{ 7.112 + return load_shader(fname, GL_GEOMETRY_SHADER); 7.113 +} 7.114 + 7.115 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 7.116 +{ 7.117 +#if defined(unix) || defined(__unix__) 7.118 + struct stat st; 7.119 +#endif 7.120 + unsigned int sdr; 7.121 + size_t filesize; 7.122 + FILE *fp; 7.123 + char *src; 7.124 + 7.125 + if(!(fp = fopen(fname, "r"))) { 7.126 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 7.127 + return 0; 7.128 + } 7.129 + 7.130 +#if defined(unix) || defined(__unix__) 7.131 + fstat(fileno(fp), &st); 7.132 + filesize = st.st_size; 7.133 +#else 7.134 + fseek(fp, 0, SEEK_END); 7.135 + filesize = ftell(fp); 7.136 + fseek(fp, 0, SEEK_SET); 7.137 +#endif /* unix */ 7.138 + 7.139 + if(!(src = malloc(filesize + 1))) { 7.140 + fclose(fp); 7.141 + return 0; 7.142 + } 7.143 + fread(src, 1, filesize, fp); 7.144 + src[filesize] = 0; 7.145 + fclose(fp); 7.146 + 7.147 + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); 7.148 + sdr = create_shader(src, sdr_type); 7.149 + 7.150 + free(src); 7.151 + return sdr; 7.152 +} 7.153 + 7.154 + 7.155 +unsigned int get_vertex_shader(const char *fname) 7.156 +{ 7.157 + return get_shader(fname, GL_VERTEX_SHADER); 7.158 +} 7.159 + 7.160 +unsigned int get_pixel_shader(const char *fname) 7.161 +{ 7.162 + return get_shader(fname, GL_FRAGMENT_SHADER); 7.163 +} 7.164 + 7.165 +unsigned int get_tessctl_shader(const char *fname) 7.166 +{ 7.167 + return get_shader(fname, GL_TESS_CONTROL_SHADER); 7.168 +} 7.169 + 7.170 +unsigned int get_tesseval_shader(const char *fname) 7.171 +{ 7.172 + return get_shader(fname, GL_TESS_EVALUATION_SHADER); 7.173 +} 7.174 + 7.175 +unsigned int get_geometry_shader(const char *fname) 7.176 +{ 7.177 + return get_shader(fname, GL_GEOMETRY_SHADER); 7.178 +} 7.179 + 7.180 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 7.181 +{ 7.182 + unsigned int sdr; 7.183 + if(!(sdr = load_shader(fname, sdr_type))) { 7.184 + return 0; 7.185 + } 7.186 + return sdr; 7.187 +} 7.188 + 7.189 + 7.190 +/* ---- gpu programs ---- */ 7.191 + 7.192 +unsigned int create_program(void) 7.193 +{ 7.194 + unsigned int prog = glCreateProgram(); 7.195 + assert(glGetError() == GL_NO_ERROR); 7.196 + return prog; 7.197 +} 7.198 + 7.199 +unsigned int create_program_link(unsigned int sdr0, ...) 7.200 +{ 7.201 + unsigned int prog, sdr; 7.202 + va_list ap; 7.203 + 7.204 + if(!(prog = create_program())) { 7.205 + return 0; 7.206 + } 7.207 + 7.208 + attach_shader(prog, sdr0); 7.209 + if(glGetError()) { 7.210 + return 0; 7.211 + } 7.212 + 7.213 + va_start(ap, sdr0); 7.214 + while((sdr = va_arg(ap, unsigned int))) { 7.215 + attach_shader(prog, sdr); 7.216 + if(glGetError()) { 7.217 + return 0; 7.218 + } 7.219 + } 7.220 + va_end(ap); 7.221 + 7.222 + if(link_program(prog) == -1) { 7.223 + free_program(prog); 7.224 + return 0; 7.225 + } 7.226 + return prog; 7.227 +} 7.228 + 7.229 +unsigned int create_program_load(const char *vfile, const char *pfile) 7.230 +{ 7.231 + unsigned int vs = 0, ps = 0; 7.232 + 7.233 + if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) { 7.234 + return 0; 7.235 + } 7.236 + if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) { 7.237 + return 0; 7.238 + } 7.239 + return create_program_link(vs, ps, 0); 7.240 +} 7.241 + 7.242 +void free_program(unsigned int sdr) 7.243 +{ 7.244 + glDeleteProgram(sdr); 7.245 +} 7.246 + 7.247 +void attach_shader(unsigned int prog, unsigned int sdr) 7.248 +{ 7.249 + glAttachShader(prog, sdr); 7.250 + assert(glGetError() == GL_NO_ERROR); 7.251 +} 7.252 + 7.253 +int link_program(unsigned int prog) 7.254 +{ 7.255 + int linked, info_len, retval = 0; 7.256 + char *info_str = 0; 7.257 + 7.258 + glLinkProgram(prog); 7.259 + assert(glGetError() == GL_NO_ERROR); 7.260 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 7.261 + assert(glGetError() == GL_NO_ERROR); 7.262 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 7.263 + assert(glGetError() == GL_NO_ERROR); 7.264 + 7.265 + if(info_len) { 7.266 + if((info_str = malloc(info_len + 1))) { 7.267 + glGetProgramInfoLog(prog, info_len, 0, info_str); 7.268 + assert(glGetError() == GL_NO_ERROR); 7.269 + } 7.270 + } 7.271 + 7.272 + if(linked) { 7.273 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 7.274 + } else { 7.275 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 7.276 + retval = -1; 7.277 + } 7.278 + 7.279 + free(info_str); 7.280 + return retval; 7.281 +} 7.282 + 7.283 +int bind_program(unsigned int prog) 7.284 +{ 7.285 + GLenum err; 7.286 + 7.287 + glUseProgram(prog); 7.288 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 7.289 + /* maybe the program is not linked, try linking first */ 7.290 + if(err == GL_INVALID_OPERATION) { 7.291 + if(link_program(prog) == -1) { 7.292 + return -1; 7.293 + } 7.294 + glUseProgram(prog); 7.295 + return glGetError() == GL_NO_ERROR ? 0 : -1; 7.296 + } 7.297 + return -1; 7.298 + } 7.299 + return 0; 7.300 +} 7.301 + 7.302 +/* ugly but I'm not going to write the same bloody code over and over */ 7.303 +#define BEGIN_UNIFORM_CODE \ 7.304 + int loc, curr_prog; \ 7.305 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 7.306 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 7.307 + return -1; \ 7.308 + } \ 7.309 + if((loc = glGetUniformLocation(prog, name)) != -1) 7.310 + 7.311 +#define END_UNIFORM_CODE \ 7.312 + if((unsigned int)curr_prog != prog) { \ 7.313 + bind_program(curr_prog); \ 7.314 + } \ 7.315 + return loc == -1 ? -1 : 0 7.316 + 7.317 +int set_uniform_int(unsigned int prog, const char *name, int val) 7.318 +{ 7.319 + BEGIN_UNIFORM_CODE { 7.320 + glUniform1i(loc, val); 7.321 + } 7.322 + END_UNIFORM_CODE; 7.323 +} 7.324 + 7.325 +int set_uniform_float(unsigned int prog, const char *name, float val) 7.326 +{ 7.327 + BEGIN_UNIFORM_CODE { 7.328 + glUniform1f(loc, val); 7.329 + } 7.330 + END_UNIFORM_CODE; 7.331 +} 7.332 + 7.333 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) 7.334 +{ 7.335 + BEGIN_UNIFORM_CODE { 7.336 + glUniform2f(loc, x, y); 7.337 + } 7.338 + END_UNIFORM_CODE; 7.339 +} 7.340 + 7.341 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 7.342 +{ 7.343 + BEGIN_UNIFORM_CODE { 7.344 + glUniform3f(loc, x, y, z); 7.345 + } 7.346 + END_UNIFORM_CODE; 7.347 +} 7.348 + 7.349 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 7.350 +{ 7.351 + BEGIN_UNIFORM_CODE { 7.352 + glUniform4f(loc, x, y, z, w); 7.353 + } 7.354 + END_UNIFORM_CODE; 7.355 +} 7.356 + 7.357 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 7.358 +{ 7.359 + BEGIN_UNIFORM_CODE { 7.360 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 7.361 + } 7.362 + END_UNIFORM_CODE; 7.363 +} 7.364 + 7.365 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 7.366 +{ 7.367 + BEGIN_UNIFORM_CODE { 7.368 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 7.369 + } 7.370 + END_UNIFORM_CODE; 7.371 +} 7.372 + 7.373 +int get_attrib_loc(unsigned int prog, const char *name) 7.374 +{ 7.375 + int loc, curr_prog; 7.376 + 7.377 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 7.378 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 7.379 + return -1; 7.380 + } 7.381 + 7.382 + loc = glGetAttribLocation(prog, (char*)name); 7.383 + 7.384 + if((unsigned int)curr_prog != prog) { 7.385 + bind_program(curr_prog); 7.386 + } 7.387 + return loc; 7.388 +} 7.389 + 7.390 +void set_attrib_float3(int attr_loc, float x, float y, float z) 7.391 +{ 7.392 + glVertexAttrib3f(attr_loc, x, y, z); 7.393 +} 7.394 + 7.395 +static const char *sdrtypestr(unsigned int sdrtype) 7.396 +{ 7.397 + switch(sdrtype) { 7.398 + case GL_VERTEX_SHADER: 7.399 + return "vertex"; 7.400 + case GL_FRAGMENT_SHADER: 7.401 + return "pixel"; 7.402 + case GL_TESS_CONTROL_SHADER: 7.403 + return "tessellation control"; 7.404 + case GL_TESS_EVALUATION_SHADER: 7.405 + return "tessellation evaluation"; 7.406 + case GL_GEOMETRY_SHADER: 7.407 + return "geometry"; 7.408 + 7.409 + default: 7.410 + break; 7.411 + } 7.412 + return "<unknown>"; 7.413 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/sdr.h Sun Dec 02 08:23:51 2012 +0200 8.3 @@ -0,0 +1,59 @@ 8.4 +#ifndef SDR_H_ 8.5 +#define SDR_H_ 8.6 + 8.7 +#ifdef __cplusplus 8.8 +extern "C" { 8.9 +#endif /* __cplusplus */ 8.10 + 8.11 +/* ---- shaders ---- */ 8.12 +unsigned int create_vertex_shader(const char *src); 8.13 +unsigned int create_pixel_shader(const char *src); 8.14 +unsigned int create_tessctl_shader(const char *src); 8.15 +unsigned int create_tesseval_shader(const char *src); 8.16 +unsigned int create_geometry_shader(const char *src); 8.17 +unsigned int create_shader(const char *src, unsigned int sdr_type); 8.18 +void free_shader(unsigned int sdr); 8.19 + 8.20 +unsigned int load_vertex_shader(const char *fname); 8.21 +unsigned int load_pixel_shader(const char *fname); 8.22 +unsigned int load_tessctl_shader(const char *fname); 8.23 +unsigned int load_tesseval_shader(const char *fname); 8.24 +unsigned int load_geometry_shader(const char *fname); 8.25 +unsigned int load_shader(const char *src, unsigned int sdr_type); 8.26 + 8.27 +unsigned int get_vertex_shader(const char *fname); 8.28 +unsigned int get_pixel_shader(const char *fname); 8.29 +unsigned int get_tessctl_shader(const char *fname); 8.30 +unsigned int get_tesseval_shader(const char *fname); 8.31 +unsigned int get_geometry_shader(const char *fname); 8.32 +unsigned int get_shader(const char *fname, unsigned int sdr_type); 8.33 + 8.34 +int add_shader(const char *fname, unsigned int sdr); 8.35 +int remove_shader(const char *fname); 8.36 + 8.37 +/* ---- gpu programs ---- */ 8.38 +unsigned int create_program(void); 8.39 +unsigned int create_program_link(unsigned int sdr0, ...); 8.40 +unsigned int create_program_load(const char *vfile, const char *pfile); 8.41 +void free_program(unsigned int sdr); 8.42 + 8.43 +void attach_shader(unsigned int prog, unsigned int sdr); 8.44 +int link_program(unsigned int prog); 8.45 +int bind_program(unsigned int prog); 8.46 + 8.47 +int set_uniform_int(unsigned int prog, const char *name, int val); 8.48 +int set_uniform_float(unsigned int prog, const char *name, float val); 8.49 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); 8.50 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 8.51 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 8.52 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 8.53 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 8.54 + 8.55 +int get_attrib_loc(unsigned int prog, const char *name); 8.56 +void set_attrib_float3(int attr_loc, float x, float y, float z); 8.57 + 8.58 +#ifdef __cplusplus 8.59 +} 8.60 +#endif /* __cplusplus */ 8.61 + 8.62 +#endif /* SDR_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/teapot_data.h Sun Dec 02 08:23:51 2012 +0200 9.3 @@ -0,0 +1,214 @@ 9.4 +#ifndef TEAPOT_DATA_H_ 9.5 +#define TEAPOT_DATA_H_ 9.6 + 9.7 +#include "vmath.h" 9.8 + 9.9 +#define NUM_TEAPOT_INDICES (sizeof teapot_index / sizeof *teapot_index) 9.10 +#define NUM_TEAPOT_VERTS (sizeof teapot_verts / sizeof *teapot_verts) 9.11 + 9.12 +#define NUM_TEAPOT_PATCHES (NUM_TEAPOT_INDICES / 16) 9.13 + 9.14 +static float teapot_part_flip[] = { 9.15 + 1, 1, 1, 1, /* rim flip */ 9.16 + 1, 1, 1, 1, /* body1 flip */ 9.17 + 1, 1, 1, 1, /* body2 flip */ 9.18 + 1, 1, 1, 1, /* lid patch 1 flip */ 9.19 + 1, 1, 1, 1, /* lid patch 2 flip */ 9.20 + 1, -1, /* handle 1 flip */ 9.21 + 1, -1, /* handle 2 flip */ 9.22 + 1, -1, /* spout 1 flip */ 9.23 + 1, -1, /* spout 2 flip */ 9.24 + 1, 1, 1, 1 /* bottom flip */ 9.25 +}; 9.26 + 9.27 +static float teapot_part_rot[] = { 9.28 + 0, 90, 180, 270, /* rim rotations */ 9.29 + 0, 90, 180, 270, /* body patch 1 rotations */ 9.30 + 0, 90, 180, 270, /* body patch 2 rotations */ 9.31 + 0, 90, 180, 270, /* lid patch 1 rotations */ 9.32 + 0, 90, 180, 270, /* lid patch 2 rotations */ 9.33 + 0, 0, /* handle 1 rotations */ 9.34 + 0, 0, /* handle 2 rotations */ 9.35 + 0, 0, /* spout 1 rotations */ 9.36 + 0, 0, /* spout 2 rotations */ 9.37 + 0, 90, 180, 270 /* bottom rotations */ 9.38 +}; 9.39 + 9.40 + 9.41 +static int teapot_index[] = { 9.42 + /* rim */ 9.43 + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9.44 + 9, 10, 11, 12, 13, 14, 15, 9.45 + 9.46 + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9.47 + 9, 10, 11, 12, 13, 14, 15, 9.48 + 9.49 + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9.50 + 9, 10, 11, 12, 13, 14, 15, 9.51 + 9.52 + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9.53 + 9, 10, 11, 12, 13, 14, 15, 9.54 + 9.55 + /* body1 */ 9.56 + 12, 13, 14, 15, 16, 17, 18, 19, 9.57 + 20, 21, 22, 23, 24, 25, 26, 27, 9.58 + 9.59 + 12, 13, 14, 15, 16, 17, 18, 19, 9.60 + 20, 21, 22, 23, 24, 25, 26, 27, 9.61 + 9.62 + 12, 13, 14, 15, 16, 17, 18, 19, 9.63 + 20, 21, 22, 23, 24, 25, 26, 27, 9.64 + 9.65 + 12, 13, 14, 15, 16, 17, 18, 19, 9.66 + 20, 21, 22, 23, 24, 25, 26, 27, 9.67 + 9.68 + /* body 2 */ 9.69 + 24, 25, 26, 27, 29, 30, 31, 32, 9.70 + 33, 34, 35, 36, 37, 38, 39, 40, 9.71 + 9.72 + 24, 25, 26, 27, 29, 30, 31, 32, 9.73 + 33, 34, 35, 36, 37, 38, 39, 40, 9.74 + 9.75 + 24, 25, 26, 27, 29, 30, 31, 32, 9.76 + 33, 34, 35, 36, 37, 38, 39, 40, 9.77 + 9.78 + 24, 25, 26, 27, 29, 30, 31, 32, 9.79 + 33, 34, 35, 36, 37, 38, 39, 40, 9.80 + 9.81 + /* lid 1 */ 9.82 + 96, 96, 96, 96, 97, 98, 99, 100, 9.83 + 101, 101, 101, 101, 0, 1, 2, 3, 9.84 + 9.85 + 96, 96, 96, 96, 97, 98, 99, 100, 9.86 + 101, 101, 101, 101, 0, 1, 2, 3, 9.87 + 9.88 + 96, 96, 96, 96, 97, 98, 99, 100, 9.89 + 101, 101, 101, 101, 0, 1, 2, 3, 9.90 + 9.91 + 96, 96, 96, 96, 97, 98, 99, 100, 9.92 + 101, 101, 101, 101, 0, 1, 2, 3, 9.93 + 9.94 + /* lid 2 */ 9.95 + 0, 1, 2, 3, 106, 107, 108, 109, 9.96 + 110, 111, 112, 113, 114, 115, 116, 117, 9.97 + 9.98 + 0, 1, 2, 3, 106, 107, 108, 109, 9.99 + 110, 111, 112, 113, 114, 115, 116, 117, 9.100 + 9.101 + 0, 1, 2, 3, 106, 107, 108, 109, 9.102 + 110, 111, 112, 113, 114, 115, 116, 117, 9.103 + 9.104 + 0, 1, 2, 3, 106, 107, 108, 109, 9.105 + 110, 111, 112, 113, 114, 115, 116, 117, 9.106 + 9.107 + /* handle 1 */ 9.108 + 41, 42, 43, 44, 45, 46, 47, 48, 9.109 + 49, 50, 51, 52, 53, 54, 55, 56, 9.110 + 9.111 + 41, 42, 43, 44, 45, 46, 47, 48, 9.112 + 49, 50, 51, 52, 53, 54, 55, 56, 9.113 + 9.114 + /* handle 2 */ 9.115 + 53, 54, 55, 56, 57, 58, 59, 60, 9.116 + 61, 62, 63, 64, 28, 65, 66, 67, 9.117 + 9.118 + 53, 54, 55, 56, 57, 58, 59, 60, 9.119 + 61, 62, 63, 64, 28, 65, 66, 67, 9.120 + 9.121 + /* spout 1 */ 9.122 + 68, 69, 70, 71, 72, 73, 74, 75, 9.123 + 76, 77, 78, 79, 80, 81, 82, 83, 9.124 + 9.125 + 68, 69, 70, 71, 72, 73, 74, 75, 9.126 + 76, 77, 78, 79, 80, 81, 82, 83, 9.127 + 9.128 + /* spout 2 */ 9.129 + 80, 81, 82, 83, 84, 85, 86, 87, 9.130 + 88, 89, 90, 91, 92, 93, 94, 95, 9.131 + 9.132 + 80, 81, 82, 83, 84, 85, 86, 87, 9.133 + 88, 89, 90, 91, 92, 93, 94, 95, 9.134 + 9.135 + /* bottom */ 9.136 + 118, 118, 118, 118, 124, 122, 119, 121, 9.137 + 123, 126, 125, 120, 40, 39, 38, 37, 9.138 + 9.139 + 118, 118, 118, 118, 124, 122, 119, 121, 9.140 + 123, 126, 125, 120, 40, 39, 38, 37, 9.141 + 9.142 + 118, 118, 118, 118, 124, 122, 119, 121, 9.143 + 123, 126, 125, 120, 40, 39, 38, 37, 9.144 + 9.145 + 118, 118, 118, 118, 124, 122, 119, 121, 9.146 + 123, 126, 125, 120, 40, 39, 38, 37 9.147 +}; 9.148 + 9.149 + 9.150 +static struct vec3 teapot_verts[] = { 9.151 + { 0.2000, 0.0000, 2.70000 }, { 0.2000, -0.1120, 2.70000 }, 9.152 + { 0.1120, -0.2000, 2.70000 }, { 0.0000, -0.2000, 2.70000 }, 9.153 + { 1.3375, 0.0000, 2.53125 }, { 1.3375, -0.7490, 2.53125 }, 9.154 + { 0.7490, -1.3375, 2.53125 }, { 0.0000, -1.3375, 2.53125 }, 9.155 + { 1.4375, 0.0000, 2.53125 }, { 1.4375, -0.8050, 2.53125 }, 9.156 + { 0.8050, -1.4375, 2.53125 }, { 0.0000, -1.4375, 2.53125 }, 9.157 + { 1.5000, 0.0000, 2.40000 }, { 1.5000, -0.8400, 2.40000 }, 9.158 + { 0.8400, -1.5000, 2.40000 }, { 0.0000, -1.5000, 2.40000 }, 9.159 + { 1.7500, 0.0000, 1.87500 }, { 1.7500, -0.9800, 1.87500 }, 9.160 + { 0.9800, -1.7500, 1.87500 }, { 0.0000, -1.7500, 1.87500 }, 9.161 + { 2.0000, 0.0000, 1.35000 }, { 2.0000, -1.1200, 1.35000 }, 9.162 + { 1.1200, -2.0000, 1.35000 }, { 0.0000, -2.0000, 1.35000 }, 9.163 + { 2.0000, 0.0000, 0.90000 }, { 2.0000, -1.1200, 0.90000 }, 9.164 + { 1.1200, -2.0000, 0.90000 }, { 0.0000, -2.0000, 0.90000 }, 9.165 + { -2.0000, 0.0000, 0.90000 }, { 2.0000, 0.0000, 0.45000 }, 9.166 + { 2.0000, -1.1200, 0.45000 }, { 1.1200, -2.0000, 0.45000 }, 9.167 + { 0.0000, -2.0000, 0.45000 }, { 1.5000, 0.0000, 0.22500 }, 9.168 + { 1.5000, -0.8400, 0.22500 }, { 0.8400, -1.5000, 0.22500 }, 9.169 + { 0.0000, -1.5000, 0.22500 }, { 1.5000, 0.0000, 0.15000 }, 9.170 + { 1.5000, -0.8400, 0.15000 }, { 0.8400, -1.5000, 0.15000 }, 9.171 + { 0.0000, -1.5000, 0.15000 }, { -1.6000, 0.0000, 2.02500 }, 9.172 + { -1.6000, -0.3000, 2.02500 }, { -1.5000, -0.3000, 2.25000 }, 9.173 + { -1.5000, 0.0000, 2.25000 }, { -2.3000, 0.0000, 2.02500 }, 9.174 + { -2.3000, -0.3000, 2.02500 }, { -2.5000, -0.3000, 2.25000 }, 9.175 + { -2.5000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 2.02500 }, 9.176 + { -2.7000, -0.3000, 2.02500 }, { -3.0000, -0.3000, 2.25000 }, 9.177 + { -3.0000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 1.80000 }, 9.178 + { -2.7000, -0.3000, 1.80000 }, { -3.0000, -0.3000, 1.80000 }, 9.179 + { -3.0000, 0.0000, 1.80000 }, { -2.7000, 0.0000, 1.57500 }, 9.180 + { -2.7000, -0.3000, 1.57500 }, { -3.0000, -0.3000, 1.35000 }, 9.181 + { -3.0000, 0.0000, 1.35000 }, { -2.5000, 0.0000, 1.12500 }, 9.182 + { -2.5000, -0.3000, 1.12500 }, { -2.6500, -0.3000, 0.93750 }, 9.183 + { -2.6500, 0.0000, 0.93750 }, { -2.0000, -0.3000, 0.90000 }, 9.184 + { -1.9000, -0.3000, 0.60000 }, { -1.9000, 0.0000, 0.60000 }, 9.185 + { 1.7000, 0.0000, 1.42500 }, { 1.7000, -0.6600, 1.42500 }, 9.186 + { 1.7000, -0.6600, 0.60000 }, { 1.7000, 0.0000, 0.60000 }, 9.187 + { 2.6000, 0.0000, 1.42500 }, { 2.6000, -0.6600, 1.42500 }, 9.188 + { 3.1000, -0.6600, 0.82500 }, { 3.1000, 0.0000, 0.82500 }, 9.189 + { 2.3000, 0.0000, 2.10000 }, { 2.3000, -0.2500, 2.10000 }, 9.190 + { 2.4000, -0.2500, 2.02500 }, { 2.4000, 0.0000, 2.02500 }, 9.191 + { 2.7000, 0.0000, 2.40000 }, { 2.7000, -0.2500, 2.40000 }, 9.192 + { 3.3000, -0.2500, 2.40000 }, { 3.3000, 0.0000, 2.40000 }, 9.193 + { 2.8000, 0.0000, 2.47500 }, { 2.8000, -0.2500, 2.47500 }, 9.194 + { 3.5250, -0.2500, 2.49375 }, { 3.5250, 0.0000, 2.49375 }, 9.195 + { 2.9000, 0.0000, 2.47500 }, { 2.9000, -0.1500, 2.47500 }, 9.196 + { 3.4500, -0.1500, 2.51250 }, { 3.4500, 0.0000, 2.51250 }, 9.197 + { 2.8000, 0.0000, 2.40000 }, { 2.8000, -0.1500, 2.40000 }, 9.198 + { 3.2000, -0.1500, 2.40000 }, { 3.2000, 0.0000, 2.40000 }, 9.199 + { 0.0000, 0.0000, 3.15000 }, { 0.8000, 0.0000, 3.15000 }, 9.200 + { 0.8000, -0.4500, 3.15000 }, { 0.4500, -0.8000, 3.15000 }, 9.201 + { 0.0000, -0.8000, 3.15000 }, { 0.0000, 0.0000, 2.85000 }, 9.202 + { 1.4000, 0.0000, 2.40000 }, { 1.4000, -0.7840, 2.40000 }, 9.203 + { 0.7840, -1.4000, 2.40000 }, { 0.0000, -1.4000, 2.40000 }, 9.204 + { 0.4000, 0.0000, 2.55000 }, { 0.4000, -0.2240, 2.55000 }, 9.205 + { 0.2240, -0.4000, 2.55000 }, { 0.0000, -0.4000, 2.55000 }, 9.206 + { 1.3000, 0.0000, 2.55000 }, { 1.3000, -0.7280, 2.55000 }, 9.207 + { 0.7280, -1.3000, 2.55000 }, { 0.0000, -1.3000, 2.55000 }, 9.208 + { 1.3000, 0.0000, 2.40000 }, { 1.3000, -0.7280, 2.40000 }, 9.209 + { 0.7280, -1.3000, 2.40000 }, { 0.0000, -1.3000, 2.40000 }, 9.210 + { 0.0000, 0.0000, 0.00000 }, { 1.4250, -0.7980, 0.00000 }, 9.211 + { 1.5000, 0.0000, 0.07500 }, { 1.4250, 0.0000, 0.00000 }, 9.212 + { 0.7980, -1.4250, 0.00000 }, { 0.0000, -1.5000, 0.07500 }, 9.213 + { 0.0000, -1.4250, 0.00000 }, { 1.5000, -0.8400, 0.07500 }, 9.214 + { 0.8400, -1.5000, 0.07500 } 9.215 +}; 9.216 + 9.217 +#endif /* TEAPOT_DATA_H_ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/test.c Sun Dec 02 08:23:51 2012 +0200 10.3 @@ -0,0 +1,209 @@ 10.4 +#include <stdio.h> 10.5 +#include <stdlib.h> 10.6 +#include <GL/glew.h> 10.7 +#include <GL/glut.h> 10.8 +#include "sdr.h" 10.9 + 10.10 +void disp(void); 10.11 +void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin); 10.12 +void reshape(int x, int y); 10.13 +void keyb(unsigned char key, int x, int y); 10.14 +void mouse(int bn, int state, int x, int y); 10.15 +void motion(int x, int y); 10.16 + 10.17 +static float cam_theta, cam_phi = 25; 10.18 +static float cam_dist = 8.0; 10.19 + 10.20 +static unsigned int prog; 10.21 + 10.22 +int main(int argc, char **argv) 10.23 +{ 10.24 + int max_tess_level; 10.25 + 10.26 + glutInit(&argc, argv); 10.27 + glutInitWindowSize(1280, 800); 10.28 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 10.29 + glutCreateWindow("tesselation shaders test"); 10.30 + 10.31 + glutDisplayFunc(disp); 10.32 + glutReshapeFunc(reshape); 10.33 + glutKeyboardFunc(keyb); 10.34 + glutMouseFunc(mouse); 10.35 + glutMotionFunc(motion); 10.36 + 10.37 + glewInit(); 10.38 + 10.39 + glClearColor(0.07, 0.07, 0.07, 1); 10.40 + 10.41 + glEnable(GL_CULL_FACE); 10.42 + 10.43 + if(!GLEW_ARB_tessellation_shader) { 10.44 + fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n"); 10.45 + return 1; 10.46 + } 10.47 + glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &max_tess_level); 10.48 + printf("maximum tesselation levels: %d\n", max_tess_level); 10.49 + 10.50 + glPatchParameteri(GL_PATCH_VERTICES, 16); 10.51 + 10.52 + { 10.53 + unsigned int vsdr, tcsdr, tesdr, psdr; 10.54 + 10.55 + if(!(vsdr = load_vertex_shader("sdr/bezier.v.glsl"))) { 10.56 + return 1; 10.57 + } 10.58 + if(!(tcsdr = load_tessctl_shader("sdr/bezier.tc.glsl"))) { 10.59 + return 1; 10.60 + } 10.61 + if(!(tesdr = load_tesseval_shader("sdr/bezier.te.glsl"))) { 10.62 + return 1; 10.63 + } 10.64 + if(!(psdr = load_pixel_shader("sdr/bezier.p.glsl"))) { 10.65 + return 1; 10.66 + } 10.67 + 10.68 + if(!(prog = create_program_link(vsdr, tcsdr, tesdr, psdr, 0))) { 10.69 + return 1; 10.70 + } 10.71 + } 10.72 + set_uniform_int(prog, "tess_level", 1); 10.73 + 10.74 + glutMainLoop(); 10.75 + return 0; 10.76 +} 10.77 + 10.78 + 10.79 +void disp(void) 10.80 +{ 10.81 + float lpos[] = {-5, 10, 4, 1}; 10.82 + 10.83 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 10.84 + 10.85 + glMatrixMode(GL_MODELVIEW); 10.86 + glLoadIdentity(); 10.87 + glTranslatef(0, 0, -cam_dist); 10.88 + glRotatef(cam_phi, 1, 0, 0); 10.89 + glRotatef(cam_theta, 0, 1, 0); 10.90 + 10.91 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 10.92 + 10.93 + set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0); 10.94 + 10.95 + glUseProgram(prog); 10.96 + 10.97 + glBegin(GL_PATCHES); 10.98 + glVertex3f(-1, -0.8, 1); 10.99 + glVertex3f(-0.25, -1, 1); 10.100 + glVertex3f(0.25, -1, 1); 10.101 + glVertex3f(1, 0, 1); 10.102 + 10.103 + glVertex3f(-1, -0.4, 0.25); 10.104 + glVertex3f(-0.25, 0, 0.25); 10.105 + glVertex3f(0.25, 0, 0.25); 10.106 + glVertex3f(1, -0.4, 0.25); 10.107 + 10.108 + glVertex3f(-1, -0.4, -0.25); 10.109 + glVertex3f(-0.25, 0.6, -0.25); 10.110 + glVertex3f(0.25, 0.3, -0.25); 10.111 + glVertex3f(1, -0.4, -0.25); 10.112 + 10.113 + glVertex3f(-1, 0, -1); 10.114 + glVertex3f(-0.25, 0.2, -1); 10.115 + glVertex3f(0.25, 0.2, -1); 10.116 + glVertex3f(1, 0, -1); 10.117 + glEnd(); 10.118 + 10.119 + glUseProgram(0); 10.120 + 10.121 + glutSwapBuffers(); 10.122 +} 10.123 + 10.124 +void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin) 10.125 +{ 10.126 + float dcol[4], scol[4]; 10.127 + 10.128 + dcol[0] = dr; 10.129 + dcol[1] = dg; 10.130 + dcol[2] = db; 10.131 + dcol[3] = 1.0; 10.132 + 10.133 + scol[0] = sr; 10.134 + scol[1] = sg; 10.135 + scol[2] = sb; 10.136 + scol[3] = 1.0; 10.137 + 10.138 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dcol); 10.139 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol); 10.140 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin); 10.141 +} 10.142 + 10.143 +void reshape(int x, int y) 10.144 +{ 10.145 + glViewport(0, 0, x, y); 10.146 + glMatrixMode(GL_PROJECTION); 10.147 + glLoadIdentity(); 10.148 + gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); 10.149 +} 10.150 + 10.151 +void keyb(unsigned char key, int x, int y) 10.152 +{ 10.153 + switch(key) { 10.154 + case 27: 10.155 + exit(0); 10.156 + 10.157 + case 'w': 10.158 + { 10.159 + static int wire; 10.160 + wire = !wire; 10.161 + if(wire) { 10.162 + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 10.163 + } else { 10.164 + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 10.165 + } 10.166 + } 10.167 + glutPostRedisplay(); 10.168 + break; 10.169 + } 10.170 + 10.171 + if(key >= '1' && key <= '9') { 10.172 + int tess_level = key - '0'; 10.173 + set_uniform_int(prog, "tess_level", tess_level); 10.174 + 10.175 + glutPostRedisplay(); 10.176 + } 10.177 +} 10.178 + 10.179 +static int bnstate[16]; 10.180 +static int prev_x, prev_y; 10.181 + 10.182 +void mouse(int bn, int state, int x, int y) 10.183 +{ 10.184 + int idx = bn - GLUT_LEFT_BUTTON; 10.185 + 10.186 + if(idx < sizeof bnstate / sizeof *bnstate) { 10.187 + bnstate[idx] = state == GLUT_DOWN; 10.188 + } 10.189 + prev_x = x; 10.190 + prev_y = y; 10.191 +} 10.192 + 10.193 +void motion(int x, int y) 10.194 +{ 10.195 + int dx = x - prev_x; 10.196 + int dy = y - prev_y; 10.197 + prev_x = x; 10.198 + prev_y = y; 10.199 + 10.200 + if(bnstate[0]) { 10.201 + cam_theta += dx * 0.5; 10.202 + cam_phi += dy * 0.5; 10.203 + if(cam_phi < -90) cam_phi = -90; 10.204 + if(cam_phi > 90) cam_phi = 90; 10.205 + glutPostRedisplay(); 10.206 + } 10.207 + 10.208 + if(bnstate[2]) { 10.209 + cam_dist += dy * 0.1; 10.210 + glutPostRedisplay(); 10.211 + } 10.212 +}