summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-21 21:42:11 -0700
committerEric Anholt <eric@anholt.net>2009-07-28 10:43:10 -0700
commit57ee2c3ababab71911e5669932a33fb981c1bf42 (patch)
tree96ce49691aa4542bff2ce98ba30f681498ada1a0
parent64575ce8f515b6c2f997ebe509f858cb4d384c50 (diff)
Use glu3 for handling our matrices instead of using ff.
-rw-r--r--configure.ac2
-rw-r--r--glass.c107
-rw-r--r--glass.h5
-rw-r--r--glass.vert9
-rw-r--r--matrix.c70
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.
diff --git a/glass.c b/glass.c
index adaebae..e86d28f 100644
--- a/glass.c
+++ b/glass.c
@@ -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;
diff --git a/glass.h b/glass.h
index b84d5ae..ae113f4 100644
--- a/glass.h
+++ b/glass.h
@@ -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 */
diff --git a/glass.vert b/glass.vert
index 293a804..abb1661 100644
--- a/glass.vert
+++ b/glass.vert
@@ -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);
diff --git a/matrix.c b/matrix.c
index ffccbce..d587da6 100644
--- a/matrix.c
+++ b/matrix.c
@@ -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;
+}