summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-07-18 19:08:34 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-07-18 19:08:34 +0200
commitf364f378cf497faf61d78aadd8f1aebce678c0ec (patch)
tree02de3c2415247a7856a02657b1eff9500b5d1e50 /src
parent68a7bafe37adef0e5ef12c2d0e8461a21e05363b (diff)
downloadcolobot-f364f378cf497faf61d78aadd8f1aebce678c0ec.tar.gz
colobot-f364f378cf497faf61d78aadd8f1aebce678c0ec.tar.bz2
colobot-f364f378cf497faf61d78aadd8f1aebce678c0ec.zip
Fixed OpenGL transformations
- fixed wrong order of transformations - added transform_test
Diffstat (limited to 'src')
-rw-r--r--src/graphics/opengl/gldevice.cpp10
-rw-r--r--src/graphics/opengl/test/CMakeLists.txt13
-rw-r--r--src/graphics/opengl/test/README.txt1
-rw-r--r--src/graphics/opengl/test/transform_test.cpp339
-rw-r--r--src/math/geometry.h2
5 files changed, 359 insertions, 6 deletions
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index e329ff4..b8f3bed 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -179,7 +179,7 @@ void Gfx::CGLDevice::BeginScene()
void Gfx::CGLDevice::EndScene()
{
- glFinish();
+ glFlush();
}
void Gfx::CGLDevice::Clear()
@@ -192,14 +192,14 @@ void Gfx::CGLDevice::SetTransform(Gfx::TransformType type, const Math::Matrix &m
if (type == Gfx::TRANSFORM_WORLD)
{
m_worldMat = matrix;
- m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
+ m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m_modelviewMat.Array());
}
else if (type == Gfx::TRANSFORM_VIEW)
{
m_viewMat = matrix;
- m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
+ m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m_modelviewMat.Array());
}
@@ -234,14 +234,14 @@ void Gfx::CGLDevice::MultiplyTransform(Gfx::TransformType type, const Math::Matr
if (type == Gfx::TRANSFORM_WORLD)
{
m_worldMat = Math::MultiplyMatrices(m_worldMat, matrix);
- m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
+ m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m_modelviewMat.Array());
}
else if (type == Gfx::TRANSFORM_VIEW)
{
m_viewMat = Math::MultiplyMatrices(m_viewMat, matrix);
- m_modelviewMat = Math::MultiplyMatrices(m_worldMat, m_viewMat);
+ m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m_modelviewMat.Array());
}
diff --git a/src/graphics/opengl/test/CMakeLists.txt b/src/graphics/opengl/test/CMakeLists.txt
index 4242c77..58c4714 100644
--- a/src/graphics/opengl/test/CMakeLists.txt
+++ b/src/graphics/opengl/test/CMakeLists.txt
@@ -48,6 +48,16 @@ set(MODEL_SOURCES
model_test.cpp
)
+set(TRANSFORM_SOURCES
+../gldevice.cpp
+../../common/device.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+../../../common/iman.cpp
+../../../app/system.cpp
+transform_test.cpp
+)
+
include_directories(../../../ ${CMAKE_CURRENT_BINARY_DIR})
set(LIBS
@@ -63,3 +73,6 @@ target_link_libraries(texture_test ${LIBS})
add_executable(model_test ${MODEL_SOURCES})
target_link_libraries(model_test ${LIBS})
+
+add_executable(transform_test ${TRANSFORM_SOURCES})
+target_link_libraries(transform_test ${LIBS})
diff --git a/src/graphics/opengl/test/README.txt b/src/graphics/opengl/test/README.txt
index c309f23..fe6f1d7 100644
--- a/src/graphics/opengl/test/README.txt
+++ b/src/graphics/opengl/test/README.txt
@@ -5,3 +5,4 @@ Test programs for OpenGL engine:
second argument is the loaded format (DXF or Colobot .mod files)
requires ./tex folder (or symlink) with Colobot textures
viewer is controlled from keyboard - the bindings can be found in code
+ - transform_test -> simple "walk around" test for world & view transformations
diff --git a/src/graphics/opengl/test/transform_test.cpp b/src/graphics/opengl/test/transform_test.cpp
new file mode 100644
index 0000000..5982c4e
--- /dev/null
+++ b/src/graphics/opengl/test/transform_test.cpp
@@ -0,0 +1,339 @@
+#include "app/system.h"
+#include "common/logger.h"
+#include "common/image.h"
+#include "common/iman.h"
+#include "graphics/opengl/gldevice.h"
+#include "math/geometry.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <map>
+
+enum KeySlots
+{
+ K_Forward,
+ K_Back,
+ K_Left,
+ K_Right,
+ K_Up,
+ K_Down,
+ K_Count
+};
+bool KEYMAP[K_Count] = { false };
+
+Math::Point MOUSE_POS_BASE;
+
+Math::Vector TRANSLATION(0.0f, 2.0f, 0.0f);
+Math::Vector ROTATION, ROTATION_BASE;
+
+const int FRAME_DELAY = 5000;
+
+SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL;
+
+void Init(Gfx::CGLDevice *device)
+{
+ device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true);
+ device->SetShadeModel(Gfx::SHADE_SMOOTH);
+}
+
+void Render(Gfx::CGLDevice *device)
+{
+ device->BeginScene();
+
+ Math::Matrix persp;
+ Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (600.0f) / (800.0f), 0.1f, 100.0f);
+ device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);
+
+
+ Math::Matrix viewMat;
+ Math::Matrix mat;
+
+ viewMat.LoadIdentity();
+
+ Math::LoadRotationXMatrix(mat, -ROTATION.x);
+ viewMat = Math::MultiplyMatrices(viewMat, mat);
+
+ Math::LoadRotationYMatrix(mat, -ROTATION.y);
+ viewMat = Math::MultiplyMatrices(viewMat, mat);
+
+ Math::LoadTranslationMatrix(mat, -TRANSLATION);
+ viewMat = Math::MultiplyMatrices(viewMat, mat);
+
+ device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat);
+
+
+ Math::Matrix worldMat;
+ worldMat.LoadIdentity();
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ Gfx::VertexCol line[2] = { Gfx::VertexCol() };
+
+ for (int x = -40; x <= 40; ++x)
+ {
+ line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
+ line[0].coord.z = -40;
+ line[0].coord.x = x;
+ line[1].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
+ line[1].coord.z = 40;
+ line[1].coord.x = x;
+ device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
+ }
+
+ for (int z = -40; z <= 40; ++z)
+ {
+ line[0].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
+ line[0].coord.z = z;
+ line[0].coord.x = -40;
+ line[1].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
+ line[1].coord.z = z;
+ line[1].coord.x = 40;
+ device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
+ }
+
+
+ Gfx::VertexCol quad[6] = { Gfx::VertexCol() };
+
+ for (int i = 0; i < 6; ++i)
+ quad[i].color = Gfx::Color(1.0f, 1.0f, 0.0f);
+
+ quad[0].coord = Math::Vector(-1.0f, -1.0f, 0.0f);
+ quad[1].coord = Math::Vector( 1.0f, -1.0f, 0.0f);
+ quad[2].coord = Math::Vector( 1.0f, 1.0f, 0.0f);
+ quad[3].coord = Math::Vector( 1.0f, 1.0f, 0.0f);
+ quad[4].coord = Math::Vector(-1.0f, 1.0f, 0.0f);
+ quad[5].coord = Math::Vector(-1.0f, -1.0f, 0.0f);
+
+ Math::LoadTranslationMatrix(worldMat, Math::Vector(40.0f, 2.0f, 40.0f));
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ for (int i = 0; i < 6; ++i)
+ quad[i].color = Gfx::Color(0.0f, 1.0f, 1.0f);
+
+ Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f));
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ for (int i = 0; i < 6; ++i)
+ quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f);
+
+ Math::LoadTranslationMatrix(worldMat, Math::Vector(0.0f, 10.0f, 0.0f));
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ device->EndScene();
+}
+
+void Update()
+{
+ const float TRANS_SPEED = 6.0f; // units / sec
+
+ GetCurrentTimeStamp(CURR_TIME);
+ float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
+ CopyTimeStamp(PREV_TIME, CURR_TIME);
+
+ Math::Vector incTrans;
+
+ if (KEYMAP[K_Forward])
+ incTrans.z = +TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Back])
+ incTrans.z = -TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Right])
+ incTrans.x = +TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Left])
+ incTrans.x = -TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Up])
+ incTrans.y = +TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Down])
+ incTrans.y = -TRANS_SPEED * timeDiff;
+
+ Math::Point rotTrans = Math::RotatePoint(-ROTATION.y, Math::Point(incTrans.x, incTrans.z));
+ incTrans.x = rotTrans.x;
+ incTrans.z = rotTrans.y;
+ TRANSLATION += incTrans;
+}
+
+void KeyboardDown(SDLKey key)
+{
+ switch (key)
+ {
+ case SDLK_w:
+ KEYMAP[K_Forward] = true;
+ break;
+ case SDLK_s:
+ KEYMAP[K_Back] = true;
+ break;
+ case SDLK_d:
+ KEYMAP[K_Right] = true;
+ break;
+ case SDLK_a:
+ KEYMAP[K_Left] = true;
+ break;
+ case SDLK_z:
+ KEYMAP[K_Down] = true;
+ break;
+ case SDLK_x:
+ KEYMAP[K_Up] = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void KeyboardUp(SDLKey key)
+{
+ switch (key)
+ {
+ case SDLK_w:
+ KEYMAP[K_Forward] = false;
+ break;
+ case SDLK_s:
+ KEYMAP[K_Back] = false;
+ break;
+ case SDLK_d:
+ KEYMAP[K_Right] = false;
+ break;
+ case SDLK_a:
+ KEYMAP[K_Left] = false;
+ break;
+ case SDLK_z:
+ KEYMAP[K_Down] = false;
+ break;
+ case SDLK_x:
+ KEYMAP[K_Up] = false;
+ break;
+ default:
+ break;
+ }
+}
+
+void MouseMove(int x, int y)
+{
+ Math::Point currentPos((float)x, (float)y);
+
+ static bool first = true;
+ if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590))
+ {
+ SDL_WarpMouse(400, 300);
+ MOUSE_POS_BASE.x = 400;
+ MOUSE_POS_BASE.y = 300;
+ ROTATION_BASE = ROTATION;
+ first = false;
+ return;
+ }
+
+ ROTATION.y = ROTATION_BASE.y + ((float) (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI;
+ ROTATION.x = ROTATION_BASE.x + ((float) (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI;
+}
+
+int main(int argc, char *argv[])
+{
+ CLogger logger;
+
+ PREV_TIME = CreateTimeStamp();
+ CURR_TIME = CreateTimeStamp();
+
+ GetCurrentTimeStamp(PREV_TIME);
+ GetCurrentTimeStamp(CURR_TIME);
+
+ CInstanceManager iMan;
+
+ // Without any error checking, for simplicity
+
+ SDL_Init(SDL_INIT_VIDEO);
+
+ IMG_Init(IMG_INIT_PNG);
+
+ const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
+
+ Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE;
+
+ if (videoInfo->hw_available)
+ videoFlags |= SDL_HWSURFACE;
+ else
+ videoFlags |= SDL_SWSURFACE;
+
+ if (videoInfo->blit_hw)
+ videoFlags |= SDL_HWACCEL;
+
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8);
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags);
+
+
+ SDL_WM_SetCaption("Transform Test", "Transform Test");
+
+ //SDL_WM_GrabInput(SDL_GRAB_ON);
+ SDL_ShowCursor(SDL_DISABLE);
+
+ Gfx::CGLDevice *device = new Gfx::CGLDevice();
+ device->Create();
+
+ Init(device);
+
+ bool done = false;
+ while (! done)
+ {
+ Render(device);
+ Update();
+
+ SDL_GL_SwapBuffers();
+
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ if (event.type == SDL_QUIT)
+ {
+ break;
+ done = true;
+ }
+ else if (event.type == SDL_KEYDOWN)
+ {
+ if (event.key.keysym.sym == SDLK_q)
+ {
+ done = true;
+ break;
+ }
+ else
+ KeyboardDown(event.key.keysym.sym);
+ }
+ else if (event.type == SDL_KEYUP)
+ KeyboardUp(event.key.keysym.sym);
+ else if (event.type == SDL_MOUSEMOTION)
+ MouseMove(event.motion.x, event.motion.y);
+ }
+
+ usleep(FRAME_DELAY);
+ }
+
+ //SDL_WM_GrabInput(SDL_GRAB_OFF);
+ SDL_ShowCursor(SDL_ENABLE);
+
+ device->Destroy();
+ delete device;
+
+ SDL_FreeSurface(surface);
+
+ IMG_Quit();
+
+ SDL_Quit();
+
+ DestroyTimeStamp(PREV_TIME);
+ DestroyTimeStamp(CURR_TIME);
+
+ return 0;
+}
diff --git a/src/math/geometry.h b/src/math/geometry.h
index e56ff10..8954655 100644
--- a/src/math/geometry.h
+++ b/src/math/geometry.h
@@ -284,7 +284,7 @@ inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from,
//! Loads a perspective projection matrix
/** \a fov field of view in radians
- \a aspect aspect ratio (width / height)
+ \a aspect aspect ratio (height / width)
\a nearPlane distance to near cut plane
\a farPlane distance to far cut plane */
inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = 1.570795f, float aspect = 1.0f,