commit 0f47d3cb2fed4fc7bbd371aa52d0c0785f79a092
parent ee4245064e020bb7a11c19781d52ab8fe0537b5c
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 20 Jan 2013 22:07:44 -0800
hello, c++ world
- fancy new C++ mat4 and vec4 classes
- convert test5.c to test5.cc
- everything seems to still work...
Diffstat:
M | Makefile | | | 3 | ++- |
M | glue.h | | | 7 | +++++++ |
A | matrix.cc | | | 123 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | matrix.h | | | 166 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | test5.c | | | 193 | ------------------------------------------------------------------------------- |
A | test5.cc | | | 185 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | util.c | | | 11 | ++++++++++- |
M | util.h | | | 10 | ++++++++++ |
8 files changed, 503 insertions(+), 195 deletions(-)
diff --git a/Makefile b/Makefile
@@ -6,6 +6,7 @@ SDLFLAGS := $(shell $(SDLCFG) --cflags)
SDLLIBS := $(shell $(SDLCFG) --libs)
CFLAGS := $(SDLFLAGS) -DWITH_SDL2=0 -Wall -g
+CXXFLAGS := $(CFLAGS)
LIBS := $(SDLLIBS) -lGL -lm -lpng
COMMONOBJS := util.o sdlglue.o loadpng.o loadfile.o loadobj.o
@@ -31,7 +32,7 @@ TEST4OBJS := test4.o $(COMMONOBJS)
test4: $(TEST4OBJS)
$(CC) -o test4 $(TEST4OBJS) $(LIBS)
-TEST5OBJS := test5.o $(COMMONOBJS)
+TEST5OBJS := test5.o $(COMMONOBJS) matrix.o
test5: $(TEST5OBJS)
$(CC) -o test5 $(TEST5OBJS) $(LIBS)
diff --git a/glue.h b/glue.h
@@ -20,6 +20,10 @@
#include <SDL_opengl.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ctxt {
unsigned width;
unsigned height;
@@ -32,4 +36,7 @@ int scene_draw(struct ctxt *c);
int shader_compile(const char *vshader, const char *fshader,
GLuint *pgm, GLuint *vshd, GLuint *fshd);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/matrix.cc b/matrix.cc
@@ -0,0 +1,123 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "matrix.h"
+
+/* m = a * b m and b must not point to the same matrix */
+void __mat4_mul_mat4(float m[16], const float a[16], const float b[16]) {
+ for (int i = 0; i < 16; i += 4) {
+ float ai0 = a[i+0], ai1 = a[i+1], ai2 = a[i+2], ai3 = a[i+3];
+ m[i+0] = ai0*b[0] + ai1*b[4] + ai2*b[8] + ai3*b[12];
+ m[i+1] = ai0*b[1] + ai1*b[5] + ai2*b[9] + ai3*b[13];
+ m[i+2] = ai0*b[2] + ai1*b[6] + ai2*b[10] + ai3*b[14];
+ m[i+3] = ai0*b[3] + ai1*b[7] + ai2*b[11] + ai3*b[15];
+ }
+}
+
+void __mat4_mul_vec4(float o[4], const float m[16], const float v[4]) {
+ float v0=v[0], v1=v[1], v2=v[2], v3=v[3];
+ o[0] = m[0]*v0 + m[4]*v1 + m[8]*v2 + m[12]*v3;
+ o[1] = m[1]*v0 + m[5]*v1 + m[9]*v2 + m[13]*v3;
+ o[2] = m[2]*v0 + m[6]*v1 + m[10]*v2 + m[14]*v3;
+ o[3] = m[3]*v0 + m[7]*v1 + m[11]*v2 + m[15]*v3;
+}
+
+void __mat4_set_identity(float m[16]) {
+ memset(m, 0, sizeof(float[16]));
+ m[0] = m[5] = m[10] = m[15] = 1.0f;
+}
+
+void __mat4_set_translate(float m[16], float x, float y, float z) {
+ memset(m, 0, sizeof(float[16]));
+ m[0] = m[5] = m[10] = 1.0;
+ m[12] = x;
+ m[13] = y;
+ m[14] = z;
+ m[15] = 1.0;
+}
+
+void __mat4_set_rotate_x(float m[16], float rad) {
+ float s = sinf(rad);
+ float c = cosf(rad);
+ memset(m, 0, sizeof(float[16]));
+ m[0] = 1.0;
+ m[5] = c;
+ m[6] = -s;
+ m[9] = s;
+ m[10] = c;
+ m[15] = 1.0;
+}
+
+void __mat4_set_rotate_y(float m[16], float rad) {
+ float s = sinf(rad);
+ float c = cosf(rad);
+ memset(m, 0, sizeof(float[16]));
+ m[0] = c;
+ m[2] = s;
+ m[5] = 1.0;
+ m[8] = -s;
+ m[10] = c;
+ m[15] = 1.0;
+}
+
+void __mat4_set_rotate_z(float m[16], float rad) {
+ float s = sinf(rad);
+ float c = cosf(rad);
+ memset(m, 0, sizeof(float[16]));
+ m[0] = c;
+ m[1] = -s;
+ m[4] = s;
+ m[5] = c;
+ m[10] = 1.0;
+ m[15] = 1.0;
+}
+
+void __mat4_set_frustum(float m[16], float left, float right, float bottom, float top, float znear, float zfar) {
+ float znear2 = 2.0 * znear;
+ float width = right - left;
+ float height = top - bottom;
+ float depth = zfar - znear;
+ memset(m, 0, sizeof(float[16]));
+ m[0] = znear2 / width;
+ m[5] = znear2 / height;
+ m[8] = (right + left) / width;
+ m[9] = (top + bottom) / height;
+ m[10] = (-zfar - znear) / depth;
+ m[11] = -1.0;
+ m[14] = (-znear2 * zfar) / depth;
+}
+
+void __mat4_set_perspective(float m[16], float fov, float aspect, float znear, float zfar) {
+ float ymax, xmax;
+ ymax = znear * tanf(fov / 2.0);
+ xmax = ymax * aspect;
+ __mat4_set_frustum(m, -xmax, xmax, -ymax, ymax, znear, zfar);
+}
+
+void __mat4_set_ortho(float m[16], float l, float r, float b, float t, float n, float f) {
+ memset(m, 0, sizeof(float[16]));
+ m[0] = 2.0 / (r - l);
+ m[5] = 2.0 / (t - b);
+ m[10] = -2.0 / (f - n);
+ m[12] = -((r + l) / (r - l));
+ m[13] = -((t + b) / (t - b));
+ m[14] = -((f + n) / (f - n));
+ m[15] = 1.0;
+}
+
diff --git a/matrix.h b/matrix.h
@@ -0,0 +1,166 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MATRIX_MATH_H_
+#define _MATRIX_MATH_H_
+
+#define D2R(d) (((d) * M_PI) / 180.0)
+
+/* low level operations */
+void __mat4_mul_mat4(float m[16], const float a[16], const float b[16]);
+void __mat4_mul_vec4(float o[4], const float m[16], const float v[4]);
+
+void __mat4_set_identity(float m[16]);
+void __mat4_set_translate(float m[16], float x, float y, float z);
+void __mat4_set_rotate_x(float m[16], float rad);
+void __mat4_set_rotate_y(float m[16], float rad);
+void __mat4_set_rotate_z(float m[16], float rad);
+
+void __mat4_set_frustum(float m[16], float left, float right,
+ float bottom, float top, float znear, float zfar);
+void __mat4_set_perspective(float m[16], float fov, float aspect,
+ float znear, float zfar);
+void __mat4_set_ortho(float m[16], float left, float right,
+ float bottom, float top, float znear, float zfar);
+
+class mat4;
+
+class vec4 {
+ float v[4];
+public:
+ vec4() { };
+ vec4(const vec4 &x) {
+ v[0] = x[0]; v[1] = x[1]; v[2] = x[2]; v[3] = x[3];
+ };
+ vec4(const float *raw) {
+ memcpy(v, raw, sizeof(float[4]));
+ }
+ vec4(float a, float b, float c, float d) {
+ v[0] = a; v[1] = b; v[2] = c; v[3] = d;
+ };
+ vec4(float x, float y, float z) {
+ v[0] = x; v[1] = y; v[2] = z; v[3] = 1.0;
+ };
+
+ /* raw accessor suitable for glSomething4fv() */
+ operator const float*() { return v; };
+
+ vec4& operator*=(float n) {
+ v[0]*=n; v[1]*=n; v[2]*=n; v[3]*=n;
+ return *this;
+ }
+
+ /* linear accessors */
+ float operator[] (const int n) const { return v[n]; };
+ float& operator[] (const int n) { return v[n]; };
+ float operator() (const int n) const { return v[n]; };
+ float& operator() (const int n) { return v[n]; };
+
+ friend vec4 operator*(const vec4& a, const float b);
+ friend vec4 operator/(const vec4& a, const float b);
+ friend vec4 operator+(const vec4& a, const vec4& b);
+ friend vec4 operator-(const vec4& a, const vec4& b);
+
+ friend vec4 operator*(const mat4& a, const vec4& b);
+};
+
+inline vec4 operator*(const vec4& a, const float n) {
+ return vec4(a.v[0]*n,a.v[1]*n,a.v[2]*n,a.v[3]*n);
+}
+inline vec4 operator/(const vec4& a, const float n) {
+ return vec4(a.v[0]/n,a.v[1]/n,a.v[2]/n,a.v[3]/n);
+}
+inline vec4 operator+(const vec4& a, const vec4& b) {
+ return vec4(a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]);
+}
+inline vec4 operator-(const vec4& a, const vec4& b) {
+ return vec4(a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]);
+}
+
+class mat4 {
+ float m[16];
+public:
+ mat4() { __mat4_set_identity(m); };
+ mat4(const float raw[16]) { memcpy(m, raw, sizeof(float[16])); };
+
+ /* raw column-major matrix, suitable for glSomething4fv() */
+ operator const float*() { return m; };
+
+ mat4& operator*=(const mat4& b) {
+ __mat4_mul_mat4(m, m, b.m);
+ return *this;
+ }
+
+ friend mat4 operator*(const mat4& a, const mat4& b) {
+ mat4 out;
+ __mat4_mul_mat4(out.m, a.m, b.m);
+ return out;
+ }
+
+ /* linear and grid accessors */
+ float operator[] (const int n) const { return m[n]; }
+ float& operator[] (const int n) { return m[n]; }
+ float operator() (const int col, const int row) const { return m[col * 4 + row]; };
+ float& operator() (const int col, const int row) { return m[col * 4 + row]; };
+
+ mat4& identity(void) {
+ __mat4_set_identity(m);
+ return *this;
+ };
+
+ mat4& rotateX(float rad) {
+ float r[16];
+ __mat4_set_rotate_x(r, rad);
+ __mat4_mul_mat4(m, m, r);
+ return *this;
+ };
+ mat4& rotateY(float rad) {
+ float r[16];
+ __mat4_set_rotate_y(r, rad);
+ __mat4_mul_mat4(m, m, r);
+ return *this;
+ };
+ mat4& rotateZ(float rad) {
+ float r[16];
+ __mat4_set_rotate_z(r, rad);
+ __mat4_mul_mat4(m, m, r);
+ return *this;
+ };
+ mat4& translate(float x, float y, float z) {
+ float t[16];
+ __mat4_set_translate(t, x, y, z);
+ __mat4_mul_mat4(m, m, t);
+ return *this;
+ };
+
+ mat4& setOrtho(float left, float right, float bottom, float top, float znear, float zfar) {
+ __mat4_set_ortho(m, left, right, bottom, top, znear, zfar);
+ return *this;
+ };
+ mat4& setPerspective(float fov, float aspect, float znear, float zfar) {
+ __mat4_set_perspective(m, fov, aspect, znear, zfar);
+ return *this;
+ };
+
+ friend vec4 operator*(const mat4& a, const vec4& b);
+};
+
+inline vec4 operator*(const mat4& a, const vec4& b) {
+ vec4 out;
+ __mat4_mul_vec4(out.v, a.m, b.v);
+ return out;
+}
+
+#endif
diff --git a/test5.c b/test5.c
@@ -1,193 +0,0 @@
-/* Copyright 2013 Brian Swetland <swetland@frotz.net>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "util.h"
-#include "glue.h"
-
-#include <math.h>
-
-void *texdata;
-unsigned texw, texh;
-
-const char *vert_src, *frag_src;
-
-GLuint pgm, vshd, fshd, tex0;
-GLuint aVertex, aNormal, aTexCoord;
-GLuint uMV, uMVP, uLight, uTexture;
-
-float camx = 0, camy = 0, camz = -5;
-float camrx = 0, camry = 0, camrz = 0;
-
-extern unsigned char keystate[];
-#include <SDL/SDL_keysym.h>
-
-mat4 Projection;
-
-float a = 0.0;
-
-struct model *m;
-
-int scene_init(struct ctxt *c) {
- float aspect = ((float) c->width) / ((float) c->height);
-
- if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1)))
- return -1;
- if (!(vert_src = load_file("test5.vs", 0)))
- return -1;
- if (!(frag_src = load_file("test5.fs", 0)))
- return -1;
-
- if (!(m = load_wavefront_obj("cube.obj")))
- return -1;
-
- glViewport(0, 0, c->width, c->height);
- glClearColor(0, 0, 0, 0);
- glClearDepth(1.0f);
-
- if (shader_compile(vert_src, frag_src, &pgm, &vshd, &fshd))
- return -1;
-
- aVertex = glGetAttribLocation(pgm, "aVertex");
- aNormal = glGetAttribLocation(pgm, "aNormal");
- aTexCoord = glGetAttribLocation(pgm, "aTexCoord");
- uMVP = glGetUniformLocation(pgm, "uMVP");
- uMV = glGetUniformLocation(pgm, "uMV");
- uLight = glGetUniformLocation(pgm, "uLight");
- uTexture = glGetUniformLocation(pgm, "uTexture");
-
- if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n");
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glFrontFace(GL_CCW);
-// glEnable(GL_BLEND);
-// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
- glGenTextures(1, &tex0);
-
- glBindTexture(GL_TEXTURE_2D, tex0);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, texdata);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- mtx_perspective(Projection, 60.0, aspect, 1.0, 100.0);
-
- return 0;
-}
-
-int scene_draw(struct ctxt *c) {
- mat4 MVP;
- mat4 MV;
- mat4 Model;
- mat4 View;
- mat4 tmp;
- vec4 light = { 0.0, 0.0, 0.0, 1.0 };
-
- float vz = cosf(camry * M_PI / 180.0);
- float vx = -sinf(camry * M_PI / 180.0);
- float vz2 = cosf((camry + 90.0) * M_PI / 180.0);
- float vx2 = -sinf((camry + 90.0) * M_PI / 180.0);
-
- if (keystate[SDLK_w]) { camx += vx * 0.1; camz += vz * 0.1; }
- if (keystate[SDLK_s]) { camx -= vx * 0.1; camz -= vz * 0.1; }
- if (keystate[SDLK_a]) { camx += vx2 * 0.1; camz += vz2 * 0.1; }
- if (keystate[SDLK_d]) { camx -= vx2 * 0.1; camz -= vz2 * 0.1; }
-
- if (keystate[SDLK_q]) camry += 3.0;
- if (keystate[SDLK_e]) camry -= 3.0;
-
- if (keystate[SDLK_r]) camrx -= 1.0;
- if (keystate[SDLK_f]) camrx += 1.0;
-
- if (keystate[SDLK_x]) { camrx = 0; camrz = 0; }
-
- if (camrx < -45.0) camrx = -45.0;
- if (camrx > 45.0) camrx = 45.0;
-
- mtx_identity(View);
- mtx_translation(tmp, -camx, camy, camz);
- mtx_mul(View, View, tmp);
- //mtx_translate(View, -camx, camy, camz);
- mtx_y_rotation(tmp, camry);
- mtx_mul(View, View, tmp);
- mtx_x_rotation(tmp, camrx);
- mtx_mul(View, View, tmp);
-
- a += 1.0;
- if (a > 360.0) a = 0.0;
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUseProgram(pgm);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex0);
-
- glUniform1i(uTexture, 0);
-
- glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata);
- glEnableVertexAttribArray(aVertex);
- glVertexAttribPointer(aNormal, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 3);
- glEnableVertexAttribArray(aNormal);
- glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 6);
- glEnableVertexAttribArray(aTexCoord);
-
- mtx_identity(Model);
- mtx_translate(Model, 20, 40, 30);
- mtx_mul_vec4(light, Model, light);
- mtx_mul_vec4(light, View, light);
- glUniform4fv(uLight, 1, light);
-
- mtx_identity(Model);
- mtx_mul_unsafe(MV, Model, View);
- mtx_mul_unsafe(MVP, MV, Projection);
-
- glUniformMatrix4fv(uMV, 1, GL_FALSE, (void*) MV);
- glUniformMatrix4fv(uMVP, 1, GL_FALSE, (void*) MVP);
- glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
-
- mtx_identity(Model);
- mtx_translate(Model, -3, 0, 0);
- mtx_mul_unsafe(MV, Model, View);
- mtx_mul_unsafe(MVP, MV, Projection);
-
- glUniformMatrix4fv(uMV, 1, GL_FALSE, (void*) MV);
- glUniformMatrix4fv(uMVP, 1, GL_FALSE, (void*) MVP);
- glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
-
- mtx_identity(Model);
- mtx_y_rotation(tmp, a);
- mtx_mul_unsafe(Model, Model, tmp);
- mtx_translation(tmp, 3, 0, 0);
- mtx_mul_unsafe(Model, Model, tmp);
- //mtx_translate(Model, 3, 0, 0);
- //mtx_mul(Model, tmp, Model);
- //mtx_rotate_y(Model, a);
- mtx_mul_unsafe(MV, Model, View);
- mtx_mul_unsafe(MVP, MV, Projection);
-
- glUniformMatrix4fv(uMV, 1, GL_FALSE, (void*) MV);
- glUniformMatrix4fv(uMVP, 1, GL_FALSE, (void*) MVP);
- glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
-
- return 0;
-}
-
diff --git a/test5.cc b/test5.cc
@@ -0,0 +1,185 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "util.h"
+#include "matrix.h"
+#include "glue.h"
+
+#include <math.h>
+
+void *texdata;
+unsigned texw, texh;
+
+const char *vert_src, *frag_src;
+
+GLuint pgm, vshd, fshd, tex0;
+GLuint aVertex, aNormal, aTexCoord;
+GLuint uMV, uMVP, uLight, uTexture;
+
+float camx = 0, camy = 0, camz = -5;
+float camrx = 0, camry = 0, camrz = 0;
+
+extern unsigned char keystate[];
+#include <SDL/SDL_keysym.h>
+
+mat4 Projection;
+
+float a = 0.0;
+
+struct model *m;
+
+int scene_init(struct ctxt *c) {
+ float aspect = ((float) c->width) / ((float) c->height);
+
+ if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1)))
+ return -1;
+ if (!(vert_src = (const char*) load_file("test5.vs", 0)))
+ return -1;
+ if (!(frag_src = (const char*) load_file("test5.fs", 0)))
+ return -1;
+
+ if (!(m = load_wavefront_obj("cube.obj")))
+ return -1;
+
+ glViewport(0, 0, c->width, c->height);
+ glClearColor(0, 0, 0, 0);
+ glClearDepth(1.0f);
+
+ if (shader_compile(vert_src, frag_src, &pgm, &vshd, &fshd))
+ return -1;
+
+ aVertex = glGetAttribLocation(pgm, "aVertex");
+ aNormal = glGetAttribLocation(pgm, "aNormal");
+ aTexCoord = glGetAttribLocation(pgm, "aTexCoord");
+ uMVP = glGetUniformLocation(pgm, "uMVP");
+ uMV = glGetUniformLocation(pgm, "uMV");
+ uLight = glGetUniformLocation(pgm, "uLight");
+ uTexture = glGetUniformLocation(pgm, "uTexture");
+
+ if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n");
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
+// glEnable(GL_BLEND);
+// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glGenTextures(1, &tex0);
+
+ glBindTexture(GL_TEXTURE_2D, tex0);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, texdata);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ Projection.setPerspective(D2R(60.0), aspect, 1.0, 100.0);
+
+ return 0;
+}
+
+int scene_draw(struct ctxt *c) {
+ mat4 MVP;
+ mat4 MV;
+ mat4 Model;
+ mat4 View;
+ mat4 tmp;
+ vec4 light(0.0,0.0,0.0,1.0);
+
+ float vz = cosf(D2R(camry));
+ float vx = -sinf(D2R(camry));
+ float vz2 = cosf(D2R(camry + 90.0));
+ float vx2 = -sinf(D2R(camry + 90.0));
+
+ if (keystate[SDLK_w]) { camx += vx * 0.1; camz += vz * 0.1; }
+ if (keystate[SDLK_s]) { camx -= vx * 0.1; camz -= vz * 0.1; }
+ if (keystate[SDLK_a]) { camx += vx2 * 0.1; camz += vz2 * 0.1; }
+ if (keystate[SDLK_d]) { camx -= vx2 * 0.1; camz -= vz2 * 0.1; }
+
+ if (keystate[SDLK_q]) camry += 3.0;
+ if (keystate[SDLK_e]) camry -= 3.0;
+
+ if (keystate[SDLK_r]) camrx -= 1.0;
+ if (keystate[SDLK_f]) camrx += 1.0;
+
+ if (keystate[SDLK_x]) { camrx = 0; camrz = 0; }
+
+ if (camrx < -45.0) camrx = -45.0;
+ if (camrx > 45.0) camrx = 45.0;
+
+ View.identity();
+ View.translate(-camx, camy, camz);
+ View.rotateY(D2R(camry));
+ View.rotateX(D2R(camrx));
+
+ a += 1.0;
+ if (a > 360.0) a = 0.0;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glUseProgram(pgm);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, tex0);
+
+ glUniform1i(uTexture, 0);
+
+ glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata);
+ glEnableVertexAttribArray(aVertex);
+ glVertexAttribPointer(aNormal, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 3);
+ glEnableVertexAttribArray(aNormal);
+ glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 6);
+ glEnableVertexAttribArray(aTexCoord);
+
+ Model.identity();
+ Model.translate(20, 40, 30);
+ light = Model * light;
+ light = View * light;
+ glUniform4fv(uLight, 1, light);
+
+ Model.identity();
+ MV = Model * View;
+ MVP = MV * Projection;
+
+ glUniformMatrix4fv(uMV, 1, GL_FALSE, MV);
+ glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP);
+ glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
+
+ Model.identity();
+ Model.translate(-3, 0, 0);
+ MV = Model * View;
+ MVP = MV * Projection;
+
+ glUniformMatrix4fv(uMV, 1, GL_FALSE, MV);
+ glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP);
+ glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
+
+ Model.identity();
+ Model.translate(3, 0, 0);
+ Model.rotateY(D2R(a));
+ MV = Model * View;
+ MVP = MV * Projection;
+
+ glUniformMatrix4fv(uMV, 1, GL_FALSE, MV);
+ glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP);
+ glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx);
+
+ return 0;
+}
+
diff --git a/util.c b/util.c
@@ -13,8 +13,9 @@
* limitations under the License.
*/
-#include <math.h>
+#include <stdio.h>
#include <string.h>
+#include <math.h>
#include "util.h"
@@ -158,3 +159,11 @@ void mtx_ortho(mat4 m, float l, float r, float b, float t, float n, float f) {
m[3][3] = 1.0;
}
+void mtx_dump(const float m[16], const char *name) {
+ fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f | %s\n",m[0],m[4],m[8],m[12], name ? name : "");
+ fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[1],m[5],m[9],m[13]);
+ fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[2],m[6],m[10],m[14]);
+ fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[3],m[7],m[11],m[15]);
+}
+
+
diff --git a/util.h b/util.h
@@ -16,6 +16,9 @@
#ifndef _UTIL_H_
#define _UTIL_H_
+#ifdef __cplusplus
+extern "C" {
+#else
typedef float mat4[4][4];
typedef float vec4[4];
typedef float vec3[3];
@@ -57,6 +60,9 @@ void mtx_frustum(mat4 out,
void mtx_perspective(mat4 out,
float fov_degrees, float aspect_ratio,
float znear, float zfar);
+#endif
+
+void mtx_dump(const float m[16], const char *name);
/* file io helpers */
void *load_png_rgba(const char *fn, unsigned *width, unsigned *height, int texture);
@@ -76,5 +82,9 @@ struct model {
};
struct model *load_wavefront_obj(const char *fn);
+
+#ifdef __cplusplus
+}
+#endif
#endif