13 Commits

Author SHA1 Message Date
Eduardo Bart
8f0ad27735 Minor SDL improvements 2013-03-11 14:43:42 -03:00
Eduardo Bart
d60413f7d6 Progress in SDL platform 2013-03-08 15:36:32 -03:00
Eduardo Bart
e6ee88af43 Changes to compile on android 2013-03-08 15:35:40 -03:00
Henrique Santiago
b3b849000d Add texture abstract class 2013-03-08 15:35:40 -03:00
Henrique
ab9351196c EGL and WGL working 2013-03-08 15:32:21 -03:00
Henrique Santiago
96bbe20588 EGL and GLX working 2013-03-08 15:32:21 -03:00
Henrique Santiago
77995a2e88 Compiling on linux again 2013-03-08 15:32:20 -03:00
Eduardo Bart
adf51f1852 Use SDL 2.0 2013-03-08 15:32:20 -03:00
Henrique
45eda6c573 Now drawing on windows again 2013-03-08 15:32:20 -03:00
Henrique Santiago
c3c951ebbb More changes to context 2013-03-08 15:32:20 -03:00
Henrique
a989ceb10c Add graphics context 2013-03-08 15:32:20 -03:00
Eduardo Bart
fb8552d142 Very basic rendering with SDL1.2 + OGL 2013-03-08 15:32:20 -03:00
Eduardo Bart
65b32d283b Add first SDL files 2013-03-08 15:32:20 -03:00
56 changed files with 1768 additions and 769 deletions

View File

@@ -48,7 +48,7 @@ g_modules.ensureModuleLoaded("game_interface")
-- mods 1000-9999
g_modules.autoLoadModules(9999)
local script = '/' .. g_app.getCompactName() .. 'rc'
local script = '/' .. g_app.getCompactName() .. 'rc.lua'
if g_resources.fileExists(script) then
dofile(script)

View File

@@ -1,5 +1,5 @@
local musicFilename = "/sounds/startup"
local musicChannel = g_sounds.getChannel(1)
local musicChannel = nil
function setMusic(filename)
musicFilename = filename
@@ -57,11 +57,14 @@ function init()
onExit = exit })
g_window.setMinimumSize({ width = 600, height = 480 })
musicChannel = g_sounds.getChannel(1)
g_sounds.preload(musicFilename)
-- initialize in fullscreen mode on mobile devices
if g_window.getPlatformType() == "X11-EGL" then
g_window.setFullscreen(true)
if g_app.getOs() == "android" then
g_window.maximize()
--g_window.setFullscreen(true)
else
-- window size
local size = { width = 800, height = 600 }

View File

@@ -238,6 +238,7 @@ end
function tryLogout()
if not g_game.isOnline() then
exit()
return
end
if logoutWindow then
@@ -746,6 +747,7 @@ function setupViewMode(mode)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
elseif mode == 2 then
local limit = limitZoom and not g_game.isGM()
gameMapPanel:setKeepAspectRatio(false)
gameMapPanel:setLimitVisibleRange(limit)
gameMapPanel:setZoom(11)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 })

View File

@@ -2,4 +2,3 @@
-- you can place any custom user code here
print 'Startup done :]'

View File

@@ -26,6 +26,7 @@
#include <framework/graphics/framebuffermanager.h>
#include <framework/graphics/painter.h>
#include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
enum {
MAX_LIGHT_INTENSITY = 8,
@@ -61,7 +62,7 @@ TexturePtr LightView::generateLightBubble(float centerFactor)
}
}
TexturePtr tex = TexturePtr(new Texture(lightImage, true));
TexturePtr tex = TexturePtr(new TextureOGL(lightImage, true));
tex->setSmooth(true);
return tex;
}

View File

@@ -29,6 +29,7 @@
#include <framework/graphics/painter.h>
#include <framework/graphics/image.h>
#include <framework/graphics/framebuffermanager.h>
#include <framework/graphics/ogl/textureogl.h>
#include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h>
#include <zlib.h>
@@ -65,7 +66,7 @@ void MinimapBlock::update()
if(shouldDraw) {
if(!m_texture) {
m_texture = TexturePtr(new Texture(image, true));
m_texture = TexturePtr(new TextureOGL(image, true));
} else {
m_texture->uploadPixels(image, true);
}

View File

@@ -48,9 +48,11 @@ bool SpriteManager::loadSpr(std::string file)
file = g_resources.guessFilePath(file, "spr");
m_spritesFile = g_resources.openFile(file);
// cache file buffer to avoid lags from hard drive
m_spritesFile->cache();
// cache file buffer to avoid lags from hard drive
#ifndef MOBILE
m_spritesFile->cache();
#endif
m_signature = m_spritesFile->getU32();
m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
m_spritesOffset = m_spritesFile->tell();

View File

@@ -28,6 +28,7 @@
#include <framework/graphics/graphics.h>
#include <framework/graphics/texture.h>
#include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
#include <framework/graphics/texturemanager.h>
#include <framework/core/filestream.h>
#include <framework/otml/otml.h>
@@ -283,7 +284,7 @@ const TexturePtr& ThingType::getTexture(int animationPhase)
}
}
}
animationPhaseTexture = TexturePtr(new Texture(fullImage, true));
animationPhaseTexture = TexturePtr(new TextureOGL(fullImage));
animationPhaseTexture->setSmooth(true);
}
return animationPhaseTexture;

View File

