glstuff

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
MMakefile | 3++-
Mglue.h | 7+++++++
Amatrix.cc | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amatrix.h | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest5.c | 193-------------------------------------------------------------------------------
Atest5.cc | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mutil.c | 11++++++++++-
Mutil.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