From 66ead32bcc79c6b5c2d1070cd79663da6cee1bc3 Mon Sep 17 00:00:00 2001 From: spartanj Date: Tue, 24 Aug 2010 05:20:02 -0300 Subject: [PATCH] Added support for Frame Buffers, FBO and PBuffer (win and linux ftm), better known as render to texture. Added loading from memory of texture groups. Fixed minor things. --- ee.linux.cbp | 6 + ee.win.cbp | 6 + src/base.hpp | 4 + src/ee.h | 3 + src/graphics/cframebuffer.cpp | 61 +++++++ src/graphics/cframebuffer.hpp | 45 +++++ src/graphics/cframebufferfbo.cpp | 120 ++++++++++++++ src/graphics/cframebufferfbo.hpp | 35 ++++ src/graphics/cframebufferpbuffer.cpp | 239 +++++++++++++++++++++++++++ src/graphics/cframebufferpbuffer.hpp | 77 +++++++++ src/graphics/ctexturegrouploader.cpp | 54 ++++++ src/graphics/ctexturegrouploader.hpp | 4 + src/graphics/cttffont.cpp | 13 +- src/system/cresourceloader.cpp | 1 - src/test/ee.cpp | 24 ++- src/utils/utils.cpp | 2 +- src/window/base.hpp | 8 + src/window/cengine.cpp | 53 +++++- src/window/cengine.hpp | 46 ++++-- 19 files changed, 781 insertions(+), 20 deletions(-) create mode 100644 src/graphics/cframebuffer.cpp create mode 100644 src/graphics/cframebuffer.hpp create mode 100644 src/graphics/cframebufferfbo.cpp create mode 100644 src/graphics/cframebufferfbo.hpp create mode 100644 src/graphics/cframebufferpbuffer.cpp create mode 100644 src/graphics/cframebufferpbuffer.hpp diff --git a/ee.linux.cbp b/ee.linux.cbp index d5538d77f..a17748165 100644 --- a/ee.linux.cbp +++ b/ee.linux.cbp @@ -82,6 +82,12 @@ + + + + + + diff --git a/ee.win.cbp b/ee.win.cbp index 2130c7b63..e80dbb7b1 100644 --- a/ee.win.cbp +++ b/ee.win.cbp @@ -84,6 +84,12 @@ + + + + + + diff --git a/src/base.hpp b/src/base.hpp index 8c3e6ed52..5ac4f559b 100644 --- a/src/base.hpp +++ b/src/base.hpp @@ -52,6 +52,10 @@ # define EE_PLATFORM EE_PLATFORM_LINUX #endif +#ifdef EE_PLATFORM +#define EE_SUPPORTED_PLATFORM +#endif + #if EE_PLATFORM == EE_PLATFORM_WIN32 #define EE_CALL _stdcall diff --git a/src/ee.h b/src/ee.h index c7ae5d8dc..2a9341225 100755 --- a/src/ee.h +++ b/src/ee.h @@ -120,6 +120,9 @@ #include "graphics/cshaderprogram.hpp" #include "graphics/cshaderprogrammanager.hpp" #include "graphics/ctexturegrouploader.hpp" + #include "graphics/cframebuffer.hpp" + #include "graphics/cframebufferfbo.hpp" + #include "graphics/cframebufferpbuffer.hpp" using namespace EE::Graphics; // Gaming diff --git a/src/graphics/cframebuffer.cpp b/src/graphics/cframebuffer.cpp new file mode 100644 index 000000000..d637beba9 --- /dev/null +++ b/src/graphics/cframebuffer.cpp @@ -0,0 +1,61 @@ +#include "cframebuffer.hpp" +#include "ctexturefactory.hpp" +#include "../window/cengine.hpp" +#include "cframebufferfbo.hpp" +#include "cframebufferpbuffer.hpp" + +namespace EE { namespace Graphics { + +cFrameBuffer * cFrameBuffer::CreateNew( const Uint32& Width, const Uint32& Height, bool DepthBuffer ) { + if ( cFrameBufferFBO::IsSupported() ) + return new cFrameBufferFBO( Width, Height, DepthBuffer ); + + if ( cFrameBufferPBuffer::IsSupported() ) + return new cFrameBufferPBuffer( Width, Height, DepthBuffer ); + + return NULL; +} + +cFrameBuffer::cFrameBuffer() : + mWidth(0), + mHeight(0), + mTexture(NULL), + mClearColor(0,0,0,0) +{} + +cFrameBuffer::~cFrameBuffer() { + if ( NULL != mTexture ) + cTextureFactory::instance()->Remove( mTexture->TexId() ); +} + +cTexture * cFrameBuffer::GetTexture() const { + return mTexture; +} + +void cFrameBuffer::ClearColor( eeColorAf Color ) { + mClearColor = Color; +} + +eeColorAf cFrameBuffer::ClearColor() const { + return mClearColor; +} + +void cFrameBuffer::SetBufferView() { + glClearColor( mClearColor.R(), mClearColor.G(), mClearColor.B(), mClearColor.A() ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + mPrevView = Window::cEngine::instance()->GetView(); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glViewport( 0, 0, mWidth, mHeight ); + glOrtho( 0.0f, mWidth, 0.f, mHeight, -1000.0f, 1000.0f ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + +void cFrameBuffer::RecoverView() { + cEngine::instance()->SetView( mPrevView ); +} + +}} diff --git a/src/graphics/cframebuffer.hpp b/src/graphics/cframebuffer.hpp new file mode 100644 index 000000000..01acc819c --- /dev/null +++ b/src/graphics/cframebuffer.hpp @@ -0,0 +1,45 @@ +#ifndef EE_GRAPHICSCFRAMEBUFFER_HPP +#define EE_GRAPHICSCFRAMEBUFFER_HPP + +#include "base.hpp" +#include "ctexture.hpp" +#include "../window/cview.hpp" + +using namespace EE::Window; + +namespace EE { namespace Graphics { + +class cFrameBuffer { + public: + static cFrameBuffer * CreateNew( const Uint32& Width, const Uint32& Height, bool DepthBuffer = false ); + + cFrameBuffer(); + + virtual ~cFrameBuffer(); + + virtual bool Create( const Uint32& Width, const Uint32& Height ) = 0; + + virtual void Bind() = 0; + + virtual void Unbind() = 0; + + cTexture * GetTexture() const; + + void ClearColor( eeColorAf Color ); + + eeColorAf ClearColor() const; + protected: + Int32 mWidth; + Int32 mHeight; + cTexture * mTexture; + eeColorAf mClearColor; + cView mPrevView; + + void SetBufferView(); + void RecoverView(); +}; + +}} + +#endif + diff --git a/src/graphics/cframebufferfbo.cpp b/src/graphics/cframebufferfbo.cpp new file mode 100644 index 000000000..5cd2ca666 --- /dev/null +++ b/src/graphics/cframebufferfbo.cpp @@ -0,0 +1,120 @@ +#include "cframebufferfbo.hpp" +#include "ctexturefactory.hpp" +#include "../window/cengine.hpp" + +namespace EE { namespace Graphics { + +cFrameBufferFBO::cFrameBufferFBO() : + cFrameBuffer(), + mFrameBuffer(0), + mDepthBuffer(0) +{} + +cFrameBufferFBO::cFrameBufferFBO( const Uint32& Width, const Uint32& Height, bool DepthBuffer ) : + cFrameBuffer(), + mFrameBuffer(0), + mDepthBuffer(0) +{ + Create( Width, Height, DepthBuffer ); +} + +cFrameBufferFBO::~cFrameBufferFBO() { + if ( !IsSupported() ) + return; + + GLint curFB; + glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &curFB ); + + if ( curFB == mFrameBuffer ) + Unbind(); + + if ( mDepthBuffer ) { + GLuint depthBuffer = static_cast( mDepthBuffer ); + glDeleteFramebuffersEXT( 1, &depthBuffer ); + } + + if ( mFrameBuffer ) { + GLuint frameBuffer = static_cast( mFrameBuffer ); + glDeleteFramebuffersEXT( 1, &frameBuffer ); + } +} + +bool cFrameBufferFBO::IsSupported() { + return 0 != GLEW_EXT_framebuffer_object; +} + +bool cFrameBufferFBO::Create( const Uint32& Width, const Uint32& Height ) { + return Create( Width, Height, false ); +} + +bool cFrameBufferFBO::Create( const Uint32& Width, const Uint32& Height, bool DepthBuffer ) { + if ( !IsSupported() ) + return false; + + GLuint frameBuffer = 0; + + glGenFramebuffersEXT( 1, &frameBuffer ); + + mFrameBuffer = static_cast( frameBuffer ); + + if ( !mFrameBuffer) + return false; + + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mFrameBuffer ); + + if ( DepthBuffer ) { + GLuint depth = 0; + + glGenRenderbuffersEXT( 1, &depth ); + + mDepthBuffer = static_cast(depth); + + if ( !mDepthBuffer ) + return false; + + glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, mDepthBuffer ); + + glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, Width, Height ); + + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthBuffer ); + } + + Uint32 TexId = cTextureFactory::instance()->CreateEmptyTexture( Width, Height, eeColorA(0,0,0,0) ); + + if ( cTextureFactory::instance()->TextureIdExists( TexId ) ) { + mTexture = cTextureFactory::instance()->GetTexture( TexId ); + } else { + return false; + } + + glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture->Texture(), 0 ); + + if ( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT ) { + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); + + return false; + } + + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); + + mWidth = Width; + mHeight = Height; + + return true; +} + +void cFrameBufferFBO::Bind() { + if ( mFrameBuffer ) { + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mFrameBuffer ); + SetBufferView(); + } +} + +void cFrameBufferFBO::Unbind() { + if ( mFrameBuffer ) { + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); + RecoverView(); + } +} + +}} diff --git a/src/graphics/cframebufferfbo.hpp b/src/graphics/cframebufferfbo.hpp new file mode 100644 index 000000000..870f0ebce --- /dev/null +++ b/src/graphics/cframebufferfbo.hpp @@ -0,0 +1,35 @@ +#ifndef EE_GRAPHICSCFRAMEBUFFERFBO_HPP +#define EE_GRAPHICSCFRAMEBUFFERFBO_HPP + +#include "base.hpp" +#include "cframebuffer.hpp" +#include "ctexture.hpp" + +namespace EE { namespace Graphics { + +class cFrameBufferFBO : public cFrameBuffer { + public: + cFrameBufferFBO(); + + ~cFrameBufferFBO(); + + cFrameBufferFBO( const Uint32& Width, const Uint32& Height, bool DepthBuffer = false ); + + bool Create( const Uint32& Width, const Uint32& Height ); + + bool Create( const Uint32& Width, const Uint32& Height, bool DepthBuffer ); + + void Bind(); + + void Unbind(); + + static bool IsSupported(); + protected: + Int32 mFrameBuffer; + Uint32 mDepthBuffer; +}; + +}} + +#endif + diff --git a/src/graphics/cframebufferpbuffer.cpp b/src/graphics/cframebufferpbuffer.cpp new file mode 100644 index 000000000..3190a3fca --- /dev/null +++ b/src/graphics/cframebufferpbuffer.cpp @@ -0,0 +1,239 @@ +#include "cframebufferpbuffer.hpp" +#include "ctexturefactory.hpp" +#include "../window/cengine.hpp" + +namespace EE { namespace Graphics { + +cFrameBufferPBuffer::cFrameBufferPBuffer() : + cFrameBuffer(), +#if EE_PLATFORM == EE_PLATFORM_WIN32 + mDeviceContext( NULL ), +#elif EE_PLATFORM == EE_PLATFORM_LINUX + mDisplay( NULL ), +#endif + mPBuffer( NULL ), + mContext( NULL ) +{ +#if EE_PLATFORM == EE_PLATFORM_LINUX + mDisplay = XOpenDisplay(NULL); +#endif +} + +cFrameBufferPBuffer::cFrameBufferPBuffer( const Uint32& Width, const Uint32& Height, bool DepthBuffer ) : + cFrameBuffer(), +#if EE_PLATFORM == EE_PLATFORM_WIN32 + mDeviceContext( NULL ), +#elif EE_PLATFORM == EE_PLATFORM_LINUX + mDisplay( NULL ), +#endif + mPBuffer( NULL ), + mContext( NULL ) +{ +#if EE_PLATFORM == EE_PLATFORM_LINUX + mDisplay = XOpenDisplay(NULL); +#endif + Create( Width, Height, DepthBuffer ); +} + +cFrameBufferPBuffer::~cFrameBufferPBuffer() { +#if EE_PLATFORM == EE_PLATFORM_WIN32 + if ( mContext ) + wglDeleteContext( mContext ); + + if ( mPBuffer && mDeviceContext ) { + wglReleasePbufferDCARB( mPBuffer, mDeviceContext ); + wglDestroyPbufferARB( mPBuffer ); + } +#elif EE_PLATFORM == EE_PLATFORM_LINUX + if ( mContext ) + glXDestroyContext( mDisplay, mContext ); + + if ( mPBuffer ) + glXDestroyGLXPbufferSGIX( mDisplay, mPBuffer ); + + if ( mDisplay ) + XCloseDisplay( mDisplay ); +#endif + + if ( Window::cEngine::ExistsSingleton() ) + Window::cEngine::instance()->SetDefaultContext(); +} + +bool cFrameBufferPBuffer::IsSupported() { +#if EE_PLATFORM == EE_PLATFORM_WIN32 + return WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format; +#elif EE_PLATFORM == EE_PLATFORM_LINUX + return glxewIsSupported("GLX_SGIX_pbuffer"); +#else + return false; +#endif +} + +bool cFrameBufferPBuffer::Create( const Uint32& Width, const Uint32& Height ) { + return Create( Width, Height, false ); +} + +bool cFrameBufferPBuffer::Create( const Uint32& Width, const Uint32& Height, bool DepthBuffer ) { + if ( !IsSupported() ) + return false; + + mWidth = Width; + mHeight = Height; + +#if EE_PLATFORM == EE_PLATFORM_WIN32 + HDC currentDC = wglGetCurrentDC(); + + int attributes[] = + { + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE, + WGL_RED_BITS_ARB, 8, + WGL_GREEN_BITS_ARB, 8, + WGL_BLUE_BITS_ARB, 8, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, ( DepthBuffer ? 24 : 0 ), + WGL_DOUBLE_BUFFER_ARB, GL_FALSE, + 0 + }; + + unsigned int nbFormats = 0; + int pixelFormat = -1; + wglChoosePixelFormatARB( currentDC, attributes, NULL, 1, &pixelFormat, &nbFormats ); + + if ( nbFormats == 0 ) + return false; + + mPBuffer = wglCreatePbufferARB( currentDC, pixelFormat, Width, Height, NULL ); + mDeviceContext = wglGetPbufferDCARB( mPBuffer ); + mContext = wglCreateContext( mDeviceContext ); + + if ( !mPBuffer || !mDeviceContext || !mContext ) + return false; + + int actualWidth, actualHeight; + wglQueryPbufferARB( mPBuffer, WGL_PBUFFER_WIDTH_ARB, &actualWidth ); + wglQueryPbufferARB( mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &actualHeight ); + + if ( ( actualWidth != static_cast(Width) ) || ( actualHeight != static_cast(Height) ) ) + return false; + + HGLRC currentContext = wglGetCurrentContext(); + if (currentContext) { + wglMakeCurrent( NULL, NULL ); + wglShareLists( currentContext, mContext ); + wglMakeCurrent( currentDC, currentContext ); + } +#elif EE_PLATFORM == EE_PLATFORM_LINUX + int visualAttributes[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, ( DepthBuffer ? 24 : 0 ), + 0 + }; + + int PBufferAttributes[] = + { + GLX_PBUFFER_WIDTH, Width, + GLX_PBUFFER_HEIGHT, Height, + 0 + }; + + int nbConfigs = 0; + GLXFBConfig* configs = glXChooseFBConfigSGIX( mDisplay, DefaultScreen( mDisplay ), visualAttributes, &nbConfigs ); + + if (!configs || !nbConfigs) + return false; + + mPBuffer = glXCreateGLXPbufferSGIX( mDisplay, configs[0], Width, Height, PBufferAttributes ); + + if ( !mPBuffer ) { + XFree(configs); + return false; + } + + unsigned int actualWidth, actualHeight; + glXQueryGLXPbufferSGIX( mDisplay, mPBuffer, GLX_WIDTH_SGIX, &actualWidth); + glXQueryGLXPbufferSGIX( mDisplay, mPBuffer, GLX_HEIGHT_SGIX, &actualHeight); + + if ( ( actualWidth != Width ) || ( actualHeight != Height ) ) { + XFree(configs); + return false; + } + + GLXDrawable currentDrawable = glXGetCurrentDrawable(); + GLXContext currentContext = glXGetCurrentContext(); + + if ( currentContext ) + glXMakeCurrent( mDisplay, NULL, NULL ); + + XVisualInfo* visual = glXGetVisualFromFBConfig( mDisplay, configs[0] ); + mContext = glXCreateContext( mDisplay, visual, currentContext, true ); + + if ( !mContext ) { + XFree(configs); + XFree(visual); + return false; + } + + if ( currentContext ) + glXMakeCurrent( mDisplay, currentDrawable, currentContext ); + + XFree(configs); + XFree(visual); +#endif + + Uint32 TexId = cTextureFactory::instance()->CreateEmptyTexture( Width, Height, eeColorA(0,0,0,0) ); + + if ( cTextureFactory::instance()->TextureIdExists( TexId ) ) { + mTexture = cTextureFactory::instance()->GetTexture( TexId ); + } else { + return false; + } + + return true; +} + +void cFrameBufferPBuffer::Bind() { + bool ChangeContext = false; + + #if EE_PLATFORM == EE_PLATFORM_WIN32 + if ( mDeviceContext && mContext ) { + if ( wglGetCurrentContext() != mContext ) { + ChangeContext = true; + wglMakeCurrent( mDeviceContext, mContext ); + } + } + #elif EE_PLATFORM == EE_PLATFORM_LINUX + if ( mPBuffer && mContext ) { + if ( glXGetCurrentContext() != mContext ) { + ChangeContext = true; + glXMakeCurrent( mDisplay, mPBuffer, mContext ); + } + } + #endif + + if ( ChangeContext ) { + Window::cEngine::instance()->ResetGL2D( true ); + SetBufferView(); + } +} + +void cFrameBufferPBuffer::Unbind() { + GLint previousTexture; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &previousTexture ); + + glBindTexture( GL_TEXTURE_2D, (GLint)mTexture->Texture() ); + glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, mWidth, mHeight ); + + glBindTexture( GL_TEXTURE_2D, previousTexture ); + + Window::cEngine::instance()->SetDefaultContext(); + RecoverView(); +} + +}} diff --git a/src/graphics/cframebufferpbuffer.hpp b/src/graphics/cframebufferpbuffer.hpp new file mode 100644 index 000000000..a987a4730 --- /dev/null +++ b/src/graphics/cframebufferpbuffer.hpp @@ -0,0 +1,77 @@ +#ifndef EE_GRAPHICSCFRAMEBUFFERPBUFFER_HPP +#define EE_GRAPHICSCFRAMEBUFFERPBUFFER_HPP + +/** Part of this code is based on the implementation of PBuffers from: +* +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +* +* NOTE by Martin Golini: This is not the original version, so differs from SFML implementation. +*/ + +#include "base.hpp" +#include "cframebuffer.hpp" + +#if EE_PLATFORM == EE_PLATFORM_WIN32 +#include "../helper/glew/wglew.h" +#elif EE_PLATFORM == EE_PLATFORM_LINUX +#include "../helper/glew/glxew.h" +#include +#elif EE_PLATFORM == EE_PLATFORM_APPLE +#include +#warning No PBuffer implemented on MAC +#else +#warning No PBuffer implemented on this platform +#endif + +namespace EE { namespace Graphics { + +class cFrameBufferPBuffer : public cFrameBuffer { + public: + cFrameBufferPBuffer(); + + ~cFrameBufferPBuffer(); + + cFrameBufferPBuffer( const Uint32& Width, const Uint32& Height, bool DepthBuffer = false ); + + bool Create( const Uint32& Width, const Uint32& Height ); + + bool Create( const Uint32& Width, const Uint32& Height, bool DepthBuffer ); + + void Bind(); + + void Unbind(); + + static bool IsSupported(); + protected: + #if EE_PLATFORM == EE_PLATFORM_WIN32 + HDC mDeviceContext; + HPBUFFERARB mPBuffer; + HGLRC mContext; + #elif EE_PLATFORM == EE_PLATFORM_LINUX + ::Display* mDisplay; + GLXPbuffer mPBuffer; + GLXContext mContext; + #endif +}; + +}} + +#endif diff --git a/src/graphics/ctexturegrouploader.cpp b/src/graphics/ctexturegrouploader.cpp index 76a05632f..c85386ba8 100644 --- a/src/graphics/ctexturegrouploader.cpp +++ b/src/graphics/ctexturegrouploader.cpp @@ -72,6 +72,60 @@ void cTextureGroupLoader::Load( const std::string& TextureGroupPath ) { } } +void cTextureGroupLoader::LoadFromPack( cPack * Pack, const std::string& FilePackPath ) { + if ( NULL != Pack && Pack->IsOpen() && -1 != Pack->Exists( FilePackPath ) ) { + std::vector TempData; + + Pack->ExtractFileToMemory( FilePackPath, TempData ); + + LoadFromMemory( reinterpret_cast ( &TempData[0] ), TempData.size(), FilePackPath ); + } +} + +void cTextureGroupLoader::LoadFromMemory( const Uint8* Data, const Uint32& DataSize, const std::string& TextureGroupName ) { + mRL.Threaded( mThreaded ); + + if ( TextureGroupName.size() ) + mTextureGroupPath = TextureGroupName; + + sTextureGroupHdr TexGrHdr; + + const Uint8* dataPtr = Data; + + if ( NULL != dataPtr ) { + memcpy( (void*)&TexGrHdr, dataPtr, sizeof(sTextureGroupHdr) ); + dataPtr += sizeof(sTextureGroupHdr); + + if ( TexGrHdr.Magic == ( ( 'E' << 0 ) | ( 'E' << 8 ) | ( 'T' << 16 ) | ( 'G' << 24 ) ) ) { + for ( Uint32 i = 0; i < TexGrHdr.TextureCount; i++ ) { + sTextureHdr tTextureHdr; + sTempTexGroup tTexGroup; + + memcpy( (void*)&tTextureHdr, dataPtr, sizeof(sTextureHdr) ); + dataPtr += sizeof(sTextureHdr); + + tTexGroup.Texture = tTextureHdr; + tTexGroup.Shapes.resize( tTextureHdr.ShapeCount ); + + std::string name( &tTextureHdr.Name[0] ); + std::string path( FileRemoveFileName( mTextureGroupPath ) + name ); + + mRL.Add( new cTextureLoader( path ) ); + + memcpy( (void*)(&tTexGroup.Shapes[0]), dataPtr, sizeof(sShapeHdr) * tTextureHdr.ShapeCount ); + dataPtr += sizeof(sShapeHdr) * tTextureHdr.ShapeCount; + + mTempGroups.push_back( tTexGroup ); + } + } + + mRL.Load(); + + if ( !mThreaded ) + CreateShapes(); + } +} + void cTextureGroupLoader::CreateShapes() { cShapeGroup * tSG = NULL; diff --git a/src/graphics/ctexturegrouploader.hpp b/src/graphics/ctexturegrouploader.hpp index 2359b1b06..ad984cf7a 100644 --- a/src/graphics/ctexturegrouploader.hpp +++ b/src/graphics/ctexturegrouploader.hpp @@ -23,6 +23,10 @@ class EE_API cTextureGroupLoader { void Load( const std::string& TextureGroupPath = "" ); + void LoadFromMemory( const Uint8* Data, const Uint32& DataSize, const std::string& TextureGroupName ); + + void LoadFromPack( cPack * Pack, const std::string& FilePackPath ); + bool Threaded() const; void Threaded( const bool& threaded ); diff --git a/src/graphics/cttffont.cpp b/src/graphics/cttffont.cpp index 97260cbc0..2fab6355c 100755 --- a/src/graphics/cttffont.cpp +++ b/src/graphics/cttffont.cpp @@ -22,8 +22,11 @@ cTTFFont::~cTTFFont() { bool cTTFFont::LoadFromPack( cPack* Pack, const std::string& FilePackPath, const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& VerticalDraw, const Uint16& NumCharsToGen, const eeColor& FontColor, const Uint8& OutlineSize, const eeColor& OutlineColor ) { std::vector TmpData; - if ( Pack->IsOpen() && Pack->ExtractFileToMemory( FilePackPath, TmpData ) ) + if ( Pack->IsOpen() && Pack->ExtractFileToMemory( FilePackPath, TmpData ) ) { + mFilepath = FilePackPath; + return LoadFromMemory( reinterpret_cast (&TmpData[0]), (eeUint)TmpData.size(), Size, Style, VerticalDraw, NumCharsToGen, FontColor, OutlineSize, OutlineColor ); + } TmpData.clear(); @@ -31,7 +34,9 @@ bool cTTFFont::LoadFromPack( cPack* Pack, const std::string& FilePackPath, const } bool cTTFFont::LoadFromMemory( Uint8* TTFData, const eeUint& TTFDataSize, const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& VerticalDraw, const Uint16& NumCharsToGen, const eeColor& FontColor, const Uint8& OutlineSize, const eeColor& OutlineColor ) { - mFilepath = "from memory"; + if ( !mFilepath.size() ) + mFilepath = "from memory"; + mLoadedFromMemory = true; mFont = hkFontManager::instance()->OpenFromMemory( reinterpret_cast(&TTFData[0]), TTFDataSize, Size, 0, NumCharsToGen ); @@ -241,7 +246,9 @@ bool cTTFFont::iLoad( const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& Ve void cTTFFont::UpdateLoading() { if ( mTexReady && NULL != mPixels ) { - mTexId = cTextureFactory::instance()->LoadFromPixels( reinterpret_cast ( &mPixels[0] ), (Uint32)mTexWidth, (Uint32)mTexHeight, 4 ); + std::string name( FileRemoveExtension( FileNameFromPath( mFilepath ) ) ); + + mTexId = cTextureFactory::instance()->LoadFromPixels( reinterpret_cast ( &mPixels[0] ), (Uint32)mTexWidth, (Uint32)mTexHeight, 4, false, eeRGB(true), EE_CLAMP_TO_EDGE, false, false, name ); eeSAFE_DELETE_ARRAY( mPixels ); diff --git a/src/system/cresourceloader.cpp b/src/system/cresourceloader.cpp index 1912a842a..112945b80 100644 --- a/src/system/cresourceloader.cpp +++ b/src/system/cresourceloader.cpp @@ -1,5 +1,4 @@ #include "cresourceloader.hpp" -#include "clog.hpp" namespace EE { namespace System { diff --git a/src/test/ee.cpp b/src/test/ee.cpp index ee3b380ae..279c084ec 100644 --- a/src/test/ee.cpp +++ b/src/test/ee.cpp @@ -191,6 +191,8 @@ class cEETest : private cThread { cTextureGroupLoader * mTGL; cSprite mBlindy; + + cFrameBuffer * mFB; }; @@ -283,6 +285,11 @@ void cEETest::Init() { Batch.AllocVertexs( 1024 ); Batch.SetBlendFunc( ALPHA_BLENDONE ); + mFB = cFrameBuffer::CreateNew( 256, 256, false ); + + if ( NULL != mFB ) + mFB->ClearColor( eeColorAf( 0, 0, 0, 0.5f ) ); + Launch(); } else { cout << "Failed to start EE++" << endl; @@ -830,6 +837,7 @@ void cEETest::Render() { eeColorA ColRR3( 100, 100, 100, 220 ); PR.SetColor( eeColorA(150, 150, 150, 220) ); + PR.DrawRectangle( 0.f, (eeFloat)EE->GetHeight() - (eeFloat)TTF->GetNumLines() * (eeFloat)TTF->GetFontSize(), @@ -865,7 +873,17 @@ void cEETest::Render() { FF2->SetText( L"FPS: " + toWStr( EE->FPS() ) ); FF2->Draw( EE->GetWidth() - FF2->GetTextWidth() - 15, 0 ); - mBlindy.Draw(); + if ( NULL != mFB ) { + mFB->Bind(); + + mBlindy.UpdatePos( 128-16, 128-16 ); + mBlindy.Draw(); + + mFB->Unbind(); + + if ( NULL != mFB->GetTexture() ) + mFB->GetTexture()->Draw( EE->GetWidth() - 256, 240, Ang ); + } cUIManager::instance()->Update(); cUIManager::instance()->Draw(); @@ -1104,6 +1122,7 @@ void cEETest::Process() { EE->Display(); } while( EE->Running() ); } + End(); } @@ -1119,7 +1138,8 @@ void cEETest::End() { cLog::instance()->Save(); - delete mTGL; + eeSAFE_DELETE( mTGL ); + eeSAFE_DELETE( mFB ); cEngine::DestroySingleton(); } diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 24aec9dce..919a29aab 100755 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -271,7 +271,7 @@ Uint32 MakeHash( const std::string& str ) { } Uint32 MakeHash( const Int8* str ) { - if ( NULL != str ) { + if ( NULL != str && *str ) { Uint32 hash = 5381 + *str; while( *str ) { diff --git a/src/window/base.hpp b/src/window/base.hpp index 8a1d9143a..f95233b9f 100644 --- a/src/window/base.hpp +++ b/src/window/base.hpp @@ -5,6 +5,14 @@ #include +#if EE_PLATFORM == EE_PLATFORM_WIN32 +#include "../helper/glew/wglew.h" +#elif EE_PLATFORM == EE_PLATFORM_LINUX +#include "../helper/glew/glxew.h" +#elif EE_PLATFORM == EE_PLATFORM_APPLE +#include +#endif + #if EE_PLATFORM == EE_PLATFORM_LINUX #include typedef Window X11Window; diff --git a/src/window/cengine.cpp b/src/window/cengine.cpp index 7f4927251..e98385b24 100755 --- a/src/window/cengine.cpp +++ b/src/window/cengine.cpp @@ -217,6 +217,8 @@ bool cEngine::Init(const Uint32& Width, const Uint32& Height, const Uint8& BitCo glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + GetMainContext(); + mDefaultView.SetView( 0, 0, mVideoInfo.Width, mVideoInfo.Height ); mCurrentView = &mDefaultView; @@ -259,7 +261,7 @@ const cView& cEngine::GetView() const { return *mCurrentView; } -void cEngine::ResetGL2D() { +void cEngine::ResetGL2D( const bool& KeepView ) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); @@ -270,7 +272,8 @@ void cEngine::ResetGL2D() { glEnable( GL_TEXTURE_2D ); // Enable Textures - SetView( mDefaultView ); + if ( !KeepView ) + SetView( mDefaultView ); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); @@ -980,4 +983,50 @@ std::wstring cEngine::GetClipboardTextWStr() { return tStr; } +#if EE_PLATFORM == EE_PLATFORM_WIN32 +void cEngine::SetCurrentContext( HGLRC Context ) { + if ( mInit ) { + wglMakeCurrent( GetDC( mVideoInfo.info.window ), Context ); + } +} + +HGLRC cEngine::GetContext() const { + return mContext; +} +#elif EE_PLATFORM == EE_PLATFORM_LINUX +void cEngine::SetCurrentContext( GLXContext Context ) { + if ( mInit ) { + mVideoInfo.info.info.x11.lock_func(); + glXMakeCurrent( mVideoInfo.info.info.x11.display, mVideoInfo.info.info.x11.window, Context ); + mVideoInfo.info.info.x11.unlock_func(); + } +} + +GLXContext cEngine::GetContext() const { + return mContext; +} +#elif EE_PLATFORM == EE_PLATFORM_APPLE +void cEngine::SetCurrentContext( AGLContext Context ) { + aglSetCurrentContext( Context ); +} + +AGLContext cEngine::GetContext() const { + return mContext; +} +#endif + +void cEngine::GetMainContext() { +#if EE_PLATFORM == EE_PLATFORM_WIN32 + mContext = wglGetCurrentContext(); +#elif EE_PLATFORM == EE_PLATFORM_LINUX + mContext = glXGetCurrentContext(); +#elif EE_PLATFORM == EE_PLATFORM_APPLE + mContext = aglGetCurrentContext(); +#endif +} + +void cEngine::SetDefaultContext() { + SetCurrentContext( mContext ); +} + }} diff --git a/src/window/cengine.hpp b/src/window/cengine.hpp index 974353de0..bb1faacc3 100755 --- a/src/window/cengine.hpp +++ b/src/window/cengine.hpp @@ -205,7 +205,7 @@ class EE_API cEngine : public cSingleton { bool WindowVisible(); /** This will set the default rendering states and view to render in 2D mode */ - void ResetGL2D(); + void ResetGL2D( const bool& KeepView = false ); /** Set the current active view @param View New view to use (pass GetDefaultView() to set the default view) @@ -232,16 +232,29 @@ class EE_API cEngine : public cSingleton { /** Set the size of the window for a windowed window */ void SetWindowSize( const Uint32& Width, const Uint32& Height ); + + #if EE_PLATFORM == EE_PLATFORM_WIN32 + void SetCurrentContext( HGLRC Context ); + HGLRC GetContext() const; + #elif EE_PLATFORM == EE_PLATFORM_LINUX + void SetCurrentContext( GLXContext Context ); + GLXContext GetContext() const; + #elif EE_PLATFORM == EE_PLATFORM_APPLE + void SetCurrentContext( AGLContext Context ); + AGLContext GetContext() const; + #endif + + void SetDefaultContext(); protected: cEngine(); ~cEngine(); private: - bool mInit; - VideoInfo mVideoInfo; - eeColor mBackColor; - SDL_Cursor * mCursor; - bool mShowCursor; - eeVector2i mOldWinPos; + bool mInit; + VideoInfo mVideoInfo; + eeColor mBackColor; + SDL_Cursor * mCursor; + bool mShowCursor; + eeVector2i mOldWinPos; struct _Frames { struct _FPS { @@ -255,12 +268,21 @@ class EE_API cEngine : public cSingleton { eeFloat ElapsedTime; } mFrames; - Uint32 mInitialWidth, mInitialHeight; + Uint32 mInitialWidth; + Uint32 mInitialHeight; - cView mDefaultView; - const cView* mCurrentView; + cView mDefaultView; + const cView * mCurrentView; - GLenum mGLEWinit; + GLenum mGLEWinit; + + #if EE_PLATFORM == EE_PLATFORM_WIN32 + HGLRC mContext; + #elif EE_PLATFORM == EE_PLATFORM_LINUX + GLXContext mContext; + #elif EE_PLATFORM == EE_PLATFORM_APPLE + AGLContext mContext + #endif void CalculateFps(); void LimitFps(); @@ -273,6 +295,8 @@ class EE_API cEngine : public cSingleton { int clipboard_convert_scrap(int type, char *dst, char *src, int srclen); void clipboard_get_scrap(int type, int *dstlen, char **dst); + + void GetMainContext(); }; }}