# HG changeset patch # User John Tsiombikas # Date 1354429431 -7200 # Node ID 72b7f9f2eeadcb64272a4dabe615a7bd398c8d7b initial commit diff -r 000000000000 -r 72b7f9f2eead .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,4 @@ +\.o$ +\.d$ +\.swp$ +^test$ diff -r 000000000000 -r 72b7f9f2eead Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,19 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +bin = test + +CFLAGS = -pedantic -Wall -g +LDFLAGS = $(libgl) + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT -lglew +else + libgl = -lGL -lGLU -lglut -lGLEW +endif + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r 72b7f9f2eead sdr/bezier.p.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/bezier.p.glsl Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,26 @@ +#version 410 compatibility + +in vec3 normal; +in vec3 vpos; + +void main() +{ + vec3 ldir = gl_LightSource[0].position.xyz - vpos; + + vec3 n = normalize(normal); + vec3 v = -normalize(vpos); + vec3 l = normalize(ldir); + vec3 h = normalize(l + v); + + float ndotl = max(dot(n, l), 0.0); + float ndoth = max(dot(n, h), 0.0); + + vec3 kd = gl_FrontMaterial.diffuse.xyz; + vec3 ks = gl_FrontMaterial.specular.xyz; + float shin = gl_FrontMaterial.shininess; + + vec3 diffuse = kd * ndotl * gl_LightSource[0].diffuse.xyz; + vec3 specular = ks * pow(ndoth, shin) * gl_LightSource[0].specular.xyz; + + gl_FragColor = vec4(diffuse + specular, gl_FrontMaterial.diffuse.w); +} diff -r 000000000000 -r 72b7f9f2eead sdr/bezier.tc.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/bezier.tc.glsl Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,18 @@ +#version 410 compatibility + +layout(vertices = 16) out; + +uniform int tess_level; + +void main() +{ + gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; + + gl_TessLevelInner[0] = tess_level; + gl_TessLevelInner[1] = tess_level; + + gl_TessLevelOuter[0] = tess_level; + gl_TessLevelOuter[1] = tess_level; + gl_TessLevelOuter[2] = tess_level; + gl_TessLevelOuter[3] = tess_level; +} diff -r 000000000000 -r 72b7f9f2eead sdr/bezier.te.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/bezier.te.glsl Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,59 @@ +#version 410 compatibility + +layout(quads) in; + +out vec3 normal; +out vec3 vpos; + +vec3 bezier_patch(float u, float v); +vec3 bezier_patch_norm(float u, float v); +float bernstein(int i, float x); + +void main() +{ + vec3 pos = bezier_patch(gl_TessCoord.x, gl_TessCoord.y); + normal = gl_NormalMatrix * bezier_patch_norm(gl_TessCoord.x, gl_TessCoord.y); + + gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0); + vpos = (gl_ModelViewMatrix * vec4(pos, 1.0)).xyz; +} + +vec3 bezier_patch(float u, float v) +{ + int i, j; + vec3 res = vec3(0.0, 0.0, 0.0); + + for(j=0; j<4; j++) { + for(i=0; i<4; i++) { + float bu = bernstein(i, u); + float bv = bernstein(j, v); + + res += gl_in[j * 4 + i].gl_Position.xyz * bu * bv; + } + } + return res; +} + +#define DT 0.0001 +vec3 bezier_patch_norm(float u, float v) +{ + vec3 tang = bezier_patch(u + DT, v) - bezier_patch(u - DT, v); + vec3 bitan = bezier_patch(u, v + DT) - bezier_patch(u, v - DT); + return cross(tang, bitan); +} + +float bernstein(int i, float x) +{ + float invx = 1.0 - x; + + if(i == 0) { + return invx * invx * invx; + } + if(i == 1) { + return 3 * x * invx * invx; + } + if(i == 2) { + return 3 * x * x * invx; + } + return x * x * x; +} diff -r 000000000000 -r 72b7f9f2eead sdr/bezier.v.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/bezier.v.glsl Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,6 @@ +#version 410 compatibility + +void main() +{ + gl_Position = gl_Vertex; +} diff -r 000000000000 -r 72b7f9f2eead src/sdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.c Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,410 @@ +#include +#include +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) +#include +#include +#endif /* unix */ + +#include "sdr.h" + +static const char *sdrtypestr(unsigned int sdrtype); + +unsigned int create_vertex_shader(const char *src) +{ + return create_shader(src, GL_VERTEX_SHADER); +} + +unsigned int create_pixel_shader(const char *src) +{ + return create_shader(src, GL_FRAGMENT_SHADER); +} + +unsigned int create_tessctl_shader(const char *src) +{ + return create_shader(src, GL_TESS_CONTROL_SHADER); +} + +unsigned int create_tesseval_shader(const char *src) +{ + return create_shader(src, GL_TESS_EVALUATION_SHADER); +} + +unsigned int create_geometry_shader(const char *src) +{ + return create_shader(src, GL_GEOMETRY_SHADER); +} + +unsigned int create_shader(const char *src, unsigned int sdr_type) +{ + unsigned int sdr; + int success, info_len; + char *info_str = 0; + GLenum err; + + sdr = glCreateShader(sdr_type); + assert(glGetError() == GL_NO_ERROR); + glShaderSource(sdr, 1, &src, 0); + err = glGetError(); + assert(err == GL_NO_ERROR); + glCompileShader(sdr); + assert(glGetError() == GL_NO_ERROR); + + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); + assert(glGetError() == GL_NO_ERROR); + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetShaderInfoLog(sdr, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(success) { + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); + } else { + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); + glDeleteShader(sdr); + sdr = 0; + } + + free(info_str); + return sdr; +} + +void free_shader(unsigned int sdr) +{ + glDeleteShader(sdr); +} + +unsigned int load_vertex_shader(const char *fname) +{ + return load_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int load_pixel_shader(const char *fname) +{ + return load_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int load_tessctl_shader(const char *fname) +{ + return load_shader(fname, GL_TESS_CONTROL_SHADER); +} + +unsigned int load_tesseval_shader(const char *fname) +{ + return load_shader(fname, GL_TESS_EVALUATION_SHADER); +} + +unsigned int load_geometry_shader(const char *fname) +{ + return load_shader(fname, GL_GEOMETRY_SHADER); +} + +unsigned int load_shader(const char *fname, unsigned int sdr_type) +{ +#if defined(unix) || defined(__unix__) + struct stat st; +#endif + unsigned int sdr; + size_t filesize; + FILE *fp; + char *src; + + if(!(fp = fopen(fname, "r"))) { + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); + return 0; + } + +#if defined(unix) || defined(__unix__) + fstat(fileno(fp), &st); + filesize = st.st_size; +#else + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); +#endif /* unix */ + + if(!(src = malloc(filesize + 1))) { + fclose(fp); + return 0; + } + fread(src, 1, filesize, fp); + src[filesize] = 0; + fclose(fp); + + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); + sdr = create_shader(src, sdr_type); + + free(src); + return sdr; +} + + +unsigned int get_vertex_shader(const char *fname) +{ + return get_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int get_pixel_shader(const char *fname) +{ + return get_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int get_tessctl_shader(const char *fname) +{ + return get_shader(fname, GL_TESS_CONTROL_SHADER); +} + +unsigned int get_tesseval_shader(const char *fname) +{ + return get_shader(fname, GL_TESS_EVALUATION_SHADER); +} + +unsigned int get_geometry_shader(const char *fname) +{ + return get_shader(fname, GL_GEOMETRY_SHADER); +} + +unsigned int get_shader(const char *fname, unsigned int sdr_type) +{ + unsigned int sdr; + if(!(sdr = load_shader(fname, sdr_type))) { + return 0; + } + return sdr; +} + + +/* ---- gpu programs ---- */ + +unsigned int create_program(void) +{ + unsigned int prog = glCreateProgram(); + assert(glGetError() == GL_NO_ERROR); + return prog; +} + +unsigned int create_program_link(unsigned int sdr0, ...) +{ + unsigned int prog, sdr; + va_list ap; + + if(!(prog = create_program())) { + return 0; + } + + attach_shader(prog, sdr0); + if(glGetError()) { + return 0; + } + + va_start(ap, sdr0); + while((sdr = va_arg(ap, unsigned int))) { + attach_shader(prog, sdr); + if(glGetError()) { + return 0; + } + } + va_end(ap); + + if(link_program(prog) == -1) { + free_program(prog); + return 0; + } + return prog; +} + +unsigned int create_program_load(const char *vfile, const char *pfile) +{ + unsigned int vs = 0, ps = 0; + + if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) { + return 0; + } + if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) { + return 0; + } + return create_program_link(vs, ps, 0); +} + +void free_program(unsigned int sdr) +{ + glDeleteProgram(sdr); +} + +void attach_shader(unsigned int prog, unsigned int sdr) +{ + glAttachShader(prog, sdr); + assert(glGetError() == GL_NO_ERROR); +} + +int link_program(unsigned int prog) +{ + int linked, info_len, retval = 0; + char *info_str = 0; + + glLinkProgram(prog); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_LINK_STATUS, &linked); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetProgramInfoLog(prog, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(linked) { + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); + } else { + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); + retval = -1; + } + + free(info_str); + return retval; +} + +int bind_program(unsigned int prog) +{ + GLenum err; + + glUseProgram(prog); + if(prog && (err = glGetError()) != GL_NO_ERROR) { + /* maybe the program is not linked, try linking first */ + if(err == GL_INVALID_OPERATION) { + if(link_program(prog) == -1) { + return -1; + } + glUseProgram(prog); + return glGetError() == GL_NO_ERROR ? 0 : -1; + } + return -1; + } + return 0; +} + +/* ugly but I'm not going to write the same bloody code over and over */ +#define BEGIN_UNIFORM_CODE \ + int loc, curr_prog; \ + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ + return -1; \ + } \ + if((loc = glGetUniformLocation(prog, name)) != -1) + +#define END_UNIFORM_CODE \ + if((unsigned int)curr_prog != prog) { \ + bind_program(curr_prog); \ + } \ + return loc == -1 ? -1 : 0 + +int set_uniform_int(unsigned int prog, const char *name, int val) +{ + BEGIN_UNIFORM_CODE { + glUniform1i(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float(unsigned int prog, const char *name, float val) +{ + BEGIN_UNIFORM_CODE { + glUniform1f(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) +{ + BEGIN_UNIFORM_CODE { + glUniform2f(loc, x, y); + } + END_UNIFORM_CODE; +} + +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) +{ + BEGIN_UNIFORM_CODE { + glUniform3f(loc, x, y, z); + } + END_UNIFORM_CODE; +} + +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) +{ + BEGIN_UNIFORM_CODE { + glUniform4f(loc, x, y, z, w); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); + } + END_UNIFORM_CODE; +} + +int get_attrib_loc(unsigned int prog, const char *name) +{ + int loc, curr_prog; + + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { + return -1; + } + + loc = glGetAttribLocation(prog, (char*)name); + + if((unsigned int)curr_prog != prog) { + bind_program(curr_prog); + } + return loc; +} + +void set_attrib_float3(int attr_loc, float x, float y, float z) +{ + glVertexAttrib3f(attr_loc, x, y, z); +} + +static const char *sdrtypestr(unsigned int sdrtype) +{ + switch(sdrtype) { + case GL_VERTEX_SHADER: + return "vertex"; + case GL_FRAGMENT_SHADER: + return "pixel"; + case GL_TESS_CONTROL_SHADER: + return "tessellation control"; + case GL_TESS_EVALUATION_SHADER: + return "tessellation evaluation"; + case GL_GEOMETRY_SHADER: + return "geometry"; + + default: + break; + } + return ""; +} diff -r 000000000000 -r 72b7f9f2eead src/sdr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.h Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,59 @@ +#ifndef SDR_H_ +#define SDR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* ---- shaders ---- */ +unsigned int create_vertex_shader(const char *src); +unsigned int create_pixel_shader(const char *src); +unsigned int create_tessctl_shader(const char *src); +unsigned int create_tesseval_shader(const char *src); +unsigned int create_geometry_shader(const char *src); +unsigned int create_shader(const char *src, unsigned int sdr_type); +void free_shader(unsigned int sdr); + +unsigned int load_vertex_shader(const char *fname); +unsigned int load_pixel_shader(const char *fname); +unsigned int load_tessctl_shader(const char *fname); +unsigned int load_tesseval_shader(const char *fname); +unsigned int load_geometry_shader(const char *fname); +unsigned int load_shader(const char *src, unsigned int sdr_type); + +unsigned int get_vertex_shader(const char *fname); +unsigned int get_pixel_shader(const char *fname); +unsigned int get_tessctl_shader(const char *fname); +unsigned int get_tesseval_shader(const char *fname); +unsigned int get_geometry_shader(const char *fname); +unsigned int get_shader(const char *fname, unsigned int sdr_type); + +int add_shader(const char *fname, unsigned int sdr); +int remove_shader(const char *fname); + +/* ---- gpu programs ---- */ +unsigned int create_program(void); +unsigned int create_program_link(unsigned int sdr0, ...); +unsigned int create_program_load(const char *vfile, const char *pfile); +void free_program(unsigned int sdr); + +void attach_shader(unsigned int prog, unsigned int sdr); +int link_program(unsigned int prog); +int bind_program(unsigned int prog); + +int set_uniform_int(unsigned int prog, const char *name, int val); +int set_uniform_float(unsigned int prog, const char *name, float val); +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); + +int get_attrib_loc(unsigned int prog, const char *name); +void set_attrib_float3(int attr_loc, float x, float y, float z); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SDR_H_ */ diff -r 000000000000 -r 72b7f9f2eead src/teapot_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/teapot_data.h Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,214 @@ +#ifndef TEAPOT_DATA_H_ +#define TEAPOT_DATA_H_ + +#include "vmath.h" + +#define NUM_TEAPOT_INDICES (sizeof teapot_index / sizeof *teapot_index) +#define NUM_TEAPOT_VERTS (sizeof teapot_verts / sizeof *teapot_verts) + +#define NUM_TEAPOT_PATCHES (NUM_TEAPOT_INDICES / 16) + +static float teapot_part_flip[] = { + 1, 1, 1, 1, /* rim flip */ + 1, 1, 1, 1, /* body1 flip */ + 1, 1, 1, 1, /* body2 flip */ + 1, 1, 1, 1, /* lid patch 1 flip */ + 1, 1, 1, 1, /* lid patch 2 flip */ + 1, -1, /* handle 1 flip */ + 1, -1, /* handle 2 flip */ + 1, -1, /* spout 1 flip */ + 1, -1, /* spout 2 flip */ + 1, 1, 1, 1 /* bottom flip */ +}; + +static float teapot_part_rot[] = { + 0, 90, 180, 270, /* rim rotations */ + 0, 90, 180, 270, /* body patch 1 rotations */ + 0, 90, 180, 270, /* body patch 2 rotations */ + 0, 90, 180, 270, /* lid patch 1 rotations */ + 0, 90, 180, 270, /* lid patch 2 rotations */ + 0, 0, /* handle 1 rotations */ + 0, 0, /* handle 2 rotations */ + 0, 0, /* spout 1 rotations */ + 0, 0, /* spout 2 rotations */ + 0, 90, 180, 270 /* bottom rotations */ +}; + + +static int teapot_index[] = { + /* rim */ + 102, 103, 104, 105, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, + + 102, 103, 104, 105, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, + + 102, 103, 104, 105, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, + + 102, 103, 104, 105, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, + + /* body1 */ + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, + + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, + + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, + + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, + + /* body 2 */ + 24, 25, 26, 27, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + + 24, 25, 26, 27, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + + 24, 25, 26, 27, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + + 24, 25, 26, 27, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + + /* lid 1 */ + 96, 96, 96, 96, 97, 98, 99, 100, + 101, 101, 101, 101, 0, 1, 2, 3, + + 96, 96, 96, 96, 97, 98, 99, 100, + 101, 101, 101, 101, 0, 1, 2, 3, + + 96, 96, 96, 96, 97, 98, 99, 100, + 101, 101, 101, 101, 0, 1, 2, 3, + + 96, 96, 96, 96, 97, 98, 99, 100, + 101, 101, 101, 101, 0, 1, 2, 3, + + /* lid 2 */ + 0, 1, 2, 3, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, + + 0, 1, 2, 3, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, + + 0, 1, 2, 3, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, + + 0, 1, 2, 3, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, + + /* handle 1 */ + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + + /* handle 2 */ + 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 28, 65, 66, 67, + + 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 28, 65, 66, 67, + + /* spout 1 */ + 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, + + 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, + + /* spout 2 */ + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + + /* bottom */ + 118, 118, 118, 118, 124, 122, 119, 121, + 123, 126, 125, 120, 40, 39, 38, 37, + + 118, 118, 118, 118, 124, 122, 119, 121, + 123, 126, 125, 120, 40, 39, 38, 37, + + 118, 118, 118, 118, 124, 122, 119, 121, + 123, 126, 125, 120, 40, 39, 38, 37, + + 118, 118, 118, 118, 124, 122, 119, 121, + 123, 126, 125, 120, 40, 39, 38, 37 +}; + + +static struct vec3 teapot_verts[] = { + { 0.2000, 0.0000, 2.70000 }, { 0.2000, -0.1120, 2.70000 }, + { 0.1120, -0.2000, 2.70000 }, { 0.0000, -0.2000, 2.70000 }, + { 1.3375, 0.0000, 2.53125 }, { 1.3375, -0.7490, 2.53125 }, + { 0.7490, -1.3375, 2.53125 }, { 0.0000, -1.3375, 2.53125 }, + { 1.4375, 0.0000, 2.53125 }, { 1.4375, -0.8050, 2.53125 }, + { 0.8050, -1.4375, 2.53125 }, { 0.0000, -1.4375, 2.53125 }, + { 1.5000, 0.0000, 2.40000 }, { 1.5000, -0.8400, 2.40000 }, + { 0.8400, -1.5000, 2.40000 }, { 0.0000, -1.5000, 2.40000 }, + { 1.7500, 0.0000, 1.87500 }, { 1.7500, -0.9800, 1.87500 }, + { 0.9800, -1.7500, 1.87500 }, { 0.0000, -1.7500, 1.87500 }, + { 2.0000, 0.0000, 1.35000 }, { 2.0000, -1.1200, 1.35000 }, + { 1.1200, -2.0000, 1.35000 }, { 0.0000, -2.0000, 1.35000 }, + { 2.0000, 0.0000, 0.90000 }, { 2.0000, -1.1200, 0.90000 }, + { 1.1200, -2.0000, 0.90000 }, { 0.0000, -2.0000, 0.90000 }, + { -2.0000, 0.0000, 0.90000 }, { 2.0000, 0.0000, 0.45000 }, + { 2.0000, -1.1200, 0.45000 }, { 1.1200, -2.0000, 0.45000 }, + { 0.0000, -2.0000, 0.45000 }, { 1.5000, 0.0000, 0.22500 }, + { 1.5000, -0.8400, 0.22500 }, { 0.8400, -1.5000, 0.22500 }, + { 0.0000, -1.5000, 0.22500 }, { 1.5000, 0.0000, 0.15000 }, + { 1.5000, -0.8400, 0.15000 }, { 0.8400, -1.5000, 0.15000 }, + { 0.0000, -1.5000, 0.15000 }, { -1.6000, 0.0000, 2.02500 }, + { -1.6000, -0.3000, 2.02500 }, { -1.5000, -0.3000, 2.25000 }, + { -1.5000, 0.0000, 2.25000 }, { -2.3000, 0.0000, 2.02500 }, + { -2.3000, -0.3000, 2.02500 }, { -2.5000, -0.3000, 2.25000 }, + { -2.5000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 2.02500 }, + { -2.7000, -0.3000, 2.02500 }, { -3.0000, -0.3000, 2.25000 }, + { -3.0000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 1.80000 }, + { -2.7000, -0.3000, 1.80000 }, { -3.0000, -0.3000, 1.80000 }, + { -3.0000, 0.0000, 1.80000 }, { -2.7000, 0.0000, 1.57500 }, + { -2.7000, -0.3000, 1.57500 }, { -3.0000, -0.3000, 1.35000 }, + { -3.0000, 0.0000, 1.35000 }, { -2.5000, 0.0000, 1.12500 }, + { -2.5000, -0.3000, 1.12500 }, { -2.6500, -0.3000, 0.93750 }, + { -2.6500, 0.0000, 0.93750 }, { -2.0000, -0.3000, 0.90000 }, + { -1.9000, -0.3000, 0.60000 }, { -1.9000, 0.0000, 0.60000 }, + { 1.7000, 0.0000, 1.42500 }, { 1.7000, -0.6600, 1.42500 }, + { 1.7000, -0.6600, 0.60000 }, { 1.7000, 0.0000, 0.60000 }, + { 2.6000, 0.0000, 1.42500 }, { 2.6000, -0.6600, 1.42500 }, + { 3.1000, -0.6600, 0.82500 }, { 3.1000, 0.0000, 0.82500 }, + { 2.3000, 0.0000, 2.10000 }, { 2.3000, -0.2500, 2.10000 }, + { 2.4000, -0.2500, 2.02500 }, { 2.4000, 0.0000, 2.02500 }, + { 2.7000, 0.0000, 2.40000 }, { 2.7000, -0.2500, 2.40000 }, + { 3.3000, -0.2500, 2.40000 }, { 3.3000, 0.0000, 2.40000 }, + { 2.8000, 0.0000, 2.47500 }, { 2.8000, -0.2500, 2.47500 }, + { 3.5250, -0.2500, 2.49375 }, { 3.5250, 0.0000, 2.49375 }, + { 2.9000, 0.0000, 2.47500 }, { 2.9000, -0.1500, 2.47500 }, + { 3.4500, -0.1500, 2.51250 }, { 3.4500, 0.0000, 2.51250 }, + { 2.8000, 0.0000, 2.40000 }, { 2.8000, -0.1500, 2.40000 }, + { 3.2000, -0.1500, 2.40000 }, { 3.2000, 0.0000, 2.40000 }, + { 0.0000, 0.0000, 3.15000 }, { 0.8000, 0.0000, 3.15000 }, + { 0.8000, -0.4500, 3.15000 }, { 0.4500, -0.8000, 3.15000 }, + { 0.0000, -0.8000, 3.15000 }, { 0.0000, 0.0000, 2.85000 }, + { 1.4000, 0.0000, 2.40000 }, { 1.4000, -0.7840, 2.40000 }, + { 0.7840, -1.4000, 2.40000 }, { 0.0000, -1.4000, 2.40000 }, + { 0.4000, 0.0000, 2.55000 }, { 0.4000, -0.2240, 2.55000 }, + { 0.2240, -0.4000, 2.55000 }, { 0.0000, -0.4000, 2.55000 }, + { 1.3000, 0.0000, 2.55000 }, { 1.3000, -0.7280, 2.55000 }, + { 0.7280, -1.3000, 2.55000 }, { 0.0000, -1.3000, 2.55000 }, + { 1.3000, 0.0000, 2.40000 }, { 1.3000, -0.7280, 2.40000 }, + { 0.7280, -1.3000, 2.40000 }, { 0.0000, -1.3000, 2.40000 }, + { 0.0000, 0.0000, 0.00000 }, { 1.4250, -0.7980, 0.00000 }, + { 1.5000, 0.0000, 0.07500 }, { 1.4250, 0.0000, 0.00000 }, + { 0.7980, -1.4250, 0.00000 }, { 0.0000, -1.5000, 0.07500 }, + { 0.0000, -1.4250, 0.00000 }, { 1.5000, -0.8400, 0.07500 }, + { 0.8400, -1.5000, 0.07500 } +}; + +#endif /* TEAPOT_DATA_H_ */ diff -r 000000000000 -r 72b7f9f2eead src/test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test.c Sun Dec 02 08:23:51 2012 +0200 @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include "sdr.h" + +void disp(void); +void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); + +static float cam_theta, cam_phi = 25; +static float cam_dist = 8.0; + +static unsigned int prog; + +int main(int argc, char **argv) +{ + int max_tess_level; + + glutInit(&argc, argv); + glutInitWindowSize(1280, 800); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("tesselation shaders test"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glewInit(); + + glClearColor(0.07, 0.07, 0.07, 1); + + glEnable(GL_CULL_FACE); + + if(!GLEW_ARB_tessellation_shader) { + fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n"); + return 1; + } + glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &max_tess_level); + printf("maximum tesselation levels: %d\n", max_tess_level); + + glPatchParameteri(GL_PATCH_VERTICES, 16); + + { + unsigned int vsdr, tcsdr, tesdr, psdr; + + if(!(vsdr = load_vertex_shader("sdr/bezier.v.glsl"))) { + return 1; + } + if(!(tcsdr = load_tessctl_shader("sdr/bezier.tc.glsl"))) { + return 1; + } + if(!(tesdr = load_tesseval_shader("sdr/bezier.te.glsl"))) { + return 1; + } + if(!(psdr = load_pixel_shader("sdr/bezier.p.glsl"))) { + return 1; + } + + if(!(prog = create_program_link(vsdr, tcsdr, tesdr, psdr, 0))) { + return 1; + } + } + set_uniform_int(prog, "tess_level", 1); + + glutMainLoop(); + return 0; +} + + +void disp(void) +{ + float lpos[] = {-5, 10, 4, 1}; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + + glLightfv(GL_LIGHT0, GL_POSITION, lpos); + + set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0); + + glUseProgram(prog); + + glBegin(GL_PATCHES); + glVertex3f(-1, -0.8, 1); + glVertex3f(-0.25, -1, 1); + glVertex3f(0.25, -1, 1); + glVertex3f(1, 0, 1); + + glVertex3f(-1, -0.4, 0.25); + glVertex3f(-0.25, 0, 0.25); + glVertex3f(0.25, 0, 0.25); + glVertex3f(1, -0.4, 0.25); + + glVertex3f(-1, -0.4, -0.25); + glVertex3f(-0.25, 0.6, -0.25); + glVertex3f(0.25, 0.3, -0.25); + glVertex3f(1, -0.4, -0.25); + + glVertex3f(-1, 0, -1); + glVertex3f(-0.25, 0.2, -1); + glVertex3f(0.25, 0.2, -1); + glVertex3f(1, 0, -1); + glEnd(); + + glUseProgram(0); + + glutSwapBuffers(); +} + +void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin) +{ + float dcol[4], scol[4]; + + dcol[0] = dr; + dcol[1] = dg; + dcol[2] = db; + dcol[3] = 1.0; + + scol[0] = sr; + scol[1] = sg; + scol[2] = sb; + scol[3] = 1.0; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dcol); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin); +} + +void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); +} + +void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + + case 'w': + { + static int wire; + wire = !wire; + if(wire) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } + glutPostRedisplay(); + break; + } + + if(key >= '1' && key <= '9') { + int tess_level = key - '0'; + set_uniform_int(prog, "tess_level", tess_level); + + glutPostRedisplay(); + } +} + +static int bnstate[16]; +static int prev_x, prev_y; + +void mouse(int bn, int state, int x, int y) +{ + int idx = bn - GLUT_LEFT_BUTTON; + + if(idx < sizeof bnstate / sizeof *bnstate) { + bnstate[idx] = state == GLUT_DOWN; + } + prev_x = x; + prev_y = y; +} + +void motion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; + glutPostRedisplay(); + } + + if(bnstate[2]) { + cam_dist += dy * 0.1; + glutPostRedisplay(); + } +}