@@ -123,15 +123,20 @@ set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/otml/otmlparser.h
# crash handler
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/unixcrashhandler.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32crashhandler.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32platform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/unixplatform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platform.h
)
if(WIN32)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/win32platform.cpp
)
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/unixplatform.cpp
)
endif()
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
@@ -258,6 +263,15 @@ if(CRASH_HANDLER)
message(STATUS "Crash handler: ON")
if(WIN32)
set(framework_LIBRARIES ${framework_LIBRARIES} imagehlp)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/win32crashhandler.cpp
)
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/unixcrashhandler.cpp
)
endif()
else()
message(STATUS "Crash handler: OFF")
@@ -290,18 +304,24 @@ endif()
if(FRAMEWORK_GRAPHICS)
set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
if(OPENGLES)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.h
)
if(OPENGLES STREQUAL "2.0")
find_package(OpenGLES2 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY})
ELSEif(OPENGLES STREQUAL "1.0")
elseif(OPENGLES STREQUAL "1.0")
find_package(OpenGLES1 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES1_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES1_LIBRARY})
endif()
else()
## TODO: CMake Documentation says that this is not the right
# Thing for Mac OS X, but it works for now.
@@ -336,6 +356,8 @@ if(FRAMEWORK_GRAPHICS)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.h
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/graphicscontextdx9.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/graphicscontextdx9.h
)
endif()
@@ -343,6 +365,44 @@ if(FRAMEWORK_GRAPHICS)
set(framework_LIBRARIES ${framework_LIBRARIES} X11)
endif()
option(SDL "Use SDL 2.0 support" OFF)
if(SDL)
find_package(SDL2 REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DSDL)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${SDL2_LIBRARY})
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/sdl/paintersdl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/sdl/paintersdl.h
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.h
)
else()
if(WIN32)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
)
if(NOT OPENGLES)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextwgl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextwgl.h
)
endif()
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
)
if(NOT OPENGLES)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextglx.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextglx.h
)
endif()
endif()
endif()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.h
@@ -362,6 +422,8 @@ if(FRAMEWORK_GRAPHICS)
${CMAKE_CURRENT_LIST_DIR}/graphics/glutil.h
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.h
${CMAKE_CURRENT_LIST_DIR}/graphics/graphicscontext.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphicscontext.h
${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.h
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp
@@ -397,6 +459,8 @@ if(FRAMEWORK_GRAPHICS)
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.h
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.h
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h
${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h
@@ -435,10 +499,6 @@ if(FRAMEWORK_GRAPHICS)
# platform window
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.h
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
# window input
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp

View File

@@ -0,0 +1,16 @@
# Try to find the SDL2 library
# SDL2_FOUND - system has SDL2
# SDL2_INCLUDE_DIR - the SDL2 include directory
# SDL2_LIBRARY - the SDL2 library
FIND_PATH(SDL2_INCLUDE_DIR PATH_SUFFIXES SDL2 SDL NAMES SDL.h)
SET(_SDL2_STATIC_LIBS libSDL2.a libSDL.a)
SET(_SDL2_SHARED_LIBS libSDL2.dll.a SDL2 SDL libSDL.dll.a SDL)
IF(USE_STATIC_LIBS)
FIND_LIBRARY(SDL2_LIBRARY NAMES ${_SDL2_STATIC_LIBS} ${_SDL2_SHARED_LIBS})
ELSE()
FIND_LIBRARY(SDL2_LIBRARY NAMES ${_SDL2_SHARED_LIBS} ${_SDL2_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDE_DIR)
MARK_AS_ADVANCED(SDL2_LIBRARY SDL2_INCLUDE_DIR)

View File

@@ -33,6 +33,7 @@
#include <framework/platform/platform.h>
#include <locale>
#include <boost/concept_check.hpp>
#ifdef FW_NET
#include <framework/net/connection.h>
@@ -163,10 +164,14 @@ void Application::close()
std::string Application::getOs()
{
#if defined(WIN32)
#if defined(ANDROID)
return "android";
#elif defined(IOS)
return "ios";
#elif defined(WIN32)
return "windows";
#elif defined(__APPLE__)
return "mac";
return "macos";
#elif __linux
return "linux";
#else

View File

@@ -24,12 +24,14 @@
#include "graphicalapplication.h"
#include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
#include <framework/input/mouse.h>
#include <framework/platform/platformwindow.h>
#include <framework/ui/uimanager.h>
#include <framework/graphics/graphics.h>
#include <framework/graphics/particlemanager.h>
#include <framework/graphics/texturemanager.h>
#include <framework/graphics/painter.h>
#include <framework/graphics/ogl/textureogl.h>
#ifdef FW_SOUND
#include <framework/sound/soundmanager.h>
@@ -232,7 +234,7 @@ void GraphicalApplication::resize(const Size& size)
m_onInputEvent = false;
if(g_graphics.canCacheBackbuffer()) {
m_foreground = TexturePtr(new Texture(size));
m_foreground = TexturePtr(new TextureOGL(size));
m_foreground->setUpsideDown(true);
}
m_mustRepaint = true;

View File

@@ -31,7 +31,7 @@
class GraphicalApplication : public Application
{
enum {
POLL_CYCLE_DELAY = 10
POLL_CYCLE_DELAY = 1000
};
public:

View File

@@ -25,23 +25,30 @@
//#include <boost/regex.hpp>
#include <framework/core/resourcemanager.h>
#include "application.h"
#ifdef FW_GRAPHICS
#include <framework/platform/platformwindow.h>
#include <framework/luaengine/luainterface.h>
#endif
#ifdef MOBILE
#include <android/log.h>
#endif
Logger g_logger;
void Logger::log(Fw::LogLevel level, const std::string& message)
{
std::lock_guard<std::recursive_mutex> lock(m_mutex);
/*
>>>>>>> Progress in SDL platform
#ifdef NDEBUG
if(level == Fw::LogDebug)
return;
#endif
*/
static bool ignoreLogs = false;
if(ignoreLogs)
return;
@@ -66,7 +73,11 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
#endif
*/
#ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, g_app.getCompactName().c_str(), outmsg.c_str());
#else
std::cout << outmsg << std::endl;
#endif
if(m_outFile.good()) {
m_outFile << outmsg << std::endl;

View File

@@ -29,6 +29,10 @@
#include <physfs.h>
#ifdef MOBILE
#include <SDL.h>
#endif
ResourceManager g_resources;
void ResourceManager::init(const char *argv0)
@@ -45,10 +49,15 @@ void ResourceManager::terminate()
bool ResourceManager::discoverWorkDir(const std::string& existentFile)
{
// search for modules directory
std::string possiblePaths[] = { g_platform.getCurrentDir(),
#ifdef ANDROID
std::string possiblePaths[] = { std::string("/sdcard/") + g_app.getCompactName() + "/" };
#else
std::string possiblePaths[] = { "./",
g_platform.getCurrentDir(),
g_resources.getBaseDir(),
g_resources.getBaseDir() + "../",
g_resources.getBaseDir() + "../share/" + g_app.getCompactName() + "/" };
#endif
bool found = false;
for(const std::string& dir : possiblePaths) {
@@ -309,7 +318,11 @@ std::string ResourceManager::getBaseDir()
std::string ResourceManager::getUserDir()
{
#ifdef ANDROID
return std::string("/sdcard/");
#else
return PHYSFS_getUserDir();
#endif
}
std::string ResourceManager::guessFilePath(const std::string& filename, const std::string& type)

View File

@@ -24,14 +24,15 @@
#include "graphics.h"
#include <framework/core/eventdispatcher.h>
#include "ogl/textureogl.h"
AnimatedTexture::AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps, bool compress)
AnimatedTexture::AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps)
{
if(!setupSize(size, buildMipmaps))
return;
for(uint i=0;i<frames.size();++i) {
m_frames.push_back(new Texture(frames[i], buildMipmaps, compress));
m_frames.push_back(new TextureOGL(frames[i], buildMipmaps));
}
m_framesDelay = framesDelay;

View File

@@ -29,7 +29,7 @@
class AnimatedTexture : public Texture
{
public:
AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps = false, bool compress = false);
AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps = false);
virtual ~AnimatedTexture();
virtual bool buildHardwareMipmaps();

View File

@@ -33,15 +33,15 @@
#include <fstream>
#if defined(_MSC_VER) && _MSC_VER >= 1300
#define swap16(data) _byteswap_ushort(data)
#define swap32(data) _byteswap_ulong(data)
#define lswap16(data) _byteswap_ushort(data)
#define lswap32(data) _byteswap_ulong(data)
#elif __linux__
#include <byteswap.h>
#define swap16(data) bswap_16(data)
#define swap32(data) bswap_32(data)
#define lswap16(data) bswap_16(data)
#define lswap32(data) bswap_32(data)
#else
#define swap16(data) (((data >> 8) & 255) | ((data & 255) << 8))
#define swap32(data) ((swap16(data) << 16) | swap16(data >> 16))
#define lswap16(data) (((data >> 8) & 255) | ((data & 255) << 8))
#define lswap32(data) ((swap16(data) << 16) | swap16(data >> 16))
#endif
#define PNG_ZBUF_SIZE 32768
@@ -865,7 +865,7 @@ int load_apng(std::stringstream& file, struct apng_data *apng)
void write_chunk(std::ostream& f, const char* name, unsigned char* data, unsigned int length)
{
unsigned int crc = crc32(0, Z_NULL, 0);
unsigned int len = swap32(length);
unsigned int len = lswap32(length);
f.write((char*)&len, 4);
f.write(name, 4);
@@ -876,7 +876,7 @@ void write_chunk(std::ostream& f, const char* name, unsigned char* data, unsigne
crc = crc32(crc, data, length);
}
crc = swap32(crc);
crc = lswap32(crc);
f.write((char*)&crc, 4);
}
@@ -937,7 +937,7 @@ void save_png(std::stringstream& f, unsigned int width, unsigned int height, int
unsigned char mCompression;
unsigned char mFilterMethod;
unsigned char mInterlaceMethod;
} ihdr = { swap32(width), swap32(height), 8, coltype, 0, 0, 0 };
} ihdr = { lswap32(width), lswap32(height), 8, coltype, 0, 0, 0 };
z_stream zstream1;
z_stream zstream2;

View File

@@ -34,6 +34,7 @@ class BitmapFont;
class CachedText;
class FrameBuffer;
class FrameBufferManager;
class GraphicsContext;
class Shader;
class ShaderProgram;
class PainterShaderProgram;
@@ -51,6 +52,7 @@ typedef stdext::shared_object_ptr<AnimatedTexture> AnimatedTexturePtr;
typedef stdext::shared_object_ptr<BitmapFont> BitmapFontPtr;
typedef stdext::shared_object_ptr<CachedText> CachedTextPtr;
typedef stdext::shared_object_ptr<FrameBuffer> FrameBufferPtr;
typedef stdext::shared_object_ptr<GraphicsContext> GraphicsContextPtr;
typedef stdext::shared_object_ptr<Shader> ShaderPtr;
typedef stdext::shared_object_ptr<ShaderProgram> ShaderProgramPtr;
typedef stdext::shared_object_ptr<PainterShaderProgram> PainterShaderProgramPtr;

View File

@@ -26,6 +26,7 @@
#include <framework/platform/platformwindow.h>
#include <framework/core/application.h>
#include <framework/graphics/ogl/textureogl.h>
uint FrameBuffer::boundFbo = 0;
@@ -61,7 +62,7 @@ void FrameBuffer::resize(const Size& size)
if(m_texture && m_texture->getSize() == size)
return;
m_texture = TexturePtr(new Texture(size));
m_texture = TexturePtr(new TextureOGL(size));
m_texture->setSmooth(m_smooth);
m_texture->setUpsideDown(true);
@@ -75,7 +76,7 @@ void FrameBuffer::resize(const Size& size)
internalRelease();
} else {
if(m_backuping) {
m_screenBackup = TexturePtr(new Texture(size));
m_screenBackup = TexturePtr(new TextureOGL(size));
m_screenBackup->setUpsideDown(true);
}
}

View File

@@ -44,6 +44,7 @@
typedef char GLchar;
// define OpenGL ES 2.0 API just to make compile, it wont actually be used
inline void glBlendEquation (GLenum mode) { }
inline void glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { }
inline void glBindFramebuffer (GLenum target, GLuint framebuffer) { }
inline void glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers) { }

View File

@@ -184,14 +184,16 @@ bool Graphics::isPainterEngineAvailable(Graphics::PainterEngine painterEngine)
bool Graphics::selectPainterEngine(PainterEngine painterEngine)
{
// TODO: remove this
#ifdef DIRECTX
painterEngine = Painter_DirectX9;
#endif
Painter *painter = nullptr;
Painter *fallbackPainter = nullptr;
PainterEngine fallbackPainterEngine = Painter_Any;
#ifdef PAINTER_DX9
// use this to force directx if its enabled (avoid changes in options module, etc, will be removed)
painterEngine = Painter_DirectX9;
// always prefer DirectX9 on Windows
if(g_painterDX9) {
if(!painter && (painterEngine == Painter_DirectX9 || painterEngine == Painter_Any)) {
@@ -238,6 +240,7 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
if(g_painter)
g_painter->unbind();
painter->bind();
g_window.setGraphicsContext(painter->getGraphicsContext());
g_painter = painter;
}
@@ -253,6 +256,11 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
void Graphics::resize(const Size& size)
{
m_viewportSize = size;
#ifdef PAINTER_DX9
if(g_painterDX9)
g_painterDX9->setResolution(size);
#endif
#ifdef PAINTER_OGL1
if(g_painterOGL1)
g_painterOGL1->setResolution(size);

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "graphicscontext.h"
GraphicsContext::GraphicsContext(const std::string& name) :
m_name(name)
{
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef GRAPHICSCONTEXT_H
#define GRAPHICSCONTEXT_H
#include "declarations.h"
class GraphicsContext : public stdext::shared_object
{
public:
GraphicsContext(const std::string& name);
virtual ~GraphicsContext() {}
std::string getName() { return m_name; }
virtual void create() {}
virtual void destroy() {}
virtual void restore() {}
virtual void swapBuffers() {}
virtual void setVerticalSync(bool enable) {}
protected:
std::string m_name;
};
#endif

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "graphicscontextegl.h"
#ifdef WIN32
#include <framework/platform/win32window.h>
#else
#include <framework/platform/x11window.h>
#endif
GraphicsContextEGL::GraphicsContextEGL() :
GraphicsContext("EGL")
{
m_eglConfig = 0;
m_eglContext = 0;
m_eglDisplay = 0;
m_eglSurface = 0;
}
void GraphicsContextEGL::create()
{
#ifdef WIN32
HDC display = g_win32Window.getDisplay();
#else
Display *display = g_x11Window.getDisplay();
#endif
m_eglDisplay = eglGetDisplay(display);
if(m_eglDisplay == EGL_NO_DISPLAY)
g_logger.fatal("EGL not supported");
if(!eglInitialize(m_eglDisplay, NULL, NULL))
g_logger.fatal("Unable to initialize EGL");
static int configList[] = {
#if OPENGL_ES==2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_NONE
};
EGLint numConfig;
if(!eglChooseConfig(m_eglDisplay, configList, &m_eglConfig, 1, &numConfig))
g_logger.fatal("Failed to choose EGL config");
if(numConfig != 1)
g_logger.warning("Didn't got the exact EGL config");
#ifndef WIN32
EGLint vid;
if(!eglGetConfigAttrib(m_eglDisplay, m_eglConfig, EGL_NATIVE_VISUAL_ID, &vid))
g_logger.fatal("Unable to get visual EGL visual id");
XVisualInfo visTemplate;
int numVisuals;
memset(&visTemplate, 0, sizeof(visTemplate));
visTemplate.visualid = vid;
g_x11Window.setVisual(XGetVisualInfo(display, VisualIDMask, &visTemplate, &numVisuals));
if(!g_x11Window.getVisual())
g_logger.fatal("Couldn't choose RGBA, double buffered visual");
g_x11Window.setRootWindow(DefaultRootWindow(display));
#endif
EGLint contextAtrrList[] = {
#if OPENGL_ES==2
EGL_CONTEXT_CLIENT_VERSION, 2,
#else
EGL_CONTEXT_CLIENT_VERSION, 1,
#endif
EGL_NONE
};
#ifdef WIN32
HWND window = g_win32Window.getWindow();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, window, NULL);
if(m_eglSurface == EGL_NO_SURFACE)
g_logger.fatal(stdext::format("Unable to create EGL surface: %s", eglGetError()));
#endif
m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAtrrList);
if(m_eglContext == EGL_NO_CONTEXT )
g_logger.fatal(stdext::format("Unable to create EGL context: %s", eglGetError()));
}
void GraphicsContextEGL::destroy()
{
if(m_eglDisplay) {
if(m_eglContext) {
eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = 0;
}
if(m_eglSurface) {
eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = 0;
}
eglTerminate(m_eglDisplay);
m_eglDisplay = 0;
}
}
void GraphicsContextEGL::restore()
{
#ifndef WIN32
Window window = g_x11Window.getWindow();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, window, NULL);
if(m_eglSurface == EGL_NO_SURFACE)
g_logger.fatal(stdext::format("Unable to create EGL surface: %s", eglGetError()));
#endif
if(!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
g_logger.fatal("Unable to make current EGL context");
}
void GraphicsContextEGL::swapBuffers()
{
eglSwapBuffers(m_eglDisplay, m_eglSurface);
}
void GraphicsContextEGL::setVerticalSync(bool enable)
{
eglSwapInterval(m_eglDisplay, enable ? 1 : 0);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef GRAPHICSCONTEXTEGL_H
#define GRAPHICSCONTEXTEGL_H
#include <framework/graphics/graphicscontext.h>
#include <EGL/egl.h>
class GraphicsContextEGL : public GraphicsContext
{
public:
GraphicsContextEGL();
void create();
void destroy();
void restore();
void swapBuffers();
void setVerticalSync(bool enable);
private:
EGLConfig m_eglConfig;
EGLContext m_eglContext;
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
};
#endif

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "graphicscontextglx.h"
GraphicsContextGLX::GraphicsContextGLX() :
GraphicsContext("GLX"), m_window(dynamic_cast<X11Window&>(g_window))
{
m_fbConfig = 0;
m_glxContext = 0;
}
void GraphicsContextGLX::create()
{
if(!glXQueryExtension(m_window.getDisplay(), NULL, NULL))
g_logger.fatal("GLX not supported");
static int attrList[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
None
};
int nelements;
m_fbConfig = glXChooseFBConfig(m_window.getDisplay(), m_window.getScreen(), attrList, &nelements);
if(!m_fbConfig)
g_logger.fatal("Couldn't choose RGBA, double buffered fbconfig");
m_window.setVisual(glXGetVisualFromFBConfig(m_window.getDisplay(), *m_fbConfig));
if(!m_window.getDisplay())
g_logger.fatal("Couldn't choose RGBA, double buffered visual");
m_window.setRootWindow(RootWindow(m_window.getDisplay(), m_window.getVisual()->screen));
m_glxContext = glXCreateContext(m_window.getDisplay(), m_window.getVisual(), NULL, True);
if(!m_glxContext)
g_logger.fatal("Unable to create GLX context");
if(!glXIsDirect(m_window.getDisplay(), m_glxContext))
g_logger.warning("GL direct rendering is not possible");
}
void GraphicsContextGLX::destroy()
{
if(m_glxContext) {
glXMakeCurrent(m_window.getDisplay(), None, NULL);
glXDestroyContext(m_window.getDisplay(), m_glxContext);
m_glxContext = 0;
}
}
void GraphicsContextGLX::restore()
{
if(!glXMakeCurrent(m_window.getDisplay(), m_window.getWindow(), m_glxContext))
g_logger.fatal("Unable to set GLX context on X11 window");
}
bool GraphicsContextGLX::isExtensionSupported(const char *ext)
{
const char *exts = glXQueryExtensionsString(m_window.getDisplay(), m_window.getScreen());
if(strstr(exts, ext))
return true;
return false;
}
void *GraphicsContextGLX::getExtensionProcAddress(const char *ext)
{
return (void *)glXGetProcAddressARB((const GLubyte*)ext);
}
void GraphicsContextGLX::swapBuffers()
{
glXSwapBuffers(m_window.getDisplay(), m_window.getWindow());
}
void GraphicsContextGLX::setVerticalSync(bool enable)
{
typedef GLint (*glSwapIntervalProc)(GLint);
glSwapIntervalProc glSwapInterval = NULL;
if(isExtensionSupported("GLX_MESA_swap_control"))
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalMESA");
else if(isExtensionSupported("GLX_SGI_swap_control"))
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalSGI");
if(glSwapInterval)
glSwapInterval(enable ? 1 : 0);
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef GRAPHICSCONTEXTGLX_H
#define GRAPHICSCONTEXTGLX_H
#include <framework/graphics/graphicscontext.h>
#include <framework/platform/x11window.h>
#include <GL/glx.h>
class GraphicsContextGLX : public GraphicsContext
{
public:
GraphicsContextGLX();
void create();
void destroy();
void restore();
bool isExtensionSupported(const char *ext);
void *getExtensionProcAddress(const char *ext);
void swapBuffers();
void setVerticalSync(bool enable);
private:
X11Window& m_window;
GLXContext m_glxContext;
GLXFBConfig *m_fbConfig;
};
#endif

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "graphicscontextwgl.h"
#include <framework/platform/win32window.h>
GraphicsContextWGL::GraphicsContextWGL() :
GraphicsContext("WGL")
{
m_wglContext = 0;
}
void GraphicsContextWGL::create()
{
HDC display = g_win32Window.getDisplay();
uint pixelFormat;
static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // Select Our Color Depth
8, 0, 8, 0, 8, 0, // Color Bits Ignored
8, // Alpha Buffer Bits
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
0, // Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 }; // Layer Masks Ignored
pixelFormat = ChoosePixelFormat(display, &pfd);
if(!pixelFormat)
g_logger.fatal("Could not find a suitable pixel format");
if(!SetPixelFormat(display, pixelFormat, &pfd))
g_logger.fatal("Could not set the pixel format");
if(!(m_wglContext = wglCreateContext(display)))
g_logger.fatal("Unable to create GL context");
}
void GraphicsContextWGL::destroy()
{
if(m_wglContext) {
if(!wglMakeCurrent(NULL, NULL))
g_logger.error("Release of dc and rc failed.");
if(!wglDeleteContext(m_wglContext))
g_logger.error("Release rendering context failed.");
m_wglContext = NULL;
}
}
void GraphicsContextWGL::restore()
{
if(!wglMakeCurrent(g_win32Window.getDisplay(), m_wglContext))
g_logger.fatal("Unable to make current WGL context");
}
bool GraphicsContextWGL::isExtensionSupported(const char *ext)
{
typedef const char* (WINAPI * wglGetExtensionsStringProc)();
wglGetExtensionsStringProc wglGetExtensionsString = (wglGetExtensionsStringProc)getExtensionProcAddress("wglGetExtensionsStringEXT");
if(!wglGetExtensionsString)
return false;
const char *exts = wglGetExtensionsString();
if(exts && strstr(exts, ext))
return true;
return false;
}
void *GraphicsContextWGL::getExtensionProcAddress(const char *ext)
{
return (void*)wglGetProcAddress(ext);
}
void GraphicsContextWGL::swapBuffers()
{
SwapBuffers(g_win32Window.getDisplay());
}
void GraphicsContextWGL::setVerticalSync(bool enable)
{
if(!isExtensionSupported("WGL_EXT_swap_control"))
return;
typedef BOOL (WINAPI * wglSwapIntervalProc)(int);
wglSwapIntervalProc wglSwapInterval = (wglSwapIntervalProc)getExtensionProcAddress("wglSwapIntervalEXT");
if(!wglSwapInterval)
return;
wglSwapInterval(enable ? 1 : 0);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef GRAPHICSCONTEXTWGL_H
#define GRAPHICSCONTEXTWGL_H
#include <framework/graphics/graphicscontext.h>
#include <windows.h>
class GraphicsContextWGL : public GraphicsContext
{
public:
GraphicsContextWGL();
void create();
void destroy();
void restore();
bool isExtensionSupported(const char *ext);
void *getExtensionProcAddress(const char *ext);
void swapBuffers();
void setVerticalSync(bool enable);
private:
HGLRC m_wglContext;
};
#endif

View File

@@ -24,8 +24,26 @@
#include <framework/graphics/graphics.h>
#include <framework/platform/platformwindow.h>
#ifdef OPENGL_ES
#include <framework/graphics/ogl/graphicscontextegl.h>
#elif WIN32
#include <framework/graphics/ogl/graphicscontextwgl.h>
#else
#include <framework/graphics/ogl/graphicscontextglx.h>
#endif
PainterOGL::PainterOGL()
{
#ifdef SDL
m_graphicsContext = GraphicsContextPtr(new GraphicsContext("null"));
#elif OPENGL_ES
m_graphicsContext = GraphicsContextPtr(new GraphicsContextEGL);
#elif WIN32
m_graphicsContext = GraphicsContextPtr(new GraphicsContextWGL);
#else
m_graphicsContext = GraphicsContextPtr(new GraphicsContextGLX);
#endif
m_glTextureId = 0;
m_oldStateIndex = 0;
m_color = Color::white;
@@ -35,6 +53,7 @@ PainterOGL::PainterOGL()
m_shaderProgram = nullptr;
m_texture = nullptr;
m_alphaWriting = false;
setResolution(g_window.getSize());
}
@@ -286,6 +305,7 @@ void PainterOGL::updateGlBlendEquation()
{
if(!g_graphics.canUseBlendEquation())
return;
if(m_blendEquation == BlendEquation_Add)
glBlendEquation(0x8006); // GL_FUNC_ADD
else if(m_blendEquation == BlendEquation_Max)

View File

@@ -0,0 +1,229 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "textureogl.h"
#include <framework/graphics/image.h>
#include <framework/core/application.h>
#include <framework/graphics/graphics.h>
TextureOGL::TextureOGL()
{
m_id = 0;
}
TextureOGL::TextureOGL(const Size& size)
{
m_id = 0;
if(!setupSize(size))
return;
createTexture();
bind();
setupPixels(0, m_glSize, nullptr, 4);
setupWrap();
setupFilters();
}
TextureOGL::TextureOGL(const ImagePtr& image, bool buildMipmaps)
{
m_id = 0;
if(!setupSize(image->getSize(), buildMipmaps))
return;
createTexture();
uploadPixels(image, buildMipmaps);
}
TextureOGL::~TextureOGL()
{
#ifndef NDEBUG
assert(!g_app.isTerminated());
#endif
// free texture from gl memory
if(g_graphics.ok() && m_id != 0)
glDeleteTextures(1, &m_id);
}
void TextureOGL::uploadPixels(const ImagePtr& image, bool buildMipmaps)
{
ImagePtr glImage = image;
if(m_size != m_glSize) {
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
glImage->paste(image);
} else
glImage = image;
bind();
if(buildMipmaps) {
int level = 0;
do {
setupPixels(level++, glImage->getSize(), glImage->getPixelData(), glImage->getBpp());
} while(glImage->nextMipmap());
m_hasMipmaps = true;
} else
setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp());
setupWrap();
setupFilters();
}
void TextureOGL::bind()
{
// must reset painter texture state
g_painter->setTexture(this);
glBindTexture(GL_TEXTURE_2D, m_id);
}
void TextureOGL::copyFromScreen(const Rect& screenRect)
{
bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
}
bool TextureOGL::buildHardwareMipmaps()
{
if(!g_graphics.canUseHardwareMipmaps())
return false;
bind();
if(!m_hasMipmaps) {
m_hasMipmaps = true;
setupFilters();
}
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
void TextureOGL::setSmooth(bool smooth)
{
if(smooth && !g_graphics.canUseBilinearFiltering())
return;
if(smooth == m_smooth)
return;
m_smooth = smooth;
bind();
setupFilters();
}
void TextureOGL::setRepeat(bool repeat)
{
if(m_repeat == repeat)
return;
m_repeat = repeat;
bind();
setupWrap();
}
void TextureOGL::setUpsideDown(bool upsideDown)
{
if(m_upsideDown == upsideDown)
return;
m_upsideDown = upsideDown;
setupTranformMatrix(m_glSize, m_size);
}
void TextureOGL::createTexture()
{
glGenTextures(1, &m_id);
assert(m_id != 0);
}
bool TextureOGL::setupSize(const Size& size, bool forcePowerOfTwo)
{
Size glSize;
if(!g_graphics.canUseNonPowerOfTwoTextures() || forcePowerOfTwo)
glSize.resize(stdext::to_power_of_two(size.width()), stdext::to_power_of_two(size.height()));
else
glSize = size;
// checks texture max size
if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) {
g_logger.error(stdext::format("loading texture with size %dx%d failed, "
"the maximum size allowed by the graphics card is %dx%d,"
"to prevent crashes the texture will be displayed as a blank texture",
size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize()));
return false;
}
m_size = size;
m_glSize = glSize;
setupTranformMatrix(m_glSize, m_size);
return true;
}
void TextureOGL::setupWrap()
{
int texParam;
if(!m_repeat && g_graphics.canUseClampToEdge())
texParam = GL_CLAMP_TO_EDGE;
else
texParam = GL_REPEAT;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
}
void TextureOGL::setupFilters()
{
int minFilter;
int magFilter;
if(m_smooth) {
minFilter = m_hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
magFilter = GL_LINEAR;
} else {
minFilter = m_hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
magFilter = GL_NEAREST;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
}
void TextureOGL::setupPixels(int level, const Size& size, uchar* pixels, int channels)
{
GLenum format = 0;
switch(channels) {
case 4:
format = GL_RGBA;
break;
case 3:
format = GL_RGB;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 1:
format = GL_LUMINANCE;
break;
}
GLenum internalFormat = GL_RGBA;
//TODO: compression support
glTexImage2D(GL_TEXTURE_2D, level, internalFormat, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TEXTUREOGL_H
#define TEXTUREOGL_H
#include <framework/graphics/texture.h>
class TextureOGL : public Texture
{
public:
TextureOGL();
TextureOGL(const Size& size);
TextureOGL(const ImagePtr& image, bool buildMipmaps = false);
virtual ~TextureOGL();
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false);
void bind();
void copyFromScreen(const Rect& screenRect);
virtual bool buildHardwareMipmaps();
virtual void setSmooth(bool smooth);
virtual void setRepeat(bool repeat);
void setUpsideDown(bool upsideDown);
protected:
void createTexture();
bool setupSize(const Size& size, bool forcePowerOfTwo = false);
void setupWrap();
void setupFilters();
void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4);
};
#endif

View File

@@ -25,6 +25,7 @@
#include <framework/graphics/declarations.h>
#include <framework/graphics/coordsbuffer.h>
#include <framework/graphics/graphicscontext.h>
#include <framework/graphics/paintershaderprogram.h>
#include <framework/graphics/texture.h>
@@ -95,6 +96,7 @@ public:
float getOpacity() { return m_opacity; }
Rect getClipRect() { return m_clipRect; }
CompositionMode getCompositionMode() { return m_compositionMode; }
GraphicsContextPtr getGraphicsContext() { return m_graphicsContext; }
virtual void setCompositionMode(CompositionMode compositionMode) = 0;
@@ -116,6 +118,7 @@ protected:
Size m_resolution;
float m_opacity;
Rect m_clipRect;
GraphicsContextPtr m_graphicsContext;
};
extern Painter *g_painter;

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef GRAPHICSCONTEXTEGL_H
#define GRAPHICSCONTEXTEGL_H
#include <framework/graphics/graphicscontext.h>
#include <EGL/egl.h>
class GraphicsContextEGL : public GraphicsContext
{
public:
GraphicsContextEGL();
void create(WindowType window, DisplayType display);
void destroy();
void restore();
void swapBuffers();
void setVerticalSync(bool enable);
private:
EGLConfig m_eglConfig;
EGLContext m_eglContext;
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
};
#endif

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef PAINTERSDL_H
#define PAINTERSDL_H
#include <framework/graphics/painter.h>
class PainterSDL: public Painter
{
public:
};
#endif

View File

@@ -33,223 +33,29 @@ Texture::Texture()
m_time = 0;
}
Texture::Texture(const Size& size)
{
m_id = 0;
m_time = 0;
if(!setupSize(size))
return;
createTexture();
bind();
setupPixels(0, m_glSize, nullptr, 4);
setupWrap();
setupFilters();
}
Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress)
{
m_id = 0;
m_time = 0;
createTexture();
uploadPixels(image, buildMipmaps, compress);
}
Texture::~Texture()
{
#ifndef NDEBUG
assert(!g_app.isTerminated());
#endif
// free texture from gl memory
if(g_graphics.ok() && m_id != 0)
glDeleteTextures(1, &m_id);
}
void Texture::uploadPixels(const ImagePtr& image, bool buildMipmaps, bool compress)
bool Texture::setupSize(const Size& size, bool)
{
if(!setupSize(image->getSize(), buildMipmaps))
return;
ImagePtr glImage = image;
if(m_size != m_glSize) {
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
glImage->paste(image);
} else
glImage = image;
bind();
if(buildMipmaps) {
int level = 0;
do {
setupPixels(level++, glImage->getSize(), glImage->getPixelData(), glImage->getBpp(), compress);
} while(glImage->nextMipmap());
m_hasMipmaps = true;
} else
setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp(), compress);
setupWrap();
setupFilters();
}
void Texture::bind()
{
// must reset painter texture state
g_painter->setTexture(this);
glBindTexture(GL_TEXTURE_2D, m_id);
}
void Texture::copyFromScreen(const Rect& screenRect)
{
bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
}
bool Texture::buildHardwareMipmaps()
{
if(!g_graphics.canUseHardwareMipmaps())
return false;
bind();
if(!m_hasMipmaps) {
m_hasMipmaps = true;
setupFilters();
}
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
void Texture::setSmooth(bool smooth)
{
if(smooth && !g_graphics.canUseBilinearFiltering())
return;
if(smooth == m_smooth)
return;
m_smooth = smooth;
bind();
setupFilters();
}
void Texture::setRepeat(bool repeat)
{
if(m_repeat == repeat)
return;
m_repeat = repeat;
bind();
setupWrap();
}
void Texture::setUpsideDown(bool upsideDown)
{
if(m_upsideDown == upsideDown)
return;
m_upsideDown = upsideDown;
setupTranformMatrix();
}
void Texture::createTexture()
{
glGenTextures(1, &m_id);
assert(m_id != 0);
}
bool Texture::setupSize(const Size& size, bool forcePowerOfTwo)
{
Size glSize;
if(!g_graphics.canUseNonPowerOfTwoTextures() || forcePowerOfTwo)
glSize.resize(stdext::to_power_of_two(size.width()), stdext::to_power_of_two(size.height()));
else
glSize = size;
// checks texture max size
if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) {
g_logger.error(stdext::format("loading texture with size %dx%d failed, "
"the maximum size allowed by the graphics card is %dx%d,"
"to prevent crashes the texture will be displayed as a blank texture",
size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize()));
return false;
}
m_size = size;
m_glSize = glSize;
setupTranformMatrix();
setupTranformMatrix(size, size);
return true;
}
void Texture::setupWrap()
{
int texParam;
if(!m_repeat && g_graphics.canUseClampToEdge())
texParam = GL_CLAMP_TO_EDGE;
else
texParam = GL_REPEAT;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
}
void Texture::setupFilters()
{
int minFilter;
int magFilter;
if(m_smooth) {
minFilter = m_hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
magFilter = GL_LINEAR;
} else {
minFilter = m_hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
magFilter = GL_NEAREST;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
}
void Texture::setupTranformMatrix()
void Texture::setupTranformMatrix(const Size& textureSize, const Size& realSize)
{
if(m_upsideDown) {
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f,
0.0f, -1.0f/m_glSize.height(), 0.0f,
0.0f, m_size.height()/(float)m_glSize.height(), 1.0f };
m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
0.0f, -1.0f/textureSize.height(), 0.0f,
0.0f, realSize.height()/(float)textureSize.height(), 1.0f };
} else {
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f,
0.0f, 1.0f/m_glSize.height(), 0.0f,
m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
0.0f, 1.0f/textureSize.height(), 0.0f,
0.0f, 0.0f, 1.0f };
}
}
void Texture::setupPixels(int level, const Size& size, uchar* pixels, int channels, bool compress)
{
GLenum format = 0;
switch(channels) {
case 4:
format = GL_RGBA;
break;
case 3:
format = GL_RGB;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 1:
format = GL_LUMINANCE;
break;
}
GLenum internalFormat = GL_RGBA;
#ifdef OPENGL_ES
//TODO
#else
if(compress)
internalFormat = GL_COMPRESSED_RGBA;
#endif
glTexImage2D(GL_TEXTURE_2D, level, internalFormat, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
}

View File

@@ -29,26 +29,25 @@ class Texture : public stdext::shared_object
{
public:
Texture();
Texture(const Size& size);
Texture(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
virtual ~Texture();
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
void bind();
void copyFromScreen(const Rect& screenRect);
virtual bool buildHardwareMipmaps();
virtual void setSmooth(bool) {}
virtual void setRepeat(bool) {}
virtual void setUpsideDown(bool) {}
virtual bool setupSize(const Size& size, bool);
virtual void copyFromScreen(const Rect&) {}
virtual bool buildHardwareMipmaps() { return false; }
virtual void uploadPixels(const ImagePtr&, bool) {}
virtual void setSmooth(bool smooth);
virtual void setRepeat(bool repeat);
void setUpsideDown(bool upsideDown);
void setTime(ticks_t time) { m_time = time; }
void setupTranformMatrix(const Size& textureSize, const Size& realSize);
uint getId() { return m_id; }
ticks_t getTime() { return m_time; }
int getWidth() { return m_size.width(); }
int getHeight() { return m_size.height(); }
const Size& getSize() { return m_size; }
const Size& getGlSize() { return m_glSize; }
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
bool isEmpty() { return m_id == 0; }
bool hasRepeat() { return m_repeat; }
@@ -56,13 +55,6 @@ public:
virtual bool isAnimatedTexture() { return false; }
protected:
void createTexture();
bool setupSize(const Size& size, bool forcePowerOfTwo = false);
void setupWrap();
void setupFilters();
void setupTranformMatrix();
void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4, bool compress = false);
uint m_id;
ticks_t m_time;
Size m_size;

View File

@@ -29,6 +29,7 @@
#include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
#include <framework/graphics/apngloader.h>
#include "ogl/textureogl.h"
TextureManager g_textures;
@@ -146,7 +147,7 @@ TexturePtr TextureManager::loadTexture(std::stringstream& file)
texture = animatedTexture;
} else {
ImagePtr image = ImagePtr(new Image(imageSize, apng.bpp, apng.pdata));
texture = TexturePtr(new Texture(image));
texture = TexturePtr(new TextureOGL(image));
}
free_apng(&apng);
}

View File

@@ -20,6 +20,9 @@
* THE SOFTWARE.
*/
#ifndef MOUSE_H
#define MOUSE_H
#include <framework/global.h>
class Mouse
@@ -43,3 +46,5 @@ private:
};
extern Mouse g_mouse;
#endif

View File

@@ -23,8 +23,6 @@
#ifndef CRASHHANDLER_H
#define CRASHHANDLER_H
#ifdef CRASH_HANDLER
void installCrashHandler();
#endif
#endif

View File

@@ -22,13 +22,20 @@
#include "platformwindow.h"
#ifdef SDL
#include "sdlwindow.h"
SDLWindow window;
#else
#ifdef WIN32
#include "win32window.h"
WIN32Window window;
WIN32Window& g_win32Window = window;
#else
#include "x11window.h"
#include <framework/core/clock.h>
X11Window window;
X11Window& g_x11Window = window;
#endif
#endif
#include <framework/core/clock.h>
@@ -58,6 +65,19 @@ int PlatformWindow::loadMouseCursor(const std::string& file, const Point& hotSpo
return internalLoadMouseCursor(image, hotSpot);
}
void PlatformWindow::setGraphicsContext(const GraphicsContextPtr& graphicsContext)
{
if(m_graphicsContext && m_graphicsContext->getName() == graphicsContext->getName())
return;
if(m_graphicsContext)
m_graphicsContext->destroy();
m_graphicsContext = graphicsContext;
m_graphicsContext->create();
m_graphicsContext->restore();
}
void PlatformWindow::updateUnmaximizedCoords()
{
if(!isMaximized() && !isFullscreen()) {

View File

@@ -27,12 +27,13 @@
#include <framework/core/inputevent.h>
#include <framework/core/timer.h>
#include <framework/graphics/declarations.h>
#include <framework/graphics/graphicscontext.h>
//@bindsingleton g_window
class PlatformWindow
{
enum {
KEY_PRESS_REPEAT_INTERVAL = 30,
KEY_PRESS_REPEAT_INTERVAL = 30
};
typedef std::function<void(const Size&)> OnResizeCallback;
@@ -57,12 +58,16 @@ public:
virtual void setMouseCursor(int cursorId) = 0;
virtual void restoreMouseCursor() = 0;
virtual void showTextInput() { }
virtual void hideTextInput() { }
virtual void setTitle(const std::string& title) = 0;
virtual void setMinimumSize(const Size& minimumSize) = 0;
virtual void setFullscreen(bool fullscreen) = 0;
virtual void setVerticalSync(bool enable) = 0;
virtual void setIcon(const std::string& iconFile) = 0;
virtual void setClipboardText(const std::string& text) = 0;
void setGraphicsContext(const GraphicsContextPtr& graphicsContext);
virtual Size getDisplaySize() = 0;
virtual std::string getClipboardText() = 0;
@@ -127,6 +132,8 @@ protected:
std::function<void()> m_onClose;
OnResizeCallback m_onResize;
OnInputEventCallback m_onInputEvent;
GraphicsContextPtr m_graphicsContext;
};
extern PlatformWindow& g_window;

View File

@@ -0,0 +1,385 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sdlwindow.h"
#include <framework/graphics/image.h>
#include <framework/core/graphicalapplication.h>
SDLWindow::SDLWindow()
{
m_window = NULL;
m_renderer = NULL;
m_minimumSize = Size(600,480);
m_size = Size(600,480);
}
void SDLWindow::init()
{
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
#ifdef OPENGL_ES
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, OPENGL_ES);
#endif
#ifdef MOBILE
int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_SHOWN;
#else
int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
#endif
m_window = SDL_CreateWindow(g_app.getName().c_str(),
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
m_size.width(), m_size.height(),
flags);
if(!m_window)
g_logger.fatal("Unable to create SDL window");
int w, h;
SDL_GetWindowSize(m_window, &w, &h);
m_size = Size(w,h);
m_context = SDL_GL_CreateContext(m_window);
if(!m_context)
g_logger.fatal("Unable to create SDL GL context");
SDL_GL_MakeCurrent(m_window, m_context);
}
void SDLWindow::terminate()
{
SDL_GL_DeleteContext(m_context);
SDL_DestroyRenderer(m_renderer);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
void SDLWindow::move(const Point& pos)
{
if(pos.x < 0 || pos.y < 0)
return;
SDL_SetWindowPosition(m_window, pos.x, pos.y);
}
void SDLWindow::resize(const Size& size)
{
if(!size.isValid())
return;
m_size = size;
SDL_SetWindowSize(m_window, m_size.width(), m_size.height());
if(m_onResize)
m_onResize(m_size);
}
void SDLWindow::show()
{
SDL_ShowWindow(m_window);
}
void SDLWindow::hide()
{
SDL_HideWindow(m_window);
}
void SDLWindow::maximize()
{
SDL_MaximizeWindow(m_window);
}
Fw::MouseButton translateMouseButton(uint8 sdlButton)
{
switch(sdlButton) {
case SDL_BUTTON_LEFT:
return Fw::MouseLeftButton;
break;
case SDL_BUTTON_MIDDLE:
return Fw::MouseMidButton;
break;
case SDL_BUTTON_RIGHT:
return Fw::MouseRightButton;
}
return Fw::MouseNoButton;
}
void SDLWindow::poll()
{
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_WINDOWEVENT: {
switch(event.window.event) {
case SDL_WINDOWEVENT_SHOWN:
m_visible = true;
break;
case SDL_WINDOWEVENT_HIDDEN:
m_visible = false;
break;
case SDL_WINDOWEVENT_MOVED:
m_position = Point(event.window.data1, event.window.data2);
break;
case SDL_WINDOWEVENT_RESIZED:
g_logger.info(stdext::format("resize %d %d", event.window.data1, event.window.data2));
m_size = Size(event.window.data1, event.window.data2);
if(m_onResize)
m_onResize(m_size);
break;
case SDL_WINDOWEVENT_MINIMIZED:
m_maximized = false;
m_visible = false;
break;
case SDL_WINDOWEVENT_MAXIMIZED:
m_maximized = true;
m_visible = true;
break;
case SDL_WINDOWEVENT_RESTORED:
m_maximized = false;
m_visible = true;
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
m_focused = true;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
m_focused = false;
break;
case SDL_WINDOWEVENT_CLOSE:
break;
}
break;
}
case SDL_KEYDOWN:
break;
case SDL_KEYUP:
break;
case SDL_TEXTINPUT:
m_inputEvent.reset(Fw::KeyTextInputEvent);
m_inputEvent.keyText = event.text.text;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
case SDL_MOUSEMOTION:
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseMoveInputEvent;
m_inputEvent.mouseMoved = Point(event.motion.xrel, event.motion.yrel);
m_inputEvent.mousePos = Point(event.motion.x, event.motion.y);
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
case SDL_MOUSEBUTTONDOWN: {
Fw::MouseButton button = translateMouseButton(event.button.button);
if(button != Fw::MouseNoButton) {
m_inputEvent.reset();
m_inputEvent.type = Fw::MousePressInputEvent;
m_inputEvent.mouseButton = button;
m_mouseButtonStates[button] = true;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
}
break;
}
case SDL_MOUSEBUTTONUP: {
Fw::MouseButton button = translateMouseButton(event.button.button);
if(button == Fw::MouseNoButton)
break;
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseReleaseInputEvent;
m_inputEvent.mouseButton = button;
m_mouseButtonStates[button] = false;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
case SDL_MOUSEWHEEL: {
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseWheelInputEvent;
m_inputEvent.mouseButton = Fw::MouseMidButton;
if(event.wheel.y > 0)
m_inputEvent.wheelDirection = Fw::MouseWheelUp;
else if(event.wheel.y < 0)
m_inputEvent.wheelDirection = Fw::MouseWheelUp;
else
break;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
case SDL_FINGERDOWN: {
Fw::MouseButton button;
if(event.tfinger.fingerId == 0)
button = Fw::MouseLeftButton;
else if(event.tfinger.fingerId == 1)
button = Fw::MouseRightButton;
else
break;
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseReleaseInputEvent;
m_inputEvent.mouseButton = button;
m_mouseButtonStates[button] = true;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
case SDL_FINGERUP: {
Fw::MouseButton button;
if(event.tfinger.fingerId == 0)
button = Fw::MouseLeftButton;
else if(event.tfinger.fingerId == 1)
button = Fw::MouseRightButton;
else
break;
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseReleaseInputEvent;
m_inputEvent.mouseButton = button;
m_mouseButtonStates[button] = false;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
case SDL_FINGERMOTION: {
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseMoveInputEvent;
m_inputEvent.mouseMoved = Point(event.tfinger.dx, event.tfinger.dy);
m_inputEvent.mousePos = Point(event.tfinger.x, event.tfinger.y);
//g_logger.info(stdext::format("motion %d %d", event.tfinger.x, event.tfinger.y));
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
case SDL_QUIT:
if(m_onClose)
m_onClose();
break;
}
}
if(!m_maximized)
updateUnmaximizedCoords();
}
void SDLWindow::swapBuffers()
{
SDL_GL_SwapWindow(m_window);
}
void SDLWindow::showMouse()
{
SDL_ShowCursor(1);
}
void SDLWindow::hideMouse()
{
SDL_ShowCursor(0);
}
void SDLWindow::setMouseCursor(int cursorId)
{
//TODO
}
void SDLWindow::restoreMouseCursor()
{
//TODO
}
void SDLWindow::showTextInput()
{
SDL_StartTextInput();
}
void SDLWindow::hideTextInput()
{
SDL_StopTextInput();
}
void SDLWindow::setTitle(const std::string& title)
{
SDL_SetWindowTitle(m_window, title.c_str());
}
void SDLWindow::setMinimumSize(const Size& minimumSize)
{
SDL_SetWindowMinimumSize(m_window, minimumSize.width(), minimumSize.height());
}
void SDLWindow::setFullscreen(bool fullscreen)
{
if(m_fullscreen == fullscreen)
return;
SDL_SetWindowFullscreen(m_window, fullscreen);
m_fullscreen = fullscreen;
}
void SDLWindow::setVerticalSync(bool enable)
{
SDL_GL_SetSwapInterval(enable);
}
void SDLWindow::setIcon(const std::string& file)
{
ImagePtr image = Image::load(file);
if(!image) {
g_logger.traceError(stdext::format("unable to load icon file %s", file));
return;
}
if(image->getBpp() != 4) {
g_logger.error("the app icon must have 4 channels");
return;
}
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(image->getPixelData(), image->getWidth(), image->getHeight(), 32, image->getWidth()*4, 0xff0000, 0xff00, 0xff, 0xff000000);
SDL_SetWindowIcon(m_window, surface);
SDL_FreeSurface(surface);
}
void SDLWindow::setClipboardText(const std::string& text)
{
SDL_SetClipboardText(text.c_str());
}
Size SDLWindow::getDisplaySize()
{
//TODO
return getSize();
}
std::string SDLWindow::getClipboardText()
{
return SDL_GetClipboardText();
}
std::string SDLWindow::getPlatformType()
{
return "SDL";
}
int SDLWindow::internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot)
{
//TODO
return 0;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef SDLWINDOW_H
#define SDLWINDOW_H
#include "platformwindow.h"
#include <SDL.h>
#include <framework/graphics/glutil.h>
class SDLWindow : public PlatformWindow
{
public:
SDLWindow();
void init();
void terminate();
void move(const Point& pos);
void resize(const Size& size);
void show();
void hide();
void maximize();
void poll();
void swapBuffers();
void showMouse();
void hideMouse();
void setMouseCursor(int cursorId);
void restoreMouseCursor();
void showTextInput();
void hideTextInput();
void setTitle(const std::string& title);
void setMinimumSize(const Size& minimumSize);
void setFullscreen(bool fullscreen);
void setVerticalSync(bool enable);
void setIcon(const std::string& file);
void setClipboardText(const std::string& text);
Size getDisplaySize();
std::string getClipboardText();
std::string getPlatformType();
protected:
int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot);
private:
SDL_Window *m_window;
SDL_Renderer *m_renderer;
SDL_GLContext m_context;
};
#endif

View File

@@ -20,8 +20,6 @@
* THE SOFTWARE.
*/
#if !defined(WIN32) && defined(CRASH_HANDLER)
#include "crashhandler.h"
#include <framework/global.h>
#include <framework/core/application.h>
@@ -133,5 +131,3 @@ void installCrashHandler()
sigaction(SIGFPE, &sa, NULL); // floating-point exception
sigaction(SIGABRT, &sa, NULL); // process aborted (asserts)
}
#endif

View File

@@ -20,8 +20,6 @@
* THE SOFTWARE.
*/
#ifndef WIN32
#include "platform.h"
#include <fstream>
#include <unistd.h>
@@ -38,7 +36,7 @@ void Platform::processArgs(std::vector<std::string>& args)
bool Platform::spawnProcess(std::string process, const std::vector<std::string>& args)
{
struct stat sts;
if(stat(process.c_str(), &sts) == -1 && errno == ENOENT)
if(stat(process.c_str(), &sts) == -1)
return false;
pid_t pid = fork();
@@ -167,6 +165,3 @@ std::string Platform::getOSName()
}
return std::string();
}
#endif

View File

@@ -20,8 +20,6 @@
* THE SOFTWARE.
*/
#if defined(WIN32) && defined(CRASH_HANDLER)
#include "crashhandler.h"
#include <framework/global.h>
#include <framework/core/application.h>
@@ -158,5 +156,3 @@ void installCrashHandler()
{
SetUnhandledExceptionFilter(ExceptionHandler);
}
#endif

View File

@@ -20,8 +20,6 @@
* THE SOFTWARE.
*/
#ifdef WIN32
#include "platform.h"
#include <windows.h>
#include <framework/stdext/stdext.h>
@@ -413,5 +411,3 @@ std::string Platform::getOSName()
}
return ret;
}
#endif

View File

@@ -20,32 +20,33 @@
* THE SOFTWARE.
*/
#ifdef WIN32
#include "win32window.h"
#include <framework/graphics/image.h>
#include <framework/core/application.h>
#include <framework/core/resourcemanager.h>
#ifndef OPENGL_ES
#include <framework/graphics/ogl/graphicscontextwgl.h>
#else
#include <framework/graphics/ogl/graphicscontextegl.h>
#endif
#define HSB_BIT_SET(p, n) (p[(n)/8] |= (128 >>((n)%8)))
WIN32Window::WIN32Window()
{
m_window = 0;
m_instance = 0;
m_deviceContext = 0;
m_cursor = 0;
m_minimumSize = Size(600,480);
m_size = Size(600,480);
m_hidden = true;
m_deviceContext = 0;
#ifdef OPENGL_ES
m_eglConfig = 0;
m_eglContext = 0;
m_eglDisplay = 0;
m_eglSurface = 0;
#ifndef OPENGL_ES
m_graphicsContext = GraphicsContextPtr(new GraphicsContextWGL);
#else
m_wglContext = 0;
m_graphicsContext = GraphicsContextPtr(new GraphicsContextEGL);
#endif
m_keyMap[VK_ESCAPE] = Fw::KeyEscape;
@@ -203,30 +204,9 @@ WIN32Window::WIN32Window()
void WIN32Window::init()
{
m_instance = GetModuleHandle(NULL);
#ifdef DIRECTX
m_d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = m_window; // set the window to be used by Direct3D
// create a device class using this information and information from the d3dpp stuct
m_d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_window,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&m_d3ddev);
#endif
internalCreateWindow();
internalCreateGLContext();
internalRestoreGLContext();
m_graphicsContext->create();
m_graphicsContext->restore();
}
void WIN32Window::terminate()
@@ -241,7 +221,7 @@ void WIN32Window::terminate()
DestroyCursor(cursor);
m_cursors.clear();
internalDestroyGLContext();
m_graphicsContext->destroy();
if(m_deviceContext) {
if(!ReleaseDC(m_window, m_deviceContext))
@@ -318,154 +298,6 @@ void WIN32Window::internalCreateWindow()
g_logger.fatal("GetDC failed");
}
void WIN32Window::internalCreateGLContext()
{
#ifdef OPENGL_ES
m_eglDisplay = eglGetDisplay(m_deviceContext);
if(m_eglDisplay == EGL_NO_DISPLAY)
g_logger.fatal("EGL not supported");
if(!eglInitialize(m_eglDisplay, NULL, NULL))
g_logger.fatal("Unable to initialize EGL");
static int configList[] = {
#if OPENGL_ES==2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_NONE
};
EGLint numConfig;
if(!eglGetConfigs(m_eglDisplay, NULL, 0, &numConfig))
g_logger.fatal("No valid GL configurations");
if(!eglChooseConfig(m_eglDisplay, configList, &m_eglConfig, 1, &numConfig))
g_logger.fatal("Failed to choose EGL config");
if(numConfig != 1)
g_logger.warning("Didn't got the exact EGL config");
EGLint contextAtrrList[] = {
#if OPENGL_ES==2
EGL_CONTEXT_CLIENT_VERSION, 2,
#else
EGL_CONTEXT_CLIENT_VERSION, 1,
#endif
EGL_NONE
};
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_window, NULL);
if(m_eglSurface == EGL_NO_SURFACE)
g_logger.fatal(stdext::format("Unable to create EGL surface: %s", eglGetError()));
m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAtrrList);
if(m_eglContext == EGL_NO_CONTEXT )
g_logger.fatal(stdext::format("Unable to create EGL context: %s", eglGetError()));
#else
uint pixelFormat;
static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // Select Our Color Depth
8, 0, 8, 0, 8, 0, // Color Bits Ignored
8, // Alpha Buffer Bits
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
0, // Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 }; // Layer Masks Ignored
pixelFormat = ChoosePixelFormat(m_deviceContext, &pfd);
if(!pixelFormat)
g_logger.fatal("Could not find a suitable pixel format");
if(!SetPixelFormat(m_deviceContext, pixelFormat, &pfd))
g_logger.fatal("Could not set the pixel format");
if(!(m_wglContext = wglCreateContext(m_deviceContext)))
g_logger.fatal("Unable to create GL context");
#endif
}
void WIN32Window::internalDestroyGLContext()
{
#ifdef OPENGL_ES
if(m_eglDisplay) {
if(m_eglContext) {
eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = 0;
}
if(m_eglSurface) {
eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = 0;
}
eglTerminate(m_eglDisplay);
m_eglDisplay = 0;
}
#else
if(m_wglContext) {
if(!wglMakeCurrent(NULL, NULL))
g_logger.error("Release of dc and rc failed.");
if(!wglDeleteContext(m_wglContext))
g_logger.error("Release rendering context failed.");
m_wglContext = NULL;
}
#endif
}
void WIN32Window::internalRestoreGLContext()
{
#ifdef OPENGL_ES
if(!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
g_logger.fatal("Unable to make current EGL context");
#else
if(!wglMakeCurrent(m_deviceContext, m_wglContext))
g_logger.fatal("Unable to make current WGL context");
#endif
}
bool WIN32Window::isExtensionSupported(const char *ext)
{
#ifdef OPENGL_ES
//TODO
return false;
#else
typedef const char* (WINAPI * wglGetExtensionsStringProc)();
wglGetExtensionsStringProc wglGetExtensionsString = (wglGetExtensionsStringProc)getExtensionProcAddress("wglGetExtensionsStringEXT");
if(!wglGetExtensionsString)
return false;
const char *exts = wglGetExtensionsString();
if(exts && strstr(exts, ext))
return true;
return false;
#endif
}
void *WIN32Window::getExtensionProcAddress(const char *ext)
{
#ifdef OPENGL_ES
//TODO
return NULL;
#else
return (void*)wglGetProcAddress(ext);
#endif
}
void WIN32Window::move(const Point& pos)
{
Rect clientRect(pos, getClientRect().size());
@@ -739,8 +571,8 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
break;
}
if(m_visible && m_deviceContext)
internalRestoreGLContext();
if(m_visible)
m_graphicsContext->restore();
Size size = Size(LOWORD(lParam), HIWORD(lParam));
size.setWidth(std::max(std::min(size.width(), 7680), 32));
@@ -762,11 +594,7 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
void WIN32Window::swapBuffers()
{
#ifdef OPENGL_ES
eglSwapBuffers(m_eglDisplay, m_eglSurface);
#else
SwapBuffers(m_deviceContext);
#endif
m_graphicsContext->swapBuffers();
}
void WIN32Window::showMouse()
@@ -862,19 +690,7 @@ void WIN32Window::setFullscreen(bool fullscreen)
void WIN32Window::setVerticalSync(bool enable)
{
#ifdef OPENGL_ES
eglSwapInterval(m_eglDisplay, enable ? 1 : 0);
#else
if(!isExtensionSupported("WGL_EXT_swap_control"))
return;
typedef BOOL (WINAPI * wglSwapIntervalProc)(int);
wglSwapIntervalProc wglSwapInterval = (wglSwapIntervalProc)getExtensionProcAddress("wglSwapIntervalEXT");
if(!wglSwapInterval)
return;
wglSwapInterval(enable ? 1 : 0);
#endif
m_graphicsContext->setVerticalSync(enable);
}
void WIN32Window::setIcon(const std::string& file)
@@ -967,11 +783,7 @@ std::string WIN32Window::getClipboardText()
std::string WIN32Window::getPlatformType()
{
#ifndef OPENGL_ES
return "WIN32-WGL";
#else
return "WIN32-EGL";
#endif
return stdext::format("WIN32-%s", m_graphicsContext->getName());
}
Rect WIN32Window::getClientRect()
@@ -1019,5 +831,3 @@ Rect WIN32Window::adjustWindowRect(const Rect& clientRect)
}
return rect;
}
#endif

View File

@@ -24,28 +24,13 @@
#define WIN32WINDOW_H
#include "platformwindow.h"
#include <windows.h>
#ifdef OPENGL_ES
#include <EGL/egl.h>
#endif
#ifdef DIRECTX
#include <d3d9.h>
#endif
struct WindowProcProxy;
class WIN32Window : public PlatformWindow
{
void internalCreateWindow();
void internalCreateGLContext();
void internalDestroyGLContext();
void internalRestoreGLContext();
void *getExtensionProcAddress(const char *ext);
bool isExtensionSupported(const char *ext);
LRESULT windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
friend class WindowProcProxy;
@@ -82,6 +67,8 @@ public:
Size getDisplaySize();
std::string getClipboardText();
std::string getPlatformType();
HWND getWindow() { return m_window; }
HDC getDisplay() { return m_deviceContext; }
protected:
int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot);
@@ -92,26 +79,14 @@ private:
Rect adjustWindowRect(const Rect& rect);
std::vector<HCURSOR> m_cursors;
HDC m_deviceContext;
HWND m_window;
HINSTANCE m_instance;
HDC m_deviceContext;
HCURSOR m_cursor;
HCURSOR m_defaultCursor;
bool m_hidden;
#ifdef DIRECTX
LPDIRECT3D9 m_d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 m_d3ddev; // the pointer to the device class
#endif
#ifdef OPENGL_ES
EGLConfig m_eglConfig;
EGLContext m_eglContext;
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
#else
HGLRC m_wglContext;
#endif
};
extern WIN32Window& g_win32Window;
#endif

