Added OpenGL test.

This commit is contained in:
Angelo Papenhoff 2015-01-17 21:51:04 +01:00
parent c0fab82c52
commit fc40bbdffe
17 changed files with 2283 additions and 0 deletions

21
tests/gl/Makefile Executable file
View File

@ -0,0 +1,21 @@
BUILDDIR = build
SRC = main.cpp glshader.cpp math.cpp camera.cpp
OBJ = $(patsubst %.cpp, $(BUILDDIR)/%.o, $(SRC))
DEP = $(patsubst %.cpp, $(BUILDDIR)/%.d, $(SRC))
RWDIR=$(HOME)/src/librw
LDLIBS=-pthread -lX11 -lXrandr -lXi -lXxf86vm -lGL -lGLEW -lm
CFLAGS=-g -I$(RWDIR) -Wall -Wextra
rwtest: $(OBJ) $(RWDIR)/librw-opengl.a /usr/local/lib/libglfw3.a
$(CXX) $^ $(LDLIBS) -o $@
$(BUILDDIR)/%.o: %.cpp
$(CXX) $(CFLAGS) -c $< -o $@
$(BUILDDIR)/%.d: %.cpp
$(CXX) -MM -MT '$(patsubst %.cpp,$(BUILDDIR)%.o,$<)' $(CFLAGS) $< > $@
clean:
rm $(BUILDDIR)/* rwtest
-include $(DEP)

20
tests/gl/Makefile.mingw Executable file
View File

@ -0,0 +1,20 @@
BUILDDIR = build
SRC = main.cpp glshader.cpp math.cpp camera.cpp
OBJ = $(patsubst %.cpp, $(BUILDDIR)/%.o, $(SRC))
DEP = $(patsubst %.cpp, $(BUILDDIR)/%.d, $(SRC))
RWDIR=$(HOME)/src/librw
LDLIBS=-static -lglfw3 -lglew32 -lopengl32 -lgdi32
CFLAGS=-g -I$(RWDIR) -Wall -Wextra -DGLEW_STATIC
rwtest: $(OBJ) $(RWDIR)/librw.a
$(CXX) $^ $(LDLIBS) -o $@
$(BUILDDIR)/%.o: %.cpp
$(CXX) $(CFLAGS) -c $< -o $@
$(BUILDDIR)/%.d: %.cpp
$(CXX) -MM -MT '$(patsubst %.cpp,$(BUILDDIR)%.o,$<)' $(CFLAGS) $< > $@
dep: $(DEP)
-include $(DEP)

168
tests/gl/camera.cpp Executable file
View File

@ -0,0 +1,168 @@
#include "rwtest.h"
using namespace std;
void
Camera::look(void)
{
projMat = Mat4::perspective(fov, aspectRatio, n, f);
viewMat = Mat4::lookat(position, target, up);
// state->mat4(PMAT,true)->val = Mat4::perspective(fov, aspectRatio, n, f);
// Mat4 mv = Mat4::lookat(position, target, up);
// state->mat4(MVMAT, true)->val = mv;
// state->mat3(NORMALMAT, true)->val = Mat3(mv);
}
void
Camera::setPosition(Vec3 q)
{
position = q;
}
Vec3
Camera::getPosition(void)
{
return position;
}
void
Camera::setTarget(Vec3 q)
{
position -= target - q;
target = q;
}
Vec3
Camera::getTarget(void)
{
return target;
}
float
Camera::getHeading(void)
{
Vec3 dir = target - position;
float a = atan2(dir.y, dir.x)-PI/2.0f;
return local_up.z < 0.0f ? a-PI : a;
}
void
Camera::turn(float yaw, float pitch)
{
yaw /= 2.0f;
pitch /= 2.0f;
Quat dir = Quat(target - position);
Quat r(cos(yaw), 0.0f, 0.0f, sin(yaw));
dir = r*dir*r.K();
local_up = Vec3(r*Quat(local_up)*r.K());
Quat right = dir.wedge(Quat(local_up)).U();
r = Quat(cos(pitch), right*sin(pitch));
dir = r*dir*r.K();
local_up = Vec3(right.wedge(dir).U());
if(local_up.z >=0) up.z = 1;
else up.z = -1;
target = position + Vec3(dir);
}
void
Camera::orbit(float yaw, float pitch)
{
yaw /= 2.0f;
pitch /= 2.0f;
Quat dir = Quat(target - position);
Quat r(cos(yaw), 0.0f, 0.0f, sin(yaw));
dir = r*dir*r.K();
local_up = Vec3(r*Quat(local_up)*r.K());
Quat right = dir.wedge(Quat(local_up)).U();
r = Quat(cos(-pitch), right*sin(-pitch));
dir = r*dir*r.K();
local_up = Vec3(right.wedge(dir).U());
if(local_up.z >=0) up.z = 1;
else up.z = -1;
position = target - Vec3(dir);
}
void
Camera::dolly(float dist)
{
Vec3 dir = (target - position).normalized()*dist;
position += dir;
target += dir;
}
void
Camera::zoom(float dist)
{
Vec3 dir = target - position;
float curdist = dir.norm();
if(dist >= curdist)
dist = curdist-0.01f;
dir = dir.normalized()*dist;
position += dir;
}
void
Camera::pan(float x, float y)
{
Vec3 dir = (target-position).normalized();
Vec3 right = dir.cross(up).normalized();
// Vec3 local_up = right.cross(dir).normalized();
dir = right*x + local_up*y;
position += dir;
target += dir;
}
float
Camera::sqDistanceTo(Vec3 q)
{
return (position - q).normsq();
}
float
Camera::distanceTo(Vec3 q)
{
return (position - q).norm();
}
void
Camera::setFov(float f)
{
fov = f;
}
float
Camera::getFov(void)
{
return fov;
}
void
Camera::setAspectRatio(float r)
{
aspectRatio = r;
}
void
Camera::setNearFar(float n, float f)
{
this->n = n;
this->f = f;
}
Camera::Camera()
{
position = Vec3(0.0f, 6.0f, 0.0f);
target = Vec3(0.0f, 0.0f, 0.0f);
local_up = up = Vec3(0.0f, 0.0f, 1.0f);
fov = 55.0f;
aspectRatio = 1.0f;
n = 0.1f;
f = 100.0f;
}

37
tests/gl/camera.h Executable file
View File

@ -0,0 +1,37 @@
class Camera
{
private:
Vec3 position;
Vec3 target;
Vec3 up;
Vec3 local_up;
float fov, aspectRatio;
float n, f;
public:
Mat4 projMat;
Mat4 viewMat;
void setPosition(Vec3 q);
Vec3 getPosition(void);
void setTarget(Vec3 q);
Vec3 getTarget(void);
float getHeading(void);
void turn(float yaw, float pitch);
void orbit(float yaw, float pitch);
void dolly(float dist);
void zoom(float dist);
void pan(float x, float y);
void setFov(float f);
float getFov(void);
void setAspectRatio(float r);
void setNearFar(float n, float f);
void look(void);
float distanceTo(Vec3 q);
float sqDistanceTo(Vec3 q);
Camera(void);
};

6
tests/gl/gl.h Executable file
View File

@ -0,0 +1,6 @@
namespace gl {
GLint linkProgram(GLint vertshader, GLint fragshader);
GLint compileShader(const char **src, int count, int type);
}

61
tests/gl/glshader.cpp Executable file
View File

@ -0,0 +1,61 @@
#include "rwtest.h"
namespace gl {
GLint
linkProgram(GLint vertshader, GLint fragshader)
{
GLint success;
GLint len;
char *log;
GLint program = glCreateProgram();
assert(program != 0);
glBindAttribLocation(program, 0, "in_vertex");
glBindAttribLocation(program, 1, "in_texCoord");
glBindAttribLocation(program, 2, "in_normal");
glBindAttribLocation(program, 3, "in_color");
glBindAttribLocation(program, 4, "in_weight");
glBindAttribLocation(program, 5, "in_indices");
glBindAttribLocation(program, 6, "in_extraColor");
glAttachShader(program, vertshader);
glAttachShader(program, fragshader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if(!success){
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
log = new char[len];
glGetProgramInfoLog(program, len, NULL, log);
fprintf(stderr, "Link Error: %s\n", log);
delete[] log;
glDeleteProgram(program);
return 0;
}
return program;
}
GLint
compileShader(const char **src, int count, int type)
{
GLint success;
GLint len;
char *log;
GLint shader = glCreateShader(type);
assert(shader != 0);
glShaderSource(shader, count, src, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success){
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
log = new char[len];
glGetShaderInfoLog(shader, len, NULL, log);
fprintf(stderr, "Shader Error: %s\n", log);
delete[] log;
glDeleteProgram(shader);
return 0;
}
return shader;
}
}

341
tests/gl/main.cpp Executable file
View File

@ -0,0 +1,341 @@
#include "rwtest.h"
using namespace std;
int screenWidth = 640, screenHeight= 480;
bool running = true;
Camera *camera;
GLint program;
GLuint vbo;
Rw::Clump *clump;
char *filename;
void
renderAtomic(Rw::Atomic *atomic)
{
using namespace Rw;
static GLenum prim[] = {
GL_TRIANGLES, GL_TRIANGLE_STRIP
};
Geometry *geo = atomic->geometry;
if(!(geo->geoflags & Geometry::NATIVE))
Gl::Instance(atomic);
Gl::InstanceDataHeader *inst = (Gl::InstanceDataHeader*)geo->instData;
MeshHeader *meshHeader = geo->meshHeader;
Frame *frm = atomic->frame;
frm->updateLTM();
glUniformMatrix4fv(glGetUniformLocation(program, "worldMat"),
1, GL_FALSE, frm->ltm);
glVertexAttrib4f(3, 1.0f, 1.0f, 1.0f, 1.0f);
if(inst->vbo == 0 && inst->ibo == 0)
Gl::UploadGeo(geo);
glBindBuffer(GL_ARRAY_BUFFER, inst->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, inst->ibo);
Gl::SetAttribPointers(inst);
uint64 offset = 0;
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
Mesh *mesh = &meshHeader->mesh[i];
glDrawElements(prim[meshHeader->flags], mesh->numIndices,
GL_UNSIGNED_SHORT, (void*)offset);
offset += mesh->numIndices*2;
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void
render(void)
{
glUseProgram(program);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera->look();
glUniformMatrix4fv(glGetUniformLocation(program, "projMat"),
1, GL_FALSE, camera->projMat.cr);
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"),
1, GL_FALSE, camera->viewMat.cr);
glVertexAttrib3f(2, -0.5f, 0.5f, 0.70710f);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 28, (GLvoid*)0);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 28, (GLvoid*)12);
glDrawArrays(GL_LINES, 0, 6);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(3);
for(Rw::uint32 i = 0; i < clump->numAtomics; i++){
char *name = PLUGINOFFSET(char, clump->atomicList[i]->frame,
Rw::NodeNameOffset);
if(strstr(name, "_dam") || strstr(name, "_vlo"))
continue;
renderAtomic(clump->atomicList[i]);
}
}
void
init(void)
{
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
const char *shadersrc =
"#version 120\n"
"#ifdef VERTEX\n"
"uniform mat4 projMat;"
"uniform mat4 viewMat;"
"uniform mat4 worldMat;"
"attribute vec3 in_vertex;"
"attribute vec3 in_texColor;"
"attribute vec3 in_normal;"
"attribute vec4 in_color;"
"varying vec4 v_color;"
"vec3 lightdir = vec3(0.5, -0.5, -0.70710);"
"void main()"
"{"
" gl_Position = projMat * viewMat * worldMat * vec4(in_vertex, 1.0);"
" vec3 n = mat3(worldMat) * in_normal;"
" float l = max(0.0, dot(n, -lightdir));"
" v_color = in_color*l;"
"}\n"
"#endif\n"
"#ifdef FRAGMENT\n"
"varying vec4 v_color;"
"void main()"
"{"
" gl_FragColor = v_color;"
"}\n"
"#endif\n";
const char *srcarr[] = { "#define VERTEX", shadersrc };
GLint vertshader = gl::compileShader(srcarr, 2, GL_VERTEX_SHADER);
assert(vertshader != 0);
srcarr[0] = "#define FRAGMENT";
GLint fragshader = gl::compileShader(srcarr, 2, GL_FRAGMENT_SHADER);
assert(fragshader != 0);
program = gl::linkProgram(vertshader, fragshader);
assert(program != 0);
GLfloat vertarray[] = {
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertarray),
vertarray, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
camera = new Camera;
camera->setAspectRatio(1.0f*screenWidth/screenHeight);
camera->setNearFar(0.1f, 450.0f);
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
Rw::RegisterMaterialRightsPlugin();
Rw::RegisterMatFXPlugin();
Rw::RegisterAtomicRightsPlugin();
Rw::RegisterHAnimPlugin();
Rw::RegisterNodeNamePlugin();
Rw::RegisterBreakableModelPlugin();
Rw::RegisterExtraVertColorPlugin();
Rw::Ps2::RegisterADCPlugin();
Rw::RegisterSkinPlugin();
Rw::RegisterNativeDataPlugin();
// Rw::Ps2::RegisterNativeDataPlugin();
Rw::RegisterMeshPlugin();
Rw::StreamFile in;
// in.open("player-vc-ogl.dff", "rb");
// in.open("player-iii.dff", "rb");
// in.open("admiral-ogl.dff", "rb");
in.open(filename, "rb");
Rw::FindChunk(&in, Rw::ID_CLUMP, NULL, NULL);
clump = Rw::Clump::streamRead(&in);
assert(clump);
in.close();
}
void
keypress(GLFWwindow *w, int key, int scancode, int action, int mods)
{
if(action != GLFW_PRESS)
return;
switch(key){
case 'Q':
case GLFW_KEY_ESCAPE:
running = false;
break;
}
}
static int lastX, lastY;
static int clickX, clickY;
static bool isLDown, isMDown, isRDown;
static bool isShiftDown, isCtrlDown, isAltDown;
void
mouseButton(GLFWwindow *w, int button, int action, int mods)
{
double x, y;
glfwGetCursorPos(w, &x, &y);
if(action == GLFW_PRESS){
lastX = clickX = x;
lastY = clickY = y;
if(button == GLFW_MOUSE_BUTTON_LEFT)
isLDown = true;
if(button == GLFW_MOUSE_BUTTON_MIDDLE)
isMDown = true;
if(button == GLFW_MOUSE_BUTTON_RIGHT)
isRDown = true;
}else if(action == GLFW_RELEASE){
if(button == GLFW_MOUSE_BUTTON_LEFT)
isLDown = false;
if(button == GLFW_MOUSE_BUTTON_MIDDLE)
isMDown = false;
if(button == GLFW_MOUSE_BUTTON_RIGHT)
isRDown = false;
}
}
void
mouseMotion(GLFWwindow *w, double x, double y)
{
GLfloat dx, dy;
static int xoff = 0, yoff = 0;
static bool wrappedLast = false;
int width, height;
glfwGetWindowSize(w, &width, &height);
dx = float(lastX - x) / float(width);
dy = float(lastY - y) / float(height);
/* Wrap the mouse if it goes over the window border.
* Unfortunately, after glfwSetMousePos is done, there can be old
* events with an old mouse position,
* hence the check if the pointer was wrapped the last time. */
if((isLDown || isMDown || isRDown) &&
(x < 0 || y < 0 || x >= width || y >= height)){
if(wrappedLast){
dx = float(lastX-xoff - x) / float(width);
dy = float(lastY-yoff - y) / float(height);
}
xoff = yoff = 0;
while (x+xoff >= width) xoff -= width;
while (y+yoff >= height) yoff -= height;
while (x+xoff < 0) xoff += width;
while (y+yoff < 0) yoff += height;
glfwSetCursorPos(w, x+xoff, y+yoff);
wrappedLast = true;
}else{
wrappedLast = false;
xoff = yoff = 0;
}
lastX = x+xoff;
lastY = y+yoff;
if(isLDown){
if(isShiftDown)
camera->turn(dx*2.0f, dy*2.0f);
else
camera->orbit(dx*2.0f, -dy*2.0f);
}
if(isMDown){
if(isShiftDown)
;
else
camera->pan(dx*8.0f, -dy*8.0f);
}
if(isRDown){
if(isShiftDown)
;
else
camera->zoom(dx*12.0f);
}
}
void
resize(GLFWwindow*, int width, int height)
{
screenWidth = width;
screenHeight = height;
glViewport(0, 0, screenWidth, screenHeight);
camera->setAspectRatio(1.0f*screenWidth/screenHeight);
}
void
closewindow(GLFWwindow*)
{
running = false;
}
int
main(int argc, char *argv[])
{
if(argc < 2)
return 1;
filename = argv[1];
if(!glfwInit()){
fprintf(stderr, "Error: could not initialize GLFW\n");
return 1;
}
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight,
"OpenGL", 0, 0);
if(!window){
fprintf(stderr, "Error: could not create GLFW window\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
GLenum status = glewInit();
if(status != GLEW_OK){
fprintf(stderr, "Error: %s\n", glewGetErrorString(status));
return 1;
}
if(!GLEW_VERSION_2_0){
fprintf(stderr, "Error: OpenGL 2.0 needed\n");
return 1;
}
init();
glfwSetWindowSizeCallback(window, resize);
glfwSetWindowCloseCallback(window, closewindow);
glfwSetMouseButtonCallback(window, mouseButton);
glfwSetCursorPosCallback(window, mouseMotion);
glfwSetKeyCallback(window, keypress);
while(running){
glfwPollEvents();
isShiftDown = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
isCtrlDown = glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS;
isAltDown = glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS;
render();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}

1227
tests/gl/math.cpp Executable file

File diff suppressed because it is too large Load Diff

93
tests/gl/math/conversion.h Executable file
View File

@ -0,0 +1,93 @@
#ifndef MATH_CONVERSION_H
#define MATH_CONVERSION_H
Vec3::Vec3(const Vec4 &v)
: x(v.x), y(v.y), z(v.z)
{
}
Vec3::Vec3(const Quat &q)
: x(q.x), y(q.y), z(q.z)
{
}
Vec4::Vec4(const Vec3 &v, float w)
: x(v.x), y(v.y), z(v.z), w(w)
{
}
Vec4::Vec4(const Quat &q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{
}
Quat::Quat(const Vec3 &v)
: x(v.x), y(v.y), z(v.z)
{
}
Quat::Quat(float w, const Vec3 &v)
: w(w), x(v.x), y(v.y), z(v.z)
{
}
Quat::Quat(const Vec4 &v)
: w(v.w), x(v.x), y(v.y), z(v.z)
{
}
Mat3::Mat3(const Mat4 &m)
{
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
this->e[i][j] = m.e[i][j];
}
Mat4::Mat4(const Mat3 &m)
{
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
this->e[i][j] = m.e[i][j];
this->e[0][3] = 0.0f;
this->e[1][3] = 0.0f;
this->e[2][3] = 0.0f;
this->e[3][3] = 1.0f;
this->e[3][2] = 0.0f;
this->e[3][1] = 0.0f;
this->e[3][0] = 0.0f;
}
Mat4
Mat4::rotation(const Quat &v)
{
Mat4 m(1.0f);
m.e[0][0] = v.w*v.w + v.x*v.x - v.y*v.y - v.z*v.z;
m.e[1][0] = 2*v.x*v.y - 2*v.w*v.z;
m.e[2][0] = 2*v.w*v.y + 2*v.x*v.z;
m.e[0][1] = 2*v.w*v.z + 2*v.x*v.y;
m.e[1][1] = v.w*v.w - v.x*v.x + v.y*v.y - v.z*v.z;
m.e[2][1] = 2*v.y*v.z - 2*v.w*v.x;
m.e[0][2] = 2*v.x*v.z - 2*v.w*v.y;
m.e[1][2] = 2*v.w*v.x + 2*v.y*v.z;
m.e[2][2] = v.w*v.w - v.x*v.x - v.y*v.y + v.z*v.z;
return m;
}
Mat3
Mat3::rotation(const Quat &v)
{
Mat3 m(1.0f);
m.e[0][0] = v.w*v.w + v.x*v.x - v.y*v.y - v.z*v.z;
m.e[1][0] = 2*v.x*v.y - 2*v.w*v.z;
m.e[2][0] = 2*v.w*v.y + 2*v.x*v.z;
m.e[0][1] = 2*v.w*v.z + 2*v.x*v.y;
m.e[1][1] = v.w*v.w - v.x*v.x + v.y*v.y - v.z*v.z;
m.e[2][1] = 2*v.y*v.z - 2*v.w*v.x;
m.e[0][2] = 2*v.x*v.z - 2*v.w*v.y;
m.e[1][2] = 2*v.w*v.x + 2*v.y*v.z;
m.e[2][2] = v.w*v.w - v.x*v.x - v.y*v.y + v.z*v.z;
return m;
}
#endif

45
tests/gl/math/dquat.h Executable file
View File

@ -0,0 +1,45 @@
#ifndef MATH_DQUAT_H
#define MATH_DQUAT_H
#include <iostream>
#include <cmath>
class Vec3;
class Vec4;
class DQuat {
public:
Quat q1, q2;
DQuat(void);
DQuat(const Quat &q1, const Quat &q2);
DQuat operator-(void) const;
DQuat operator+(const DQuat &rhs) const;
DQuat operator-(const DQuat &rhs) const;
DQuat operator*(const DQuat &rhs) const;
DQuat operator*(float rhs) const;
DQuat operator/(float rhs) const;
DQuat &operator+=(const DQuat &rhs);
DQuat &operator-=(const DQuat &rhs);
DQuat &operator*=(const DQuat &rhs);
DQuat &operator*=(float rhs);
DQuat &operator/=(float rhs);
bool operator==(const DQuat &rhs) const;
bool operator!=(const DQuat &rhs) const;
// DQuat inv(void) const;
DQuat K(void) const; /* conjugate */
// DQuat S(void) const; /* scalar */
// DQuat V(void) const; /* vector */
// float T(void) const; /* tensor */
// float N(void) const; /* norm = tensor^2 */
// DQuat U(void) const; /* versor */
// DQuat wedge(const Quat &rhs) const;
// float inner(const Quat &rhs) const;
// DQuat slerp(const Quat &rhs, float t) const;
void print(std::ostream &of) const;
};
#endif

43
tests/gl/math/mat3.h Executable file
View File

@ -0,0 +1,43 @@
#ifndef MATH_MATRIX3_H
#define MATH_MATRIX3_H
#include <iostream>
#include <cmath>
class Mat4;
class Mat3 {
public:
union {
float e[3][3];
float cr[9];
};
Mat3(void);
Mat3(float f);
Mat3(float *f);
Mat3(float e00, float e10, float e20,
float e01, float e11, float e21,
float e02, float e12, float e22);
Mat3(const Mat4 &m);
float *ptr(void);
static Mat3 rotation(float theta, const Vec3 &v);
static Mat3 rotation(const Quat &v);
static Mat3 scale(const Vec3 &v);
Mat3 transpose(void) const;
Mat3 operator+(const Mat3 &rhs) const;
Mat3 operator-(const Mat3 &rhs) const;
Mat3 operator*(float rhs) const;
Mat3 operator/(float rhs) const;
Mat3 operator*(const Mat3 &rhs) const;
Vec3 operator*(const Vec3 &rhs) const;
Mat3 &operator+=(const Mat3 &rhs);
Mat3 &operator-=(const Mat3 &rhs);
Mat3 &operator*=(float rhs);
Mat3 &operator/=(float rhs);
Mat3 &operator*=(const Mat3 &rhs);
void print(std::ostream &of) const;
};
#endif

52
tests/gl/math/mat4.h Executable file
View File

@ -0,0 +1,52 @@
#ifndef MATH_MATRIX4_H
#define MATH_MATRIX4_H
#include <iostream>
#include <cmath>
class Mat3;
class Mat4 {
public:
union {
float e[4][4];
float cr[16];
};
Mat4(void);
Mat4(float f);
Mat4(float *f);
Mat4(float e00, float e10, float e20, float e30,
float e01, float e11, float e21, float e31,
float e02, float e12, float e22, float e32,
float e03, float e13, float e23, float e33);
Mat4(const Mat3 &m);
float *ptr(void);
static Mat4 perspective(float fov, float aspect, float n, float f);
static Mat4 frustum(float l, float r, float b, float t,
float n, float f);
static Mat4 ortho(float l, float r, float b, float t,
float n, float f);
static Mat4 lookat(const Vec3 &pos, const Vec3 &target, const Vec3 &up);
static Mat4 translation(const Vec3 &v);
static Mat4 rotation(float theta, const Vec3 &v);
static Mat4 rotation(const Quat &q);
static Mat4 transrot(const DQuat &q);
static Mat4 scale(const Vec3 &v);
Mat4 transpose(void) const;
Mat4 operator+(const Mat4 &rhs) const;
Mat4 operator-(const Mat4 &rhs) const;
Mat4 operator*(float rhs) const;
Mat4 operator/(float rhs) const;
Mat4 operator*(const Mat4 &rhs) const;
Vec4 operator*(const Vec4 &rhs) const;
Mat4 &operator+=(const Mat4 &rhs);
Mat4 &operator-=(const Mat4 &rhs);
Mat4 &operator*=(float rhs);
Mat4 &operator/=(float rhs);
Mat4 &operator*=(const Mat4 &rhs);
void print(std::ostream &of) const;
};
#endif

21
tests/gl/math/math.h Executable file
View File

@ -0,0 +1,21 @@
#ifndef MATH_H
#define MATH_H
#include "vec3.h"
#include "vec4.h"
#include "quat.h"
#include "dquat.h"
#include "mat3.h"
#include "mat4.h"
std::ostream &operator<<(std::ostream& of, const Vec3 &v);
std::ostream &operator<<(std::ostream& of, const Vec4 &v);
std::ostream &operator<<(std::ostream& of, const Quat &v);
std::ostream &operator<<(std::ostream& of, const DQuat &v);
std::ostream &operator<<(std::ostream& of, const Mat3 &v);
std::ostream &operator<<(std::ostream& of, const Mat4 &v);
#define PI 3.14159265359f
#endif

54
tests/gl/math/quat.h Executable file
View File

@ -0,0 +1,54 @@
#ifndef MATH_QUAT_H
#define MATH_QUAT_H
#include <iostream>
#include <cmath>
class Vec3;
class Vec4;
class Mat3;
/* Hamilton style */
class Quat {
public:
float w, x, y, z;
Quat(void);
Quat(float w);
Quat(float x, float y, float z);
Quat(float w, float x, float y, float z);
Quat(float w, const Vec3 &v);
Quat(const Vec3 &v);
Quat(const Vec4 &v);
Quat(const Mat3 &m);
float *ptr(void);
Quat operator-(void) const;
Quat operator+(const Quat &rhs) const;
Quat operator-(const Quat &rhs) const;
Quat operator*(const Quat &rhs) const;
Quat operator*(float rhs) const;
Quat operator/(float rhs) const;
Quat &operator+=(const Quat &rhs);
Quat &operator-=(const Quat &rhs);
Quat &operator*=(const Quat &rhs);
Quat &operator*=(float rhs);
Quat &operator/=(float rhs);
bool operator==(const Quat &rhs) const;
bool operator!=(const Quat &rhs) const;
Quat inv(void) const;
Quat K(void) const; /* conjugate */
Quat S(void) const; /* scalar */
Quat V(void) const; /* vector */
float T(void) const; /* tensor */
float N(void) const; /* norm = tensor^2 */
Quat U(void) const; /* versor */
Quat wedge(const Quat &rhs) const;
float inner(const Quat &rhs) const;
Quat lerp(const Quat &rhs, float t) const;
Quat slerp(const Quat &rhs, float t) const;
void print(std::ostream &of) const;
};
#endif

40
tests/gl/math/vec3.h Executable file
View File

@ -0,0 +1,40 @@
#ifndef MATH_VECTOR3_H
#define MATH_VECTOR3_H
#include <iostream>
#include <cmath>
class Vec4;
class Quat;
class Vec3 {
public:
float x, y, z;
Vec3(void);
Vec3(float x, float y, float z);
Vec3(float *v);
Vec3(const Vec4 &v);
Vec3(const Quat &q);
float *ptr(void);
Vec3 operator-(void) const;
Vec3 operator+(const Vec3 &rhs) const;
Vec3 operator-(const Vec3 &rhs) const;
Vec3 operator*(float rhs) const;
Vec3 operator/(float rhs) const;
Vec3 &operator+=(const Vec3 &rhs);
Vec3 &operator-=(const Vec3 &rhs);
Vec3 &operator*=(float rhs);
Vec3 &operator/=(float rhs);
bool operator==(const Vec3 &rhs) const;
bool operator!=(const Vec3 &rhs) const;
float norm(void) const;
float normsq(void) const;
Vec3 normalized(void) const;
float dot(const Vec3 &rhs) const;
Vec3 cross(const Vec3 &rhs) const;
void print(std::ostream &of) const;
};
#endif

39
tests/gl/math/vec4.h Executable file
View File

@ -0,0 +1,39 @@
#ifndef MATH_VECTOR4_H
#define MATH_VECTOR4_H
#include <iostream>
#include <cmath>
class Vec3;
class Quat;
class Vec4 {
public:
float x, y, z, w;
Vec4(void);
Vec4(float x, float y, float z, float w);
Vec4(float *v);
Vec4(const Vec3 &v, float w = 0.0f);
Vec4(const Quat &w);
float *ptr(void);
Vec4 operator-(void) const;
Vec4 operator+(const Vec4 &rhs) const;
Vec4 operator-(const Vec4 &rhs) const;
Vec4 operator*(float rhs) const;
Vec4 operator/(float rhs) const;
Vec4 &operator+=(const Vec4 &rhs);
Vec4 &operator-=(const Vec4 &rhs);
Vec4 &operator*=(float rhs);
Vec4 &operator/=(float rhs);
bool operator==(const Vec4 &rhs) const;
bool operator!=(const Vec4 &rhs) const;
float norm(void) const;
float normsq(void) const;
Vec4 normalized(void) const;
float dot(const Vec4 &rhs) const;
void print(std::ostream &of) const;
};
#endif

15
tests/gl/rwtest.h Executable file
View File

@ -0,0 +1,15 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <fstream>
#include "../librw/rw.h"
#include "../librw/src/gtaplg.h"
#include "math/math.h"
#include "camera.h"
#include "gl.h"