summaryrefslogtreecommitdiffstats
path: root/src/graphics/opengl
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-07-05 23:47:29 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-07-05 23:47:29 +0200
commite8c9945e13fca88a6f8232838682df0654437f3e (patch)
tree2a0974afe8cdb30d7862e189d4d9adc5d6d59849 /src/graphics/opengl
parentaf3057df7eb41973349b407539846f17d9094c21 (diff)
downloadcolobot-e8c9945e13fca88a6f8232838682df0654437f3e.tar.gz
colobot-e8c9945e13fca88a6f8232838682df0654437f3e.tar.bz2
colobot-e8c9945e13fca88a6f8232838682df0654437f3e.zip
Fixed bug with texturing
- moved creation-time tex params to Gfx::TextureCreateParams - fixed bug with texture creation - added simple test for multitexturing
Diffstat (limited to 'src/graphics/opengl')
-rw-r--r--src/graphics/opengl/gldevice.cpp192
-rw-r--r--src/graphics/opengl/gldevice.h5
-rw-r--r--src/graphics/opengl/test/CMakeLists.txt31
-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.cpp365
6 files changed, 494 insertions, 99 deletions
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index c6e91e1..3182dfc 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -105,14 +105,14 @@ bool Gfx::CGLDevice::Create()
return false;
}
- m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
+ /*m_private->glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
m_private->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
if ((m_private->glMultiTexCoord2fARB == NULL) || (m_private->glActiveTextureARB == NULL))
{
m_error = "Could not load extension functions, even though they seem supported";
return false;
- }
+ }*/
m_wasInit = true;
@@ -144,8 +144,8 @@ bool Gfx::CGLDevice::Create()
void Gfx::CGLDevice::Destroy()
{
- m_private->glMultiTexCoord2fARB = NULL;
- m_private->glActiveTextureARB = NULL;
+ /*m_private->glMultiTexCoord2fARB = NULL;
+ m_private->glActiveTextureARB = NULL;*/
// Delete the remaining textures
// Should not be strictly necessary, but just in case
@@ -328,41 +328,83 @@ bool Gfx::CGLDevice::GetLightEnabled(int index)
return m_lightsEnabled[index];
}
-Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, bool alpha, bool mipMap)
+/** If image is invalid, returns NULL.
+ Otherwise, returns pointer to new Gfx::Texture struct.
+ This struct must not be deleted in other way than through DeleteTexture() */
+Gfx::Texture* Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
{
+ ImageData *data = image->GetData();
+ if (data == NULL)
+ return NULL;
+
Gfx::Texture *result = new Gfx::Texture();
+ result->valid = true;
- // Texturing must be enabled, so enable 1st texture stage
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB);
+ // Use & enable 1st texture stage
+ glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
glGenTextures(1, &result->id);
glBindTexture(GL_TEXTURE_2D, result->id);
+ // Set params
+
+ GLint minF = 0;
+ if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST) minF = GL_NEAREST;
+ else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR) minF = GL_LINEAR;
+ else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST) minF = GL_NEAREST_MIPMAP_NEAREST;
+ else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_NEAREST) minF = GL_LINEAR_MIPMAP_NEAREST;
+ else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_LINEAR) minF = GL_NEAREST_MIPMAP_LINEAR;
+ else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR) minF = GL_LINEAR_MIPMAP_LINEAR;
+ else assert(false);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minF);
+
+ GLint magF = 0;
+ if (params.magFilter == Gfx::TEX_MAG_FILTER_NEAREST) magF = GL_NEAREST;
+ else if (params.magFilter == Gfx::TEX_MAG_FILTER_LINEAR) magF = GL_LINEAR;
+ else assert(false);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magF);
+
+ if (params.wrapS == Gfx::TEX_WRAP_CLAMP)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ else if (params.wrapS == Gfx::TEX_WRAP_REPEAT)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ else assert(false);
+
+ if (params.wrapT == Gfx::TEX_WRAP_CLAMP)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ else if (params.wrapT == Gfx::TEX_WRAP_REPEAT)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ else assert(false);
+
+
+ if (params.mipmap)
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
+
GLenum sourceFormat = 0;
- if (alpha)
+ if (params.alpha)
sourceFormat = GL_RGBA;
else
sourceFormat = GL_RGB;
- ImageData *data = image->GetData();
- if (data == NULL)
- return NULL;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data->surface->w, data->surface->h,
+ 0, sourceFormat, GL_UNSIGNED_BYTE, data->surface->pixels);
- if (mipMap)
- {
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, data->surface->w,
- data->surface->h, sourceFormat, GL_UNSIGNED_BYTE,
- data->surface->pixels);
- }
+
+ // Restore the previous state of 1st stage
+ if (m_textures[0] == NULL)
+ glBindTexture(GL_TEXTURE_2D, 0);
else
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data->surface->w, data->surface->h,
- 0, sourceFormat, GL_UNSIGNED_BYTE, data->surface->pixels);
- }
+ glBindTexture(GL_TEXTURE_2D, m_textures[0]->id);
- // Restore previous setup of 1st texture stage
- RestoreTextureStage(0);
+ if ( (! m_texturing) || (! m_texturesEnabled[0]) )
+ glDisable(GL_TEXTURE_2D);
return result;
}
@@ -373,6 +415,13 @@ void Gfx::CGLDevice::DestroyTexture(Gfx::Texture *texture)
if (it != m_allTextures.end())
m_allTextures.erase(it);
+ // Unbind the texture if in use anywhere
+ for (int index = 0; index < (int)m_textures.size(); ++index)
+ {
+ if (m_textures[index] == texture)
+ SetTexture(index, NULL);
+ }
+
glDeleteTextures(1, &texture->id);
}
@@ -402,7 +451,7 @@ void Gfx::CGLDevice::SetTexture(int index, Gfx::Texture *texture)
assert(index < (int)m_textures.size());
// Enable the given texture stage
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ glActiveTextureARB(GL_TEXTURE0_ARB + index);
glEnable(GL_TEXTURE_2D);
if ((texture == NULL) || (! texture->valid))
@@ -439,7 +488,7 @@ void Gfx::CGLDevice::SetTextureEnabled(int index, bool enabled)
m_texturesEnabled[index] = enabled;
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ glActiveTextureARB(GL_TEXTURE0_ARB + index);
if (enabled)
glEnable(GL_TEXTURE_2D);
else
@@ -466,41 +515,17 @@ void Gfx::CGLDevice::SetTextureParams(int index, const Gfx::TextureParams &param
// Remember the settings
m_texturesParams[index] = params;
+ // Don't actually do anything if texture not set
+ if (m_textures[index] == NULL)
+ {
+ printf("No texture set: %d\n", index);
+ return;
+ }
+
// Enable the given stage
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ glActiveTextureARB(GL_TEXTURE0_ARB + index);
glEnable(GL_TEXTURE_2D);
- GLint minF = 0;
- if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST) minF = GL_NEAREST;
- else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR) minF = GL_LINEAR;
- else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST) minF = GL_NEAREST_MIPMAP_NEAREST;
- else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_NEAREST) minF = GL_LINEAR_MIPMAP_NEAREST;
- else if (params.minFilter == Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_LINEAR) minF = GL_NEAREST_MIPMAP_LINEAR;
- else if (params.minFilter == Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR) minF = GL_LINEAR_MIPMAP_LINEAR;
- else assert(false);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minF);
-
- GLint magF = 0;
- if (params.magFilter == Gfx::TEX_MAG_FILTER_NEAREST) magF = GL_NEAREST;
- else if (params.magFilter == Gfx::TEX_MAG_FILTER_LINEAR) magF = GL_LINEAR;
- else assert(false);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magF);
-
- if (params.wrapS == Gfx::TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- else if (params.wrapS == Gfx::TEX_WRAP_REPEAT)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- else assert(false);
-
- if (params.wrapT == Gfx::TEX_WRAP_CLAMP)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- else if (params.wrapT == Gfx::TEX_WRAP_REPEAT)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- else assert(false);
-
-
// Selection of operation and arguments
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -609,7 +634,7 @@ void Gfx::CGLDevice::SetTextureFactor(Gfx::Color &color)
for (int index = 0; index < (int)m_textures.size(); ++index)
{
// Activate stage
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ glActiveTextureARB(GL_TEXTURE0_ARB + index);
glEnable(GL_TEXTURE_2D);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.Array());
@@ -623,7 +648,7 @@ void Gfx::CGLDevice::SetTextureFactor(Gfx::Color &color)
Gfx::Color Gfx::CGLDevice::GetTextureFactor()
{
// Get from 1st stage (should be the same for all stages)
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB);
+ glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
GLfloat color[4] = { 0.0f };
@@ -636,22 +661,6 @@ Gfx::Color Gfx::CGLDevice::GetTextureFactor()
return Gfx::Color(color[0], color[1], color[2], color[3]);
}
-void Gfx::CGLDevice::RestoreTextureStage(int index)
-{
- // Ensure that we're working with the right stage
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
- glEnable(GL_TEXTURE_2D);
-
- if (m_textures[index] != NULL)
- glBindTexture(GL_TEXTURE_2D, m_textures[index]->id); // bind to the previous texture
- else
- glBindTexture(GL_TEXTURE_2D, 0); // unbind
-
- // Disable the stage if it is set so
- if ( (! m_texturing) || (! m_texturesEnabled[index]) )
- glDisable(GL_TEXTURE_2D);
-}
-
void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, int vertexCount)
{
if (type == Gfx::PRIMITIVE_LINES)
@@ -661,10 +670,12 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Vertex *vertices, in
else if (type == Gfx::PRIMITIVE_TRIANGLE_STRIP)
glBegin(GL_TRIANGLE_STRIP);
+ glColor3f(1.0f, 1.0f, 1.0f); // TODO: set global color?
+
for (int i = 0; i < vertexCount; ++i)
{
glNormal3fv((GLfloat*)vertices[i].normal.Array());
- glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array());
+ glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, (GLfloat*)vertices[i].texCoord.Array());
glVertex3fv((GLfloat*)vertices[i].coord.Array());
}
@@ -684,7 +695,7 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vert
{
// TODO: specular through EXT_separate_specular_color?
glColor4fv((GLfloat*)vertices[i].color.Array());
- glTexCoord2fv((GLfloat*)vertices[i].texCoord.Array());
+ glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, (GLfloat*)vertices[i].texCoord.Array());
glVertex3fv((GLfloat*)vertices[i].coord.Array());
}
@@ -703,8 +714,8 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices
for (int i = 0; i < vertexCount; ++i)
{
glNormal3fv((GLfloat*) vertices[i].normal.Array());
- m_private->glMultiTexCoord2fARB(GL_TEXTURE0_ARB, vertices[i].texCoord.x, vertices[i].texCoord.y);
- m_private->glMultiTexCoord2fARB(GL_TEXTURE1_ARB, vertices[i].texCoord2.x, vertices[i].texCoord2.y);
+ glMultiTexCoord2fARB(GL_TEXTURE0_ARB, vertices[i].texCoord.x, vertices[i].texCoord.y);
+ glMultiTexCoord2fARB(GL_TEXTURE1_ARB, vertices[i].texCoord2.x, vertices[i].texCoord2.y);
glVertex3fv((GLfloat*) vertices[i].coord.Array());
}
@@ -722,25 +733,16 @@ void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled)
{
m_texturing = enabled;
- if (enabled)
+ // Enable/disable stages with new setting
+ for (int index = 0; index < (int)m_textures.size(); ++index)
{
- // All enabled multitexture stages have to be enabled
- for (int index = 0; index < (int)m_textures.size(); ++index)
- {
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
- if (m_texturesEnabled[index])
- glEnable(GL_TEXTURE_2D);
- }
- }
- else
- {
- // All multitexture stages have to be disabled
- for (int index = 0; index < (int)m_textures.size(); ++index)
- {
- m_private->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ if (m_texturing && m_texturesEnabled[index])
+ glEnable(GL_TEXTURE_2D);
+ else
glDisable(GL_TEXTURE_2D);
- }
}
+
return;
}
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index aa5dd04..2b1b05d 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -97,7 +97,7 @@ public:
virtual void SetLightEnabled(int index, bool enabled);
virtual bool GetLightEnabled(int index);
- virtual Gfx::Texture* CreateTexture(CImage *image, bool alpha, bool mipMap);
+ virtual Gfx::Texture* CreateTexture(CImage *image, const Gfx::TextureCreateParams &params);
virtual void DestroyTexture(Gfx::Texture *texture);
virtual void DestroyAllTextures();
@@ -187,9 +187,6 @@ private:
//! Set of all created textures
std::set<Gfx::Texture*> m_allTextures;
-
- //! Restores the state of given texture stage to the previously saved settings
- void RestoreTextureStage(int index);
};
}; // namespace Gfx
diff --git a/src/graphics/opengl/test/CMakeLists.txt b/src/graphics/opengl/test/CMakeLists.txt
new file mode 100644
index 0000000..ce2a83f
--- /dev/null
+++ b/src/graphics/opengl/test/CMakeLists.txt
@@ -0,0 +1,31 @@
+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(SOURCES
+../gldevice.cpp
+../../common/device.cpp
+../../../common/logger.cpp
+../../../common/image.cpp
+texture_test.cpp
+)
+
+include_directories(../../../)
+
+set(LIBS
+${SDL_LIBRARY}
+${SDLIMAGE_LIBRARY}
+${OPENGL_LIBRARY}
+${PNG_LIBRARIES}
+)
+
+add_executable(texture_test ${SOURCES})
+
+target_link_libraries(texture_test ${LIBS})
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..022cf87
--- /dev/null
+++ b/src/graphics/opengl/test/texture_test.cpp
@@ -0,0 +1,365 @@
+#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>
+
+#include <GL/gl.h>
+
+
+#define DEV 1
+
+
+void Init(Gfx::CGLDevice *device)
+{
+ device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
+ device->SetShadeModel(Gfx::SHADE_SMOOTH);
+
+ 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.alpha = true;
+ tex1CreateParams.mipmap = true;
+ tex1CreateParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR;
+ tex1CreateParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR;
+ tex1CreateParams.wrapT = Gfx::TEX_WRAP_CLAMP;
+
+ Gfx::TextureCreateParams tex2CreateParams;
+ tex2CreateParams.alpha = true;
+ tex2CreateParams.mipmap = true;
+ tex2CreateParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST;
+ tex2CreateParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
+ tex2CreateParams.wrapS = Gfx::TEX_WRAP_CLAMP;
+
+ Gfx::Texture* tex1 = device->CreateTexture(&img1, tex1CreateParams);
+ Gfx::Texture* tex2 = device->CreateTexture(&img2, tex2CreateParams);
+
+ device->SetTexture(0, tex1);
+ device->SetTexture(1, tex2);
+
+ Gfx::TextureParams tex1Params;
+ tex1Params.alphaOperation = Gfx::TEX_MIX_OPER_MODULATE;
+ tex1Params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE;
+ device->SetTextureParams(0, tex1Params);
+
+ Gfx::TextureParams tex2Params;
+ tex2Params.alphaOperation = Gfx::TEX_MIX_OPER_MODULATE;
+ tex2Params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE;
+ device->SetTextureParams(1, tex2Params);
+
+ device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
+}
+
+void Render(Gfx::CGLDevice *device)
+{
+ device->BeginScene();
+
+ glFlush();
+
+ 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, 1.0f), Math::Point(0.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(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, 0.0f), Math::Point(1.0f, 0.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::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)),
+ };
+
+ 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);
+
+ device->SetTextureEnabled(0, true);
+ device->SetTextureEnabled(1, true);
+
+ Math::LoadTranslationMatrix(t, Math::Vector( 0.0f, -4.0f, 0.0f));
+ device->SetTransform(Gfx::TRANSFORM_VIEW, t);
+
+ device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);
+
+ device->EndScene();
+}
+
+void InitGL()
+{
+ 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());
+ }
+
+ unsigned int textureHandle1 = 0;
+
+ glActiveTexture(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_2D);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+
+ glGenTextures(1, &textureHandle1);
+ glBindTexture(GL_TEXTURE_2D, textureHandle1);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img1.GetData()->surface->w, img1.GetData()->surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img1.GetData()->surface->pixels);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_RGB, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_2D, GL_SRC0_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_2D, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_2D, GL_SRC0_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_2D, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+
+
+ unsigned int textureHandle2 = 0;
+
+ glActiveTexture(GL_TEXTURE1_ARB);
+ glEnable(GL_TEXTURE_2D);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+
+ glGenTextures(1, &textureHandle2);
+ glBindTexture(GL_TEXTURE_2D, textureHandle2);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img2.GetData()->surface->w, img2.GetData()->surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img2.GetData()->surface->pixels);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_2D, GL_SRC0_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_2D, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_2D, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_2D, GL_SRC0_ALPHA, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_2D, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+
+
+ glMatrixMode(GL_PROJECTION);
+ glOrtho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 1.0f);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+void RenderGL()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glLoadIdentity();
+
+ glColor3f(1.0f, 1.0f, 1.0f);
+
+ glPushMatrix();
+ glTranslatef(-4.0f, 4.0f, 0.0f);
+
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glDisable(GL_TEXTURE_2D);
+
+ glBegin(GL_QUADS);
+ {
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 1.0f);
+ glVertex2f(-2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 1.0f);
+ glVertex2f(2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 0.0f);
+ glVertex2f(2.0f, 2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 0.0f);
+ glVertex2f(-2.0f, 2.0f);
+ }
+ glEnd();
+
+ glPopMatrix();
+ glPushMatrix();
+ glTranslatef( 4.0f, 4.0f, 0.0f);
+
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glEnable(GL_TEXTURE_2D);
+
+ glBegin(GL_QUADS);
+ {
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 1.0f);
+ glVertex2f(-2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 1.0f);
+ glVertex2f(2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 0.0f);
+ glVertex2f(2.0f, 2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 0.0f);
+ glVertex2f(-2.0f, 2.0f);
+ }
+ glEnd();
+
+ glPopMatrix();
+ glPushMatrix();
+ glTranslatef( 0.0f, -4.0f, 0.0f);
+
+ glActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTextureARB(GL_TEXTURE1_ARB);
+ glEnable(GL_TEXTURE_2D);
+
+ glBegin(GL_QUADS);
+ {
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 1.0f);
+ glVertex2f(-2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 1.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 1.0f);
+ glVertex2f(2.0f, -2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0f, 0.0f);
+ glVertex2f(2.0f, 2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0f, 0.0f);
+ glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0f, 0.0f);
+ glVertex2f(-2.0f, 2.0f);
+ }
+ glEnd();
+
+ glPopMatrix();
+
+ glFlush();
+}
+
+
+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");
+
+
+ #if DEV
+ Gfx::CGLDevice *device = new Gfx::CGLDevice();
+ device->Create();
+
+ Init(device);
+ #else
+ InitGL();
+ #endif
+
+ bool done = false;
+ while (! done)
+ {
+ #if DEV
+ Render(device);
+ #else
+ RenderGL();
+ #endif
+
+ SDL_GL_SwapBuffers();
+
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ if (event.type == SDL_QUIT)
+ done = true;
+
+ usleep(50000);
+ }
+
+ #if DEV
+ device->Destroy();
+ #endif
+
+ SDL_FreeSurface(surface);
+
+ IMG_Quit();
+
+ SDL_Quit();
+
+ return 0;
+}