View File

@@ -20,13 +20,17 @@
* THE SOFTWARE.
*/
#ifndef WIN32
#include "x11window.h"
#include <framework/core/resourcemanager.h>
#include <framework/graphics/image.h>
#include <unistd.h>
#ifndef OPENGL_ES
#include <framework/graphics/ogl/graphicscontextglx.h>
#else
#include <framework/graphics/ogl/graphicscontextegl.h>
#endif
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
X11Window::X11Window()
@@ -44,15 +48,10 @@ X11Window::X11Window()
m_wmDelete = 0;
m_minimumSize = Size(600,480);
m_size = Size(600,480);
#ifdef OPENGL_ES
m_eglConfig = 0;
m_eglContext = 0;
m_eglDisplay = 0;
m_eglSurface = 0;
#ifndef OPENGL_ES
m_graphicsContext = GraphicsContextPtr(new GraphicsContextGLX);
#else
m_fbConfig = 0;
m_glxContext = 0;
m_graphicsContext = GraphicsContextPtr(new GraphicsContextEGL);
#endif
m_keyMap[XK_Escape] = Fw::KeyEscape;
@@ -211,9 +210,7 @@ X11Window::X11Window()
void X11Window::init()
{
internalOpenDisplay();
internalCheckGL();
internalChooseGLVisual();
internalCreateGLContext();
m_graphicsContext->create();
internalCreateWindow();
}
@@ -243,7 +240,7 @@ void X11Window::terminate()
m_colormap = 0;
}
internalDestroyGLContext();
m_graphicsContext->destroy();
if(m_visual) {
XFree(m_visual);
@@ -331,7 +328,7 @@ void X11Window::internalCreateWindow()
if(!internalSetupWindowInput())
g_logger.warning("Input of special keys may be messed up, because window input initialization failed");
internalConnectGLContext();
m_graphicsContext->restore();
}
bool X11Window::internalSetupWindowInput()
@@ -358,169 +355,6 @@ bool X11Window::internalSetupWindowInput()
return true;
}
void X11Window::internalCheckGL()
{
#ifdef OPENGL_ES
m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_display);
if(m_eglDisplay == EGL_NO_DISPLAY)
g_logger.fatal("EGL not supported");
if(!eglInitialize(m_eglDisplay, NULL, NULL))
g_logger.fatal("Unable to initialize EGL");
#else
if(!glXQueryExtension(m_display, NULL, NULL))
g_logger.fatal("GLX not supported");
#endif
}
void X11Window::internalChooseGLVisual()
{
#ifdef OPENGL_ES
static int attrList[] = {
#if OPENGL_ES==2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_NONE
};
EGLint numConfig;
XVisualInfo visTemplate;
int numVisuals;
if(!eglChooseConfig(m_eglDisplay, attrList, &m_eglConfig, 1, &numConfig))
g_logger.fatal("Failed to choose EGL config");
if(numConfig != 1)
g_logger.warning("Didn't got the exact EGL config");
EGLint vid;
if(!eglGetConfigAttrib(m_eglDisplay, m_eglConfig, EGL_NATIVE_VISUAL_ID, &vid))
g_logger.fatal("Unable to get visual EGL visual id");
memset(&visTemplate, 0, sizeof(visTemplate));
visTemplate.visualid = vid;
m_visual = XGetVisualInfo(m_display, VisualIDMask, &visTemplate, &numVisuals);
if(!m_visual)
g_logger.fatal("Couldn't choose RGBA, double buffered visual");
m_rootWindow = DefaultRootWindow(m_display);
#else
static int attrList[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
None
};
int nelements;
m_fbConfig = glXChooseFBConfig(m_display, m_screen, attrList, &nelements);
if(!m_fbConfig)
g_logger.fatal("Couldn't choose RGBA, double buffered fbconfig");
m_visual = glXGetVisualFromFBConfig(m_display, *m_fbConfig);
if(!m_visual)
g_logger.fatal("Couldn't choose RGBA, double buffered visual");
m_rootWindow = RootWindow(m_display, m_visual->screen);
#endif
}
void X11Window::internalCreateGLContext()
{
#ifdef OPENGL_ES
EGLint attrList[] = {
#if OPENGL_ES==2
EGL_CONTEXT_CLIENT_VERSION, 2,
#else
EGL_CONTEXT_CLIENT_VERSION, 1,
#endif
EGL_NONE
};
m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attrList);
if(m_eglContext == EGL_NO_CONTEXT )
g_logger.fatal(stdext::format("Unable to create EGL context: %s", eglGetError()));
#else
m_glxContext = glXCreateContext(m_display, m_visual, NULL, True);
if(!m_glxContext)
g_logger.fatal("Unable to create GLX context");
if(!glXIsDirect(m_display, m_glxContext))
g_logger.warning("GL direct rendering is not possible");
#endif
}
void X11Window::internalDestroyGLContext()
{
#ifdef OPENGL_ES
if(m_eglDisplay) {
if(m_eglContext) {
eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = 0;
}
if(m_eglSurface) {
eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = 0;
}
eglTerminate(m_eglDisplay);
m_eglDisplay = 0;
}
#else
if(m_glxContext) {
glXMakeCurrent(m_display, None, NULL);
glXDestroyContext(m_display, m_glxContext);
m_glxContext = 0;
}
#endif
}
void X11Window::internalConnectGLContext()
{
#ifdef OPENGL_ES
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_window, NULL);
if(m_eglSurface == EGL_NO_SURFACE)
g_logger.fatal(stdext::format("Unable to create EGL surface: %s", eglGetError()));
if(!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
g_logger.fatal("Unable to connect EGL context into X11 window");
#else
if(!glXMakeCurrent(m_display, m_window, m_glxContext))
g_logger.fatal("Unable to set GLX context on X11 window");
#endif
}
void *X11Window::getExtensionProcAddress(const char *ext)
{
#ifdef OPENGL_ES
//TODO
return NULL;
#else
return (void *)glXGetProcAddressARB((const GLubyte*)ext);
#endif
}
bool X11Window::isExtensionSupported(const char *ext)
{
#ifdef OPENGL_ES
//TODO
return false;
#else
const char *exts = glXQueryExtensionsString(m_display, m_screen);
if(strstr(exts, ext))
return true;
#endif
return false;
}
void X11Window::move(const Point& pos)
{
m_position = pos;
@@ -840,11 +674,7 @@ void X11Window::poll()
void X11Window::swapBuffers()
{
#ifdef OPENGL_ES
eglSwapBuffers(m_eglDisplay, m_eglSurface);
#else
glXSwapBuffers(m_display, m_window);
#endif
m_graphicsContext->swapBuffers();
}
void X11Window::showMouse()
@@ -968,20 +798,7 @@ void X11Window::setFullscreen(bool fullscreen)
void X11Window::setVerticalSync(bool enable)
{
#ifdef OPENGL_ES
//TODO
#else
typedef GLint (*glSwapIntervalProc)(GLint);
glSwapIntervalProc glSwapInterval = NULL;
if(isExtensionSupported("GLX_MESA_swap_control"))
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalMESA");
else if(isExtensionSupported("GLX_SGI_swap_control"))
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalSGI");
if(glSwapInterval)
glSwapInterval(enable ? 1 : 0);
#endif
m_graphicsContext->setVerticalSync(enable);
}
void X11Window::setIcon(const std::string& file)
@@ -1069,11 +886,5 @@ std::string X11Window::getClipboardText()
std::string X11Window::getPlatformType()
{
#ifndef OPENGL_ES
return "X11-GLX";
#else
return "X11-EGL";
#endif
return stdext::format("X11-%s", m_graphicsContext->getName());
}
#endif

View File

@@ -28,12 +28,9 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#ifdef OPENGL_ES
#include <EGL/egl.h>
#else
#include <GL/glx.h>
#endif
typedef Window WindowType;
class X11Window : public PlatformWindow
{
@@ -41,15 +38,6 @@ class X11Window : public PlatformWindow
void internalCreateWindow();
bool internalSetupWindowInput();
void internalCheckGL();
void internalChooseGLVisual();
void internalCreateGLContext();
void internalDestroyGLContext();
void internalConnectGLContext();
void *getExtensionProcAddress(const char *ext);
bool isExtensionSupported(const char *ext);
public:
X11Window();
@@ -75,10 +63,16 @@ public:
void setVerticalSync(bool enable);
void setIcon(const std::string& file);
void setClipboardText(const std::string& text);
void setVisual(XVisualInfo *visual) { m_visual = visual; }
void setRootWindow(const Window& window) { m_rootWindow = window; }
Size getDisplaySize();
std::string getClipboardText();
std::string getPlatformType();
Window getWindow() { return m_window; }
Display *getDisplay() { return m_display; }
int getScreen() { return m_screen; }
XVisualInfo *getVisual() { return m_visual; }
protected:
int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot);
@@ -97,17 +91,9 @@ private:
int m_screen;
Atom m_wmDelete;
std::string m_clipboardText;
#ifndef OPENGL_ES
GLXContext m_glxContext;
GLXFBConfig *m_fbConfig;
#else
EGLConfig m_eglConfig;
EGLContext m_eglContext;
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
#endif
};
extern X11Window& g_x11Window;
#endif

View File

@@ -33,8 +33,4 @@
#error "Compiler not supported."
#endif
#if !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error "Sorry, you must enable C++0x to compile."
#endif
#endif

View File

@@ -25,7 +25,11 @@
#include <framework/luaengine/luainterface.h>
#include <client/client.h>
int main(int argc, const char* argv[])
#ifdef SDL
#include <SDL.h>
#endif
int main(int argc, char** argv)
{
std::vector<std::string> args(argv, argv + argc);
@@ -54,5 +58,7 @@ int main(int argc, const char* argv[])
// terminate everything and free memory
g_client.terminate();
g_app.terminate();
exit(0);
return 0;
}