diff options
author | Eric Anholt <eric@anholt.net> | 2009-07-21 21:42:11 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-07-28 10:43:10 -0700 |
commit | 57ee2c3ababab71911e5669932a33fb981c1bf42 (patch) | |
tree | 96ce49691aa4542bff2ce98ba30f681498ada1a0 | |
parent | 64575ce8f515b6c2f997ebe509f858cb4d384c50 (diff) |
Use glu3 for handling our matrices instead of using ff.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | glass.c | 107 | ||||
-rw-r--r-- | glass.h | 5 | ||||
-rw-r--r-- | glass.vert | 9 | ||||
-rw-r--r-- | matrix.c | 70 |
5 files changed, 142 insertions, 51 deletions
diff --git a/configure.ac b/configure.ac index 56f84ed..6067a43 100644 --- a/configure.ac +++ b/configure.ac @@ -50,7 +50,7 @@ if test "x$GCC" = "xyes"; then fi AC_SUBST([WARN_CFLAGS]) -PKG_CHECK_MODULES(GL, [gl sdl]) +PKG_CHECK_MODULES(GL, [gl glu3 sdl]) GL_LIBS="$GL_LIBS -lGLEW" dnl libpng check, taken from cairo. Yuck. @@ -39,6 +39,8 @@ #include "glass.h" +#include <glu3.h> + #include <SDL.h> #define DEFAULT_WIDTH 600 @@ -56,6 +58,8 @@ struct revolved_object { }; enum uniform_list { + UNIFORM_MV, + UNIFORM_MVP, UNIFORM_LIGHT_EYE, UNIFORM_NORMAL_SAMPLER, UNIFORM_HEIGHTMAP_SAMPLER, @@ -67,6 +71,8 @@ struct uniform_desc { const char *name; GLint location; } uniforms[] = { + [UNIFORM_MV] = { "mv" }, + [UNIFORM_MVP] = { "mvp" }, [UNIFORM_LIGHT_EYE] = { "light_eye" }, [UNIFORM_NORMAL_SAMPLER] = { "normal_sampler" }, [UNIFORM_HEIGHTMAP_SAMPLER] = { "heightmap_sampler" }, @@ -77,9 +83,16 @@ struct uniform_desc { struct revolved_object ring; GLuint normalmap_tex, heightmap_tex; -static const float light_start_world[4] = { 10.0, 0.0, -2.0, 1.0}; -static float eye_world[4] = {0.0, 0.0, 5.0}; -float light_eye[4]; +static const GLUvec4 light_start_world = {{0.0, 5.0, 10.0, 1.0}}; +static const GLUvec4 x_axis = {{1.0, 0.0, 0.0, 1.0}}; +static const GLUvec4 y_axis = {{0.0, 1.0, 0.0, 1.0}}; +static const GLUvec4 z_axis = {{0.0, 0.0, 1.0, 1.0}}; + +static GLUvec4 eye_world = {{0.0, 0.0, 2.0, 1.0}}; +static GLUvec4 eye_center_world = {{0.0, 1.0, 2.0, 1.0}}; +static GLUvec4 light_eye; +static GLUmat4 projection; +static GLUmat4 world_to_eye; static time_t start_tv_sec = 0; static float start_time, cur_time, last_fps_time = 0; @@ -119,7 +132,7 @@ update_brdf_constants(void) static void update_light_position(void) { - float rotation_matrix[16]; + GLUmat4 light_eye_matrix, temp; float light_rotation_rads; /* Set the light position: Rotate around the Y axis from its original @@ -127,21 +140,19 @@ update_light_position(void) */ light_rotation_rads = cur_time * 2 * M_PI / 4; - init_m4_y_rotate(rotation_matrix, light_rotation_rads); - - mult_m4_p4(light_eye, rotation_matrix, light_start_world); - - light_eye[0] /= light_eye[3]; - light_eye[1] /= light_eye[3]; - light_eye[2] /= light_eye[3]; - light_eye[3] = 1.0; + light_eye_matrix = gluRotate4v(&z_axis, light_rotation_rads); + temp = gluTranslate3(-eye_world.values[0], + -eye_world.values[1], + -eye_world.values[2]); + gluMult4m_4m(&temp, &light_eye_matrix); + light_eye = gluMult4m_4v(&light_eye_matrix, &light_start_world); - /* Transform from world space to eye space */ - light_eye[0] -= eye_world[0]; - light_eye[1] -= eye_world[1]; - light_eye[2] -= eye_world[2]; + light_eye.values[0] /= light_eye.values[3]; + light_eye.values[1] /= light_eye.values[3]; + light_eye.values[2] /= light_eye.values[3]; + light_eye.values[3] = 1.0; - glUniform3fv(uniforms[UNIFORM_LIGHT_EYE].location, 1, light_eye); + glUniform3fv(uniforms[UNIFORM_LIGHT_EYE].location, 1, light_eye.values); } static void @@ -179,40 +190,45 @@ install_transform(int instance) int x_index = (instance / 3) / 3 - 1; int y_index = (instance / 3) % 3 - 1; int z_index = instance % 3; + GLUmat4 mv, mvp, obj_to_world, temp; - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + /* Have the ring spinning on its axis slowly. */ + obj_to_world = gluRotate4v(&z_axis, cur_time * 2 * M_PI / 20); - /* world-to-eye transformation: */ - /* Translate for eye location. */ - glTranslatef(-eye_world[0], -eye_world[1], -eye_world[2]); + /* Make them wobble a little over time. */ + temp = gluRotate4v(&x_axis, M_PI / 8 * sin(cur_time * 2 * M_PI / 3)); + obj_to_world = gluMult4m_4m(&temp, &obj_to_world); - /* Move some of them left/right. */ - glTranslatef(x_index * 8.0, y_index * 6.0, z_index * -6.0); + temp = gluRotate4v(&y_axis, M_PI / 16 * sin(cur_time * 2 * M_PI / 5)); + obj_to_world = gluMult4m_4m(&temp, &obj_to_world); + /* Have the vertical rows start with different alignments. */ switch (z_index) { case 0: break; case 1: - /* Turn it a little on the X axis. */ - glRotatef(45, 1, 0, 0); + temp = gluRotate4v(&x_axis, M_PI / 4); + obj_to_world = gluMult4m_4m(&temp, &obj_to_world); break; case 2: - /* Turn it a little the other way on the X axis. */ - glRotatef(-45, 1, 0, 0); + temp = gluRotate4v(&x_axis, -M_PI / 4); + obj_to_world = gluMult4m_4m(&temp, &obj_to_world); break; } - - /* model-to-world transformation: model is at 0,0,0 */ - /* Rotate the object on the x/z axis a bit over time.*/ - glRotatef(20 * sin(cur_time * 2 * M_PI / 3), - 1, 0, 0); - glRotatef(10 * sin(cur_time * 2 * M_PI / 5), - 0, 0, 1); - - /* Finally, have the ring spinning on its axis slowly. */ - glRotatef(360 * cur_time / 20, - 0, 1, 0); + /* Move them out into their position in the cube. */ + temp = gluTranslate3(x_index * 5.0, + 10 + y_index * 5.0, + 7.0 + z_index * 5.0); + obj_to_world = gluMult4m_4m(&temp, &obj_to_world); + + /* Generate the whole mvp */ + mv = gluMult4m_4m(&world_to_eye, &obj_to_world); + mvp = gluMult4m_4m(&projection, &mv); + + glUniformMatrix4fv(uniforms[UNIFORM_MV].location, 1, 0, + (float *)&mv); + glUniformMatrix4fv(uniforms[UNIFORM_MVP].location, 1, 0, + (float *)&mvp); } static void @@ -432,9 +448,9 @@ reshape(int width, int height) if (sdl_surf == NULL) errx(1, "video mode set fail\n"); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(80, win_width / (float)win_height, 0.2, 40); + projection = gluPerspective4(80, + (float)win_width / (float)win_height, + 0.2, 40); } static GLint @@ -677,13 +693,18 @@ init(void) if (!GLEW_ARB_vertex_array_object) errx(1, "Requires ARB_vertex_array_object\n"); + /* Have the eye out in the world, sitting above the ground on the + * Z axis, looking down y. + */ + world_to_eye = gluLookAt4v(&eye_world, &eye_center_world, &z_axis); + generate_rounded_rect_verts(0.2, 1.0, .02, 0.9, corner_steps, &verts, &num_verts); memset(translation_matrix, 0, sizeof(translation_matrix)); translation_matrix[0 * 4 + 0] = 1.0; translation_matrix[1 * 4 + 1] = 1.0; - translation_matrix[3 * 4 + 0] = 3.0; + translation_matrix[3 * 4 + 0] = 1.9; translation_matrix[3 * 4 + 1] = -0.5; translation_matrix[2 * 4 + 2] = 1.0; translation_matrix[3 * 4 + 3] = 1.0; @@ -31,7 +31,12 @@ /* matrix.c */ void mult_m4_p4(float *result, const float *mat4, const float *point4); void mult_m4_m4(float *result, const float *a4, const float *b4); +void init_m4_x_rotate(float *mat4, float x_rads); void init_m4_y_rotate(float *mat4, float y_rads); +void init_m4_z_rotate(float *mat4, float z_rads); +void init_m4_translate(float *mat4, float x, float y, float z); +void init_m4_perspective(float *mat4, float fovy, float aspect, + float near, float far); void print_m4(const float *mat4, const char *name); /* load_texture.c */ @@ -3,20 +3,21 @@ varying vec2 texcoord; varying vec3 light_surf; varying vec3 eye_surf; varying vec3 tangent_surf; +uniform mat4 mvp, mv; void main() { - vec3 t = gl_NormalMatrix * gl_MultiTexCoord1.xyz; - vec3 n = gl_NormalMatrix * gl_Normal; + vec3 t = (mv * vec4(gl_MultiTexCoord1.xyz, 0.0)).xyz; + vec3 n = (mv * vec4(gl_Normal, 0.0)).xyz; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = mvp * gl_Vertex; mat3 tbn = mat3(t, cross(n, t), n ); - vec3 vertex_eye = vec3(gl_ModelViewMatrix * gl_Vertex); + vec3 vertex_eye = vec3(mv * gl_Vertex); texcoord = vec2(gl_MultiTexCoord0.x * 4, gl_MultiTexCoord0.y); light_surf = normalize((light_eye - vertex_eye) * tbn); @@ -1,5 +1,6 @@ /* * Copyright © 2009 Eric Anholt + * Copyright © 2009 Ian D. Romanick * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,6 +33,13 @@ #include "glass.h" +static const float identity_mat4[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +}; + /* result = mat4 * point4 */ void mult_m4_p4(float *result, const float *mat4, const float *point4) @@ -63,6 +71,17 @@ void mult_m4_m4(float *result, const float *a4, const float *b4) { int row, col; + float a_temp[16], b_temp[16]; + + if (a4 == result) { + memcpy(a_temp, a4, sizeof(a_temp)); + a4 = a_temp; + } + if (b4 == result) { + memcpy(b_temp, b4, sizeof(b_temp)); + b4 = b_temp; + } + for (col = 0; col < 4; col++) { for (row = 0; row < 4; row++) { result[col * 4 + row] = @@ -91,11 +110,24 @@ print_m4(const float *mat4, const char *name) } } -/* +void +init_m4_translate(float *mat4, float x, float y, float z) +{ + memcpy(mat4, identity_mat4, sizeof(identity_mat4)); + + mat4[3 * 4 + 0] = x; + mat4[3 * 4 + 1] = y; + mat4[3 * 4 + 2] = z; +} + void init_m4_x_rotate(float *mat4, float x_rads) { - memset(mat4, 0, sizeof(mat4)); + int i; + + for (i = 0; i < 16; i++) + mat4[i] = 0.0; + mat4[0 * 4 + 0] = 1.0; mat4[1 * 4 + 1] = cos(x_rads); mat4[1 * 4 + 2] = sin(x_rads); @@ -103,7 +135,6 @@ init_m4_x_rotate(float *mat4, float x_rads) mat4[2 * 4 + 2] = cos(x_rads); mat4[3 * 4 + 3] = 1.0; } -*/ void init_m4_y_rotate(float *mat4, float y_rads) @@ -120,3 +151,36 @@ init_m4_y_rotate(float *mat4, float y_rads) mat4[2 * 4 + 2] = cos(y_rads); mat4[3 * 4 + 3] = 1.0; } + +void +init_m4_z_rotate(float *mat4, float y_rads) +{ + int i; + + for (i = 0; i < 16; i++) + mat4[i] = 0.0; + + mat4[1 * 4 + 1] = 1.0; + mat4[0 * 4 + 0] = cos(y_rads); + mat4[0 * 4 + 2] = sin(y_rads); + mat4[2 * 4 + 0] = -sin(y_rads); + mat4[2 * 4 + 2] = cos(y_rads); + mat4[3 * 4 + 3] = 1.0; +} + +void +init_m4_perspective(float *mat4, float fovy, float aspect, + float near, float far) +{ + double sine = sin(fovy / 2.0); + double cosine = cos(fovy / 2.0); + + memcpy(mat4, identity_mat4, sizeof(identity_mat4)); + + mat4[0 * 4 + 0] = cosine / (sine * aspect); + mat4[1 * 4 + 1] = cosine / sine; + mat4[2 * 4 + 2] = -(far + near) / (far - near); + mat4[2 * 4 + 3] = -1.0; + mat4[3 * 4 + 2] = -2.0 * near * far / (far - near); + mat4[3 * 4 + 3] = 0.0; +} |