summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2010-10-13 02:34:58 -0500
committerKamil Kaminski <kamilkss@gmail.com>2010-10-13 02:34:58 -0500
commit12d3ce2f336f634d6e49dcb014411aca1444b082 (patch)
treeb876cf2b4b0d26d3985d458d19337a0d937f494e
parent0ea7ef8bba36e2f9a1e06e077f94aadc55616ac2 (diff)
downloadGLPyramid-12d3ce2f336f634d6e49dcb014411aca1444b082.tar.gz
GLPyramid-12d3ce2f336f634d6e49dcb014411aca1444b082.tar.bz2
GLPyramid-12d3ce2f336f634d6e49dcb014411aca1444b082.zip
Initial camera
-rw-r--r--sdl/GL_todo.txt8
-rw-r--r--sdl/Makefile7
-rw-r--r--sdl/glframe.c107
-rw-r--r--sdl/glframe.h21
-rw-r--r--sdl/gltools.c6
-rw-r--r--sdl/math3d.c2
-rw-r--r--sdl/math3d.h5
-rw-r--r--sdl/pyramid.c45
8 files changed, 189 insertions, 12 deletions
diff --git a/sdl/GL_todo.txt b/sdl/GL_todo.txt
index 3a59826..845aabd 100644
--- a/sdl/GL_todo.txt
+++ b/sdl/GL_todo.txt
@@ -1,5 +1,11 @@
+pass for now:
- cast a shadow
-- create camera struct/class and walk with arrow keys, gluLookAt() ?
+
+wip:
- extend m3d
+
+todo:
+- create camera struct/class and walk with arrow keys, gluLookAt() ?
- enable fog
- xbox controller
+- obj loader
diff --git a/sdl/Makefile b/sdl/Makefile
index 0ea6faa..51a013f 100644
--- a/sdl/Makefile
+++ b/sdl/Makefile
@@ -1,5 +1,5 @@
PROG = pyramid
-OBJS = $(PROG).o math3d.o gltools.o
+OBJS = $(PROG).o math3d.o gltools.o glframe.o
CC = gcc
DBGFLAGS = -g -O0
ifdef DEBUG
@@ -23,7 +23,10 @@ math3d.o: math3d.c math3d.h
$(CC) -c $(CFLAGS) math3d.c
gltools.o: gltools.c gltools.h math3d.h
- $(CC) -c $(CFLAGS) gltools.c
+ $(CC) -c $(CFLAGS) gltools.c
+
+glframe.o: glframe.c math3d.h
+ $(CC) -c $(CFLAGS) glframe.c
.PHONY: clean
diff --git a/sdl/glframe.c b/sdl/glframe.c
new file mode 100644
index 0000000..fa6b461
--- /dev/null
+++ b/sdl/glframe.c
@@ -0,0 +1,107 @@
+/* glframe.c
+ *
+ * Camera
+ *
+ * note: we could make these functions to be inlines, but they would need
+ * to be moved into the header
+ *
+ */
+
+#include "glframe.h"
+#include "math3d.h"
+
+void reset_glframe(GLFrame *frame)
+{
+ frame->v_location[0] = 0.0f;
+ frame->v_location[1] = 0.0f;
+ frame->v_location[2] = 0.0f;
+
+ frame->v_forward[0] = 0.0f;
+ frame->v_forward[1] = 0.0f;
+ frame->v_forward[2] = -1.0f;
+
+ frame->v_up[0] = 0.0f;
+ frame->v_up[1] = 1.0f;
+ frame->v_up[2] = 0.0f;
+}
+
+/* get a 4x4 transformation matrix that describes the ccamera orientation */
+void get_camera_orientation(GLFrame *frame, M3DMatrix44f m)
+{
+ M3DVector3f x, z;
+
+ /* make rotation matrix, z vector is reversed */
+ z[0] = -frame->v_forward[0];
+ z[1] = -frame->v_forward[1];
+ z[2] = -frame->v_forward[2];
+
+ /* x vector = y cross z */
+ m3dCrossProductf(x, frame->v_up, z);
+
+ /* matrix has no translation information and is transposed */
+ #define M(row,col) m[col*4+row]
+ M(0, 0) = x[0];
+ M(0, 1) = x[1];
+ M(0, 2) = x[2];
+ M(0, 3) = 0.0;
+ M(1, 0) = frame->v_up[0];
+ M(1, 1) = frame->v_up[1];
+ M(1, 2) = frame->v_up[2];
+ M(1, 3) = 0.0;
+ M(2, 0) = z[0];
+ M(2, 1) = z[1];
+ M(2, 2) = z[2];
+ M(2, 3) = 0.0;
+ M(3, 0) = 0.0;
+ M(3, 1) = 0.0;
+ M(3, 2) = 0.0;
+ M(3, 3) = 1.0;
+ #undef M
+}
+
+/* perform viewing or modeling transformations */
+/* some of the code is unimplemented */
+void apply_camera_transform(GLFrame *frame)
+{
+ M3DMatrix44f m;
+ get_camera_orientation(frame, m);
+ glMultMatrixf(m);
+
+#if 0
+ /* if Rotation only, then do not do the translation */
+ if (!rot_only)
+ glTranslatef(-v_location[0], -v_location[1], -v_location[2]);
+
+ gluLookAt(v_location[0], v_location[1], v_location[2],
+ v_location[0] + v_forward[0],
+ v_location[1] + v_forward[1],
+ v_location[2] + v_forward[2],
+ v_up[0], v_up[1], v_up[2]);
+#endif
+}
+
+void move_forward(GLFrame *frame, float delta)
+{
+ // Move along direction of front direction
+ frame->v_location[0] += frame->v_forward[0] * delta;
+ frame->v_location[1] += frame->v_forward[1] * delta;
+ frame->v_location[2] += frame->v_forward[2] * delta;
+}
+
+void rotate_local_y(GLFrame *frame, float angle)
+{
+ M3DMatrix44f rotMat;
+
+ /* just Rotate around the up vector */
+ /* create a rotation matrix around my Up (Y) vector */
+ m3dRotationMatrix44f(rotMat, angle, frame->v_up[0], frame->v_up[1], frame->v_up[2]);
+
+ M3DVector3f newVect;
+
+ /* rotate forward pointing vector (inlined 3x3 transform) */
+ newVect[0] = rotMat[0] * frame->v_forward[0] + rotMat[4] * frame->v_forward[1] + rotMat[8] * frame->v_forward[2];
+ newVect[1] = rotMat[1] * frame->v_forward[0] + rotMat[5] * frame->v_forward[1] + rotMat[9] * frame->v_forward[2];
+ newVect[2] = rotMat[2] * frame->v_forward[0] + rotMat[6] * frame->v_forward[1] + rotMat[10] * frame->v_forward[2];
+ m3dCopyVector3f(frame->v_forward, newVect);
+}
+
diff --git a/sdl/glframe.h b/sdl/glframe.h
new file mode 100644
index 0000000..fa5c991
--- /dev/null
+++ b/sdl/glframe.h
@@ -0,0 +1,21 @@
+#ifndef _GLFRAME_H_
+#define _GLFRAME_H_
+
+#include "math3d.h"
+
+typedef struct
+{
+ M3DVector3f v_location; /* location */
+ M3DVector3f v_forward; /* where am I heading */
+ M3DVector3f v_up; /* which way is up */
+} GLFrame;
+
+/* function prototypes */
+void reset_glframe(GLFrame *frame);
+void get_camera_orientation(GLFrame *frame, M3DMatrix44f m);
+void apply_camera_transform(GLFrame *frame);
+void move_forward(GLFrame *frame, float delta);
+void rotate_local_y(GLFrame *frame, float angle);
+
+#endif
+
diff --git a/sdl/gltools.c b/sdl/gltools.c
index 15e07ef..350f3db 100644
--- a/sdl/gltools.c
+++ b/sdl/gltools.c
@@ -1,3 +1,9 @@
+/* gltools.c
+ *
+ * OpenGL Tools
+ *
+ */
+
#include "math3d.h"
#include "gltools.h"
diff --git a/sdl/math3d.c b/sdl/math3d.c
index 53e0fff..10167a5 100644
--- a/sdl/math3d.c
+++ b/sdl/math3d.c
@@ -1,6 +1,8 @@
/* revision 6 */
/* @2010 Kamil Kaminski
+ *
+ * math3d.c
*
* this code is not yet endian aware, and it won't be, screw powerpc
* the style of the syntax is original k&r except there's \n
diff --git a/sdl/math3d.h b/sdl/math3d.h
index 4ebe092..510c017 100644
--- a/sdl/math3d.h
+++ b/sdl/math3d.h
@@ -105,5 +105,10 @@ static inline void m3dTransposeMatrix44f(M3DMatrix44f dst,
TRANSPOSE44(dst, src);
}
+static inline void m3dCopyVector3f(M3DVector3f dst, const M3DVector3f src)
+{
+ memcpy(dst, src, sizeof(M3DVector3f));
+}
+
#endif
diff --git a/sdl/pyramid.c b/sdl/pyramid.c
index ab98494..1d36870 100644
--- a/sdl/pyramid.c
+++ b/sdl/pyramid.c
@@ -1,8 +1,14 @@
/* pyramid.c
*
+ * @2010 Kamil Kaminski
+ *
* notes: since lighting is enabled, we need to specify normals for
* each polygon face so the OpenGL can calculate e.g. how light reflects
*
+ * drawing a shadow for the pyramid would require drawing things twice, so on 2nd
+ * pass we would draw with black color and multiply by squished matrix, we should
+ * get to this later with better approach
+ *
*/
#include <SDL/SDL.h>
@@ -10,11 +16,13 @@
/* for some reason order of the headers matters */
#include "math3d.h"
#include "gltools.h"
+#include "glframe.h"
#include <sys/time.h>
-#define FRAMES_PER_SECOND 300
+#define FRAMES_PER_SECOND 60
/* global */
int program_running = 1;
+GLFrame camera;
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
@@ -95,6 +103,9 @@ static void SetupRC()
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);
+
+ /* set the camera to <0,0,0> */
+ reset_glframe(&camera);
}
static void keys(SDL_keysym *keysym, unsigned int *keys_held, int flag)
@@ -104,23 +115,36 @@ static void keys(SDL_keysym *keysym, unsigned int *keys_held, int flag)
switch (keysym->sym)
{
case SDLK_ESCAPE: program_running = 0; break;
- case SDLK_w: xRot -= 1.0f; break;
- case SDLK_s: xRot += 1.0f; break;
- case SDLK_a: yRot -= 1.0f; break;
- case SDLK_d: yRot += 1.0f; break;
+ case SDLK_w: xRot -= 5.0f; break;
+ case SDLK_s: xRot += 5.0f; break;
+ case SDLK_a: yRot -= 5.0f; break;
+ case SDLK_d: yRot += 5.0f; break;
+ case SDLK_UP: move_forward(&camera, 0.1f); break;
+ case SDLK_DOWN: move_forward(&camera, -0.1f); break;
+ case SDLK_LEFT: rotate_local_y(&camera, 0.1f); break;
+ case SDLK_RIGHT: rotate_local_y(&camera, -0.1f); break;
default: break;
}
}
else
{
if (keys_held[SDLK_w])
- xRot -= 1.0f;
+ xRot -= 5.0f;
if (keys_held[SDLK_s])
- xRot += 1.0f;
+ xRot += 5.0f;
if (keys_held[SDLK_a])
- yRot -= 1.0f;
+ yRot -= 5.0f;
if (keys_held[SDLK_d])
- yRot += 1.0f;
+ yRot += 5.0f;
+
+ if (keys_held[SDLK_UP])
+ move_forward(&camera, 0.01f);
+ if (keys_held[SDLK_DOWN])
+ move_forward(&camera, -0.01f);
+ if (keys_held[SDLK_LEFT])
+ rotate_local_y(&camera, 0.01f);
+ if (keys_held[SDLK_RIGHT])
+ rotate_local_y(&camera, -0.01f);
}
xRot = (GLfloat) ((const int) xRot % 360);
@@ -206,6 +230,9 @@ static void render(void)
/* save the matrix state and do the rotations */
glPushMatrix();
+
+ apply_camera_transform(&camera);
+
/* move object back and do in place rotation */
glTranslatef(0.0f, 0.2f, -3.5f);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);