summaryrefslogtreecommitdiffstats
path: root/src/graphics/opengl/test
diff options
context:
space:
mode:
authorerihel <erihel@gmail.com>2012-08-09 20:20:47 +0200
committererihel <erihel@gmail.com>2012-08-09 20:20:47 +0200
commit611680a72e0f04e080c3b7ed59bd23d5b8b709f1 (patch)
treee27ba7ba84de26777d275969993d46d904eb37e7 /src/graphics/opengl/test
parentd56db5f4e4a8e0d572bf3d682619bb25aebe4120 (diff)
parentbc24b9f9e516e657fcc0034808e010287fc2e393 (diff)
downloadcolobot-611680a72e0f04e080c3b7ed59bd23d5b8b709f1.tar.gz
colobot-611680a72e0f04e080c3b7ed59bd23d5b8b709f1.tar.bz2
colobot-611680a72e0f04e080c3b7ed59bd23d5b8b709f1.zip
Merge branch 'dev' of https://github.com/adiblol/colobot into dev
Conflicts: src/sound/sound.h
Diffstat (limited to 'src/graphics/opengl/test')
-rw-r--r--src/graphics/opengl/test/CMakeLists.txt87
-rw-r--r--src/graphics/opengl/test/README.txt9
-rw-r--r--src/graphics/opengl/test/light_test.cpp437
-rw-r--r--src/graphics/opengl/test/model_test.cpp377
-rw-r--r--src/graphics/opengl/test/tex1.pngbin0 -> 151263 bytes
-rw-r--r--src/graphics/opengl/test/tex2.pngbin0 -> 57503 bytes
-rw-r--r--src/graphics/opengl/test/texture_test.cpp193
-rw-r--r--src/graphics/opengl/test/transform_test.cpp339
8 files changed, 1442 insertions, 0 deletions
diff --git a/src/graphics/opengl/test/CMakeLists.txt b/src/graphics/opengl/test/CMakeLists.txt
new file mode 100644
index 0000000..8ed7364
--- /dev/null
+++ b/src/graphics/opengl/test/CMakeLists.txt
@@ -0,0 +1,87 @@
+cmake_minimum_required(VERSION 2.8)
+
+find_package(OpenGL REQUIRED)
+find_package(SDL REQUIRED)
+find_package(SDL_image REQUIRED)
+find_package(PNG REQUIRED)
+
+set(CMAKE_BUILD_TYPE debug)
+set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0")
+
+set(ADD_LIBS "")
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ set(PLATFORM_WINDOWS 1)
+ set(PLATFORM_LINUX 0)
+ set(PLATFORM_OTHER 0)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ set(PLATFORM_WINDOWS 0)
+ set(PLATFORM_LINUX 1)
+ set(PLATFORM_OTHER 0)
+ set(ADD_LIBS "-lrt")
+else()
+ set(PLATFORM_WINDOWS 0)
+ set(PLATFORM_LINUX 0)
+ set(PLATFORM_OTHER 1)
+endif()
+
+configure_file(../../../common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h)
+
+
+set(TEXTURE_SOURCES
+../gldevice.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+texture_test.cpp
+)
+
+set(MODEL_SOURCES
+../gldevice.cpp
+../../engine/modelfile.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+../../../common/iman.cpp
+../../../common/stringutils.cpp
+../../../app/system.cpp
+model_test.cpp
+)
+
+set(TRANSFORM_SOURCES
+../gldevice.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+../../../common/iman.cpp
+../../../app/system.cpp
+transform_test.cpp
+)
+
+set(LIGHT_SOURCES
+../gldevice.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+../../../common/iman.cpp
+../../../app/system.cpp
+light_test.cpp
+)
+
+include_directories(../../../ ${CMAKE_CURRENT_BINARY_DIR})
+
+set(LIBS
+${SDL_LIBRARY}
+${SDLIMAGE_LIBRARY}
+${OPENGL_LIBRARY}
+${PNG_LIBRARIES}
+${ADD_LIBS}
+)
+
+add_executable(texture_test ${TEXTURE_SOURCES})
+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})
+
+add_executable(light_test ${LIGHT_SOURCES})
+target_link_libraries(light_test ${LIBS})
diff --git a/src/graphics/opengl/test/README.txt b/src/graphics/opengl/test/README.txt
new file mode 100644
index 0000000..c618415
--- /dev/null
+++ b/src/graphics/opengl/test/README.txt
@@ -0,0 +1,9 @@
+Test programs for OpenGL engine:
+ - texture_test -> multitexturing test with 2 textures (included as files: ./tex1.png, ./tex2.png)
+ - model_test -> simple model viewer to test model loading
+ usage: ./model_test {dxf|mod} model_file
+ 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
+ - light test -> test for lighting
diff --git a/src/graphics/opengl/test/light_test.cpp b/src/graphics/opengl/test/light_test.cpp
new file mode 100644
index 0000000..80fa911
--- /dev/null
+++ b/src/graphics/opengl/test/light_test.cpp
@@ -0,0 +1,437 @@
+#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;
+
+float CUBE_ORBIT = 0.0f;
+
+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();
+
+ /* Unlit part of scene */
+
+ device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false);
+ device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); // Double-sided drawing
+
+ Math::Matrix persp;
+ Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.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() };
+
+ 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);
+
+ for (int i = 0; i < 6; ++i)
+ quad[i].color = Gfx::Color(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_TRIANGLE_STRIP, quad, 4);
+
+ 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_TRIANGLE_STRIP, quad, 4);
+
+ for (int i = 0; i < 6; ++i)
+ quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f);
+
+ Math::LoadTranslationMatrix(worldMat, Math::Vector(10.0f, 4.5f, 5.0f));
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+
+ /* Moving lit cube */
+ device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true);
+ device->SetRenderState(Gfx::RENDER_STATE_CULLING, true); // Culling (CCW faces)
+
+ device->SetGlobalAmbient(Gfx::Color(0.4f, 0.4f, 0.4f));
+
+ Gfx::Light light1;
+ light1.type = Gfx::LIGHT_POINT;
+ light1.position = Math::Vector(10.0f, 4.5f, 5.0f);
+ light1.ambient = Gfx::Color(0.2f, 0.2f, 0.2f);
+ light1.diffuse = Gfx::Color(1.0f, 0.1f, 0.1f);
+ light1.specular = Gfx::Color(0.0f, 0.0f, 0.0f);
+ device->SetLight(0, light1);
+ device->SetLightEnabled(0, true);
+
+ /*Gfx::Light light2;
+ device->SetLight(1, light2);
+ device->SetLightEnabled(1, true);*/
+
+ Gfx::Material material;
+ material.ambient = Gfx::Color(0.3f, 0.3f, 0.3f);
+ material.diffuse = Gfx::Color(0.8f, 0.7f, 0.6f);
+ material.specular = Gfx::Color(0.0f, 0.0f, 0.0f);
+ device->SetMaterial(material);
+
+ const Gfx::Vertex cube[6][4] =
+ {
+ {
+ // Front
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f))
+ },
+
+ {
+ // Back
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f))
+ },
+
+ {
+ // Top
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 1.0f, 0.0f))
+ },
+
+ {
+ // Bottom
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f, 0.0f))
+ },
+
+ {
+ // Left
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector(-1.0f, 0.0f, 0.0f))
+ },
+
+ {
+ // Right
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 1.0f, 0.0f, 0.0f))
+ }
+ };
+
+ Math::Matrix cubeTrans;
+ Math::LoadTranslationMatrix(cubeTrans, Math::Vector(10.0f, 2.0f, 5.0f));
+ Math::Matrix cubeRot;
+ Math::LoadRotationMatrix(cubeRot, Math::Vector(0.0f, 1.0f, 0.0f), CUBE_ORBIT);
+ Math::Matrix cubeRotInv;
+ Math::LoadRotationMatrix(cubeRotInv, Math::Vector(0.0f, 1.0f, 0.0f), -CUBE_ORBIT);
+ Math::Matrix cubeTransRad;
+ Math::LoadTranslationMatrix(cubeTransRad, Math::Vector(0.0f, 0.0f, 6.0f));
+ worldMat = Math::MultiplyMatrices(cubeTransRad, cubeRotInv);
+ worldMat = Math::MultiplyMatrices(cubeRot, worldMat);
+ worldMat = Math::MultiplyMatrices(cubeTrans, worldMat);
+ device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);
+
+ for (int i = 0; i < 6; ++i)
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, cube[i], 4);
+
+ 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);
+
+ CUBE_ORBIT += timeDiff * (Math::PI / 4.0f);
+
+ 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("Light Test", "Light 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/graphics/opengl/test/model_test.cpp b/src/graphics/opengl/test/model_test.cpp
new file mode 100644
index 0000000..3e8efe6
--- /dev/null
+++ b/src/graphics/opengl/test/model_test.cpp
@@ -0,0 +1,377 @@
+#include "app/system.h"
+#include "common/logger.h"
+#include "common/image.h"
+#include "common/iman.h"
+#include "graphics/engine/modelfile.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_RotXUp,
+ K_RotXDown,
+ K_RotYLeft,
+ K_RotYRight,
+ K_Forward,
+ K_Back,
+ K_Left,
+ K_Right,
+ K_Up,
+ K_Down,
+ K_Count
+};
+bool KEYMAP[K_Count] = { false };
+
+Math::Vector TRANSLATION(0.0f, 0.0f, 30.0f);
+Math::Vector ROTATION;
+
+const int FRAME_DELAY = 5000;
+
+std::map<std::string, Gfx::Texture> TEXS;
+
+SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL;
+
+Gfx::Texture GetTexture(const std::string &name)
+{
+ std::map<std::string, Gfx::Texture>::iterator it = TEXS.find(name);
+ if (it == TEXS.end())
+ return Gfx::Texture();
+
+ return (*it).second;
+}
+
+void LoadTexture(Gfx::CGLDevice *device, const std::string &name)
+{
+ if (name.empty())
+ return;
+
+ Gfx::Texture tex = GetTexture(name);
+
+ if (tex.valid)
+ return;
+
+ CImage img;
+ if (! img.Load(std::string("tex/") + name))
+ {
+ std::string err = img.GetError();
+ GetLogger()->Error("Texture not loaded, error: %s!\n", err.c_str());
+ }
+ else
+ {
+ Gfx::TextureCreateParams texCreateParams;
+ texCreateParams.mipmap = true;
+ if (img.GetData()->surface->format->Amask == 0)
+ texCreateParams.format = Gfx::TEX_IMG_BGR;
+ else
+ texCreateParams.format = Gfx::TEX_IMG_BGRA;
+ texCreateParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
+ texCreateParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR;
+
+ tex = device->CreateTexture(&img, texCreateParams);
+ }
+
+ TEXS[name] = tex;
+}
+
+void Init(Gfx::CGLDevice *device, Gfx::CModelFile *model)
+{
+ std::vector<Gfx::ModelTriangle> &triangles = model->GetTriangles();
+
+ for (int i = 0; i < (int) triangles.size(); ++i)
+ {
+ LoadTexture(device, triangles[i].tex1Name);
+ LoadTexture(device, triangles[i].tex2Name);
+ }
+
+ device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
+ device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true);
+ device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true);
+ device->SetShadeModel(Gfx::SHADE_SMOOTH);
+
+ Gfx::Light light;
+ light.type = Gfx::LIGHT_DIRECTIONAL;
+ light.ambient = Gfx::Color(0.4f, 0.4f, 0.4f, 0.0f);
+ light.diffuse = Gfx::Color(0.8f, 0.8f, 0.8f, 0.0f);
+ light.specular = Gfx::Color(0.2f, 0.2f, 0.2f, 0.0f);
+ light.position = Math::Vector(0.0f, 0.0f, -1.0f);
+ light.direction = Math::Vector(0.0f, 0.0f, 1.0f);
+
+ device->SetGlobalAmbient(Gfx::Color(0.5f, 0.5f, 0.5f, 0.0f));
+ device->SetLight(0, light);
+ device->SetLightEnabled(0, true);
+}
+
+void Render(Gfx::CGLDevice *device, Gfx::CModelFile *modelFile)
+{
+ device->BeginScene();
+
+ Math::Matrix persp;
+ Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f);
+ device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);
+
+ Math::Matrix id;
+ id.LoadIdentity();
+ device->SetTransform(Gfx::TRANSFORM_WORLD, id);
+
+ Math::Matrix viewMat;
+ Math::LoadTranslationMatrix(viewMat, TRANSLATION);
+ Math::Matrix rot;
+ Math::LoadRotationXZYMatrix(rot, ROTATION);
+ viewMat = Math::MultiplyMatrices(viewMat, rot);
+ device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat);
+
+ std::vector<Gfx::ModelTriangle> &triangles = modelFile->GetTriangles();
+
+ Gfx::VertexTex2 tri[3];
+
+ for (int i = 0; i < (int) triangles.size(); ++i)
+ {
+ device->SetTexture(0, GetTexture(triangles[i].tex1Name));
+ device->SetTexture(1, GetTexture(triangles[i].tex2Name));
+ device->SetTextureEnabled(0, true);
+ device->SetTextureEnabled(1, true);
+
+ device->SetMaterial(triangles[i].material);
+
+ tri[0] = triangles[i].p1;
+ tri[1] = triangles[i].p2;
+ tri[2] = triangles[i].p3;
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, tri, 3);
+ }
+
+ device->EndScene();
+}
+
+void Update()
+{
+ const float ROT_SPEED = 80.0f * Math::DEG_TO_RAD; // rad / sec
+ const float TRANS_SPEED = 3.0f; // units / sec
+
+ GetCurrentTimeStamp(CURR_TIME);
+ float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
+ CopyTimeStamp(PREV_TIME, CURR_TIME);
+
+ if (KEYMAP[K_RotYLeft])
+ ROTATION.y -= ROT_SPEED * timeDiff;
+ if (KEYMAP[K_RotYRight])
+ ROTATION.y += ROT_SPEED * timeDiff;
+ if (KEYMAP[K_RotXDown])
+ ROTATION.x -= ROT_SPEED * timeDiff;
+ if (KEYMAP[K_RotXUp])
+ ROTATION.x += ROT_SPEED * timeDiff;
+
+ if (KEYMAP[K_Forward])
+ TRANSLATION.z -= TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Back])
+ TRANSLATION.z += TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Left])
+ TRANSLATION.x += TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Right])
+ TRANSLATION.x -= TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Up])
+ TRANSLATION.y += TRANS_SPEED * timeDiff;
+ if (KEYMAP[K_Down])
+ TRANSLATION.y -= TRANS_SPEED * timeDiff;
+}
+
+void KeyboardDown(SDLKey key)
+{
+ switch (key)
+ {
+ case SDLK_LEFT:
+ KEYMAP[K_RotYLeft] = true;
+ break;
+ case SDLK_RIGHT:
+ KEYMAP[K_RotYRight] = true;
+ break;
+ case SDLK_UP:
+ KEYMAP[K_RotXUp] = true;
+ break;
+ case SDLK_DOWN:
+ KEYMAP[K_RotXDown] = true;
+ break;
+ case SDLK_w:
+ KEYMAP[K_Forward] = true;
+ break;
+ case SDLK_s:
+ KEYMAP[K_Back] = true;
+ break;
+ case SDLK_a:
+ KEYMAP[K_Left] = true;
+ break;
+ case SDLK_d:
+ KEYMAP[K_Right] = 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_LEFT:
+ KEYMAP[K_RotYLeft] = false;
+ break;
+ case SDLK_RIGHT:
+ KEYMAP[K_RotYRight] = false;
+ break;
+ case SDLK_UP:
+ KEYMAP[K_RotXUp] = false;
+ break;
+ case SDLK_DOWN:
+ KEYMAP[K_RotXDown] = false;
+ break;
+ case SDLK_w:
+ KEYMAP[K_Forward] = false;
+ break;
+ case SDLK_s:
+ KEYMAP[K_Back] = false;
+ break;
+ case SDLK_a:
+ KEYMAP[K_Left] = false;
+ break;
+ case SDLK_d:
+ KEYMAP[K_Right] = false;
+ break;
+ case SDLK_z:
+ KEYMAP[K_Down] = false;
+ break;
+ case SDLK_x:
+ KEYMAP[K_Up] = false;
+ break;
+ default:
+ break;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ CLogger logger;
+
+ PREV_TIME = CreateTimeStamp();
+ CURR_TIME = CreateTimeStamp();
+
+ GetCurrentTimeStamp(PREV_TIME);
+ GetCurrentTimeStamp(CURR_TIME);
+
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << "{mod|dxf} model_file" << std::endl;
+ return 1;
+ }
+
+ CInstanceManager iMan;
+
+ Gfx::CModelFile *modelFile = new Gfx::CModelFile(&iMan);
+ if (std::string(argv[1]) == "mod")
+ {
+ if (! modelFile->ReadModel(argv[2], false, false))
+ {
+ std::cerr << "Error reading MOD: " << modelFile->GetError() << std::endl;
+ return 1;
+ }
+ }
+ else if (std::string(argv[1]) == "dxf")
+ {
+ if (! modelFile->ReadDXF(argv[2], 0.0f, 0.0f))
+ {
+ std::cerr << "Error reading DXF: " << modelFile->GetError() << std::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ std::cerr << "Usage: " << argv[0] << "{mod|dxf} model_file" << std::endl;
+ return 1;
+ }
+
+ // 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("Model Test", "Model Test");
+
+ Gfx::CGLDevice *device = new Gfx::CGLDevice();
+ device->Create();
+
+ Init(device, modelFile);
+
+ bool done = false;
+ while (! done)
+ {
+ Render(device, modelFile);
+ Update();
+
+ SDL_GL_SwapBuffers();
+
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ if (event.type == SDL_QUIT)
+ done = true;
+ else if (event.type == SDL_KEYDOWN)
+ KeyboardDown(event.key.keysym.sym);
+ else if (event.type == SDL_KEYUP)
+ KeyboardUp(event.key.keysym.sym);
+
+ usleep(FRAME_DELAY);
+ }
+
+ delete modelFile;
+
+ device->Destroy();
+ delete device;
+
+ SDL_FreeSurface(surface);
+
+ IMG_Quit();
+
+ SDL_Quit();
+
+ DestroyTimeStamp(PREV_TIME);
+ DestroyTimeStamp(CURR_TIME);
+
+ return 0;
+}
diff --git a/src/graphics/opengl/test/tex1.png b/src/graphics/opengl/test/tex1.png
new file mode 100644
index 0000000..46c68a0
--- /dev/null
+++ b/src/graphics/opengl/test/tex1.png
Binary files differ
diff --git a/src/graphics/opengl/test/tex2.png b/src/graphics/opengl/test/tex2.png
new file mode 100644
index 0000000..ebdae0d
--- /dev/null
+++ b/src/graphics/opengl/test/tex2.png
Binary files differ
diff --git a/src/graphics/opengl/test/texture_test.cpp b/src/graphics/opengl/test/texture_test.cpp
new file mode 100644
index 0000000..c3c568b
--- /dev/null
+++ b/src/graphics/opengl/test/texture_test.cpp
@@ -0,0 +1,193 @@
+#include "common/logger.h"
+#include "common/image.h"
+#include "graphics/opengl/gldevice.h"
+#include "math/geometry.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <unistd.h>
+
+
+void Init(Gfx::CGLDevice *device)
+{
+ device->SetShadeModel(Gfx::SHADE_SMOOTH);
+
+ device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
+ device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
+
+ device->SetTextureEnabled(0, true);
+ device->SetTextureEnabled(1, true);
+
+ CImage img1;
+ if (! img1.Load("tex1.png"))
+ {
+ std::string err = img1.GetError();
+ GetLogger()->Error("texture 1 not loaded, error: %d!\n", err.c_str());
+ }
+ CImage img2;
+ if (! img2.Load("tex2.png"))
+ {
+ std::string err = img2.GetError();
+ GetLogger()->Error("texture 2 not loaded, error: %d!\n", err.c_str());
+ }
+
+ Gfx::TextureCreateParams tex1CreateParams;
+ tex1CreateParams.mipmap = true;
+ tex1CreateParams.format = Gfx::TEX_IMG_RGBA;
+ tex1CreateParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
+ tex1CreateParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR;
+
+ Gfx::TextureCreateParams tex2CreateParams;
+ tex2CreateParams.mipmap = true;
+ tex2CreateParams.format = Gfx::TEX_IMG_RGBA;
+ tex2CreateParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST;
+ tex2CreateParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
+
+ Gfx::Texture tex1 = device->CreateTexture(&img1, tex1CreateParams);
+ Gfx::Texture tex2 = device->CreateTexture(&img2, tex2CreateParams);
+
+ device->SetTexture(0, tex1);
+ device->SetTexture(1, tex2);
+}
+
+void Render(Gfx::CGLDevice *device)
+{
+ device->BeginScene();
+
+ Math::Matrix ortho;
+ Math::LoadOrthoProjectionMatrix(ortho, -10, 10, -10, 10);
+ device->SetTransform(Gfx::TRANSFORM_PROJECTION, ortho);
+
+ Math::Matrix id;
+ id.LoadIdentity();
+
+ device->SetTransform(Gfx::TRANSFORM_WORLD, id);
+ device->SetTransform(Gfx::TRANSFORM_VIEW, id);
+
+ static Gfx::VertexTex2 quad[] =
+ {
+ Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
+ Gfx::VertexTex2(Math::Vector( 2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 0.0f), Math::Point(1.0f, 0.0f)),
+ Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
+
+ Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
+ Gfx::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)),
+ Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
+ };
+
+ Gfx::TextureStageParams tex1StageParams;
+ tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ device->SetTextureStageParams(0, tex1StageParams);
+
+ Gfx::TextureStageParams tex2StageParams;
+ tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ device->SetTextureStageParams(1, tex2StageParams);
+
+ Math::Matrix t;
+ Math::LoadTranslationMatrix(t, Math::Vector(-4.0f, 4.0f, 0.0f));
+ device->SetTransform(Gfx::TRANSFORM_VIEW, t);
+
+ device->SetTextureEnabled(0, true);
+ device->SetTextureEnabled(1, false);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ Math::LoadTranslationMatrix(t, Math::Vector( 4.0f, 4.0f, 0.0f));
+ device->SetTransform(Gfx::TRANSFORM_VIEW, t);
+
+ device->SetTextureEnabled(0, false);
+ device->SetTextureEnabled(1, true);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ Math::LoadTranslationMatrix(t, Math::Vector( 0.0f, -4.0f, 0.0f));
+ device->SetTransform(Gfx::TRANSFORM_VIEW, t);
+
+ device->SetTextureEnabled(0, true);
+ device->SetTextureEnabled(1, true);
+
+ tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ device->SetTextureStageParams(0, tex1StageParams);
+
+ tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_ADD;
+ tex2StageParams.colorArg1 = Gfx::TEX_MIX_ARG_COMPUTED_COLOR;
+ tex2StageParams.colorArg2 = Gfx::TEX_MIX_ARG_TEXTURE;
+ tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
+ device->SetTextureStageParams(1, tex2StageParams);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ device->EndScene();
+}
+
+int main()
+{
+ CLogger();
+
+ // 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("Texture Test", "Texture Test");
+
+ Gfx::CGLDevice *device = new Gfx::CGLDevice();
+ device->Create();
+
+ Init(device);
+
+ bool done = false;
+ while (! done)
+ {
+ Render(device);
+
+ SDL_GL_SwapBuffers();
+
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ if (event.type == SDL_QUIT)
+ done = true;
+
+ usleep(10000);
+ }
+
+ device->Destroy();
+ delete device;
+
+ SDL_FreeSurface(surface);
+
+ IMG_Quit();
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/src/graphics/opengl/test/transform_test.cpp b/src/graphics/opengl/test/transform_test.cpp
new file mode 100644
index 0000000..83819b8
--- /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, (800.0f) / (600.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;
+}