From e8c9945e13fca88a6f8232838682df0654437f3e Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 5 Jul 2012 23:47:29 +0200 Subject: Fixed bug with texturing - moved creation-time tex params to Gfx::TextureCreateParams - fixed bug with texture creation - added simple test for multitexturing --- src/graphics/opengl/gldevice.cpp | 192 ++++++++-------- src/graphics/opengl/gldevice.h | 5 +- src/graphics/opengl/test/CMakeLists.txt | 31 +++ src/graphics/opengl/test/tex1.png | Bin 0 -> 151263 bytes src/graphics/opengl/test/tex2.png | Bin 0 -> 57503 bytes src/graphics/opengl/test/texture_test.cpp | 365 ++++++++++++++++++++++++++++++ 6 files changed, 494 insertions(+), 99 deletions(-) create mode 100644 src/graphics/opengl/test/CMakeLists.txt create mode 100644 src/graphics/opengl/test/tex1.png create mode 100644 src/graphics/opengl/test/tex2.png create mode 100644 src/graphics/opengl/test/texture_test.cpp (limited to 'src/graphics/opengl') 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 ¶ms) { + 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 ¶m // 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 ¶ms); virtual void DestroyTexture(Gfx::Texture *texture); virtual void DestroyAllTextures(); @@ -187,9 +187,6 @@ private: //! Set of all created textures std::set 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 Binary files /dev/null and b/src/graphics/opengl/test/tex1.png differ diff --git a/src/graphics/opengl/test/tex2.png b/src/graphics/opengl/test/tex2.png new file mode 100644 index 0000000..ebdae0d Binary files /dev/null and b/src/graphics/opengl/test/tex2.png 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 +#include +#include + +#include + + +#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; +} -- cgit v1.2.3-1-g7c22