Added OpenGL test.
This commit is contained in:
parent
c0fab82c52
commit
fc40bbdffe
21
tests/gl/Makefile
Executable file
21
tests/gl/Makefile
Executable 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
20
tests/gl/Makefile.mingw
Executable 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
168
tests/gl/camera.cpp
Executable 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
37
tests/gl/camera.h
Executable 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
6
tests/gl/gl.h
Executable 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
61
tests/gl/glshader.cpp
Executable 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
341
tests/gl/main.cpp
Executable 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
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
93
tests/gl/math/conversion.h
Executable 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
45
tests/gl/math/dquat.h
Executable 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
43
tests/gl/math/mat3.h
Executable 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
52
tests/gl/math/mat4.h
Executable 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
21
tests/gl/math/math.h
Executable 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
54
tests/gl/math/quat.h
Executable 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
40
tests/gl/math/vec3.h
Executable 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
39
tests/gl/math/vec4.h
Executable 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
15
tests/gl/rwtest.h
Executable 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"
|
||||
|
Loading…
Reference in New Issue
Block a user