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 -- mods 1000-9999
g_modules.autoLoadModules(9999) g_modules.autoLoadModules(9999)
local script = '/' .. g_app.getCompactName() .. 'rc' local script = '/' .. g_app.getCompactName() .. 'rc.lua'
if g_resources.fileExists(script) then if g_resources.fileExists(script) then
dofile(script) dofile(script)

View File

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

View File

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

View File

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

View File

@@ -26,6 +26,7 @@
#include <framework/graphics/framebuffermanager.h> #include <framework/graphics/framebuffermanager.h>
#include <framework/graphics/painter.h> #include <framework/graphics/painter.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
enum { enum {
MAX_LIGHT_INTENSITY = 8, 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); tex->setSmooth(true);
return tex; return tex;
} }

View File

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

View File

@@ -48,9 +48,11 @@ bool SpriteManager::loadSpr(std::string file)
file = g_resources.guessFilePath(file, "spr"); file = g_resources.guessFilePath(file, "spr");
m_spritesFile = g_resources.openFile(file); 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_signature = m_spritesFile->getU32();
m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16(); m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
m_spritesOffset = m_spritesFile->tell(); m_spritesOffset = m_spritesFile->tell();

View File

@@ -28,6 +28,7 @@
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/graphics/texture.h> #include <framework/graphics/texture.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
#include <framework/graphics/texturemanager.h> #include <framework/graphics/texturemanager.h>
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
#include <framework/otml/otml.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); animationPhaseTexture->setSmooth(true);
} }
return animationPhaseTexture; return animationPhaseTexture;

View File

@@ -123,15 +123,20 @@ set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/otml/otmlparser.h ${CMAKE_CURRENT_LIST_DIR}/otml/otmlparser.h
# crash handler # 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.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platform.h ${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 set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os") PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
@@ -258,6 +263,15 @@ if(CRASH_HANDLER)
message(STATUS "Crash handler: ON") message(STATUS "Crash handler: ON")
if(WIN32) if(WIN32)
set(framework_LIBRARIES ${framework_LIBRARIES} imagehlp) 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() endif()
else() else()
message(STATUS "Crash handler: OFF") message(STATUS "Crash handler: OFF")
@@ -290,18 +304,24 @@ endif()
if(FRAMEWORK_GRAPHICS) if(FRAMEWORK_GRAPHICS)
set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING) set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
if(OPENGLES STREQUAL "2.0") if(OPENGLES)
find_package(OpenGLES2 REQUIRED) set(framework_SOURCES ${framework_SOURCES}
find_package(EGL REQUIRED) ${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.cpp
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2) ${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.h
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR}) )
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY}) if(OPENGLES STREQUAL "2.0")
ELSEif(OPENGLES STREQUAL "1.0") find_package(OpenGLES2 REQUIRED)
find_package(OpenGLES1 REQUIRED) find_package(EGL REQUIRED)
find_package(EGL REQUIRED) set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1) set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR})
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES1_INCLUDE_DIR}) set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES1_LIBRARY}) 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() else()
## TODO: CMake Documentation says that this is not the right ## TODO: CMake Documentation says that this is not the right
# Thing for Mac OS X, but it works for now. # Thing for Mac OS X, but it works for now.
@@ -336,6 +356,8 @@ if(FRAMEWORK_GRAPHICS)
set(framework_SOURCES ${framework_SOURCES} set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.h ${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() endif()
@@ -343,6 +365,44 @@ if(FRAMEWORK_GRAPHICS)
set(framework_LIBRARIES ${framework_LIBRARIES} X11) set(framework_LIBRARIES ${framework_LIBRARIES} X11)
endif() 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} set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.h ${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/glutil.h
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.h ${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.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.h ${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.h
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp ${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/shaderprogram.h
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h ${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.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h ${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h
${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h ${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h
@@ -435,10 +499,6 @@ if(FRAMEWORK_GRAPHICS)
# platform window # platform window
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.cpp ${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.h ${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 # window input
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp ${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 <framework/platform/platform.h>
#include <locale> #include <locale>
#include <boost/concept_check.hpp>
#ifdef FW_NET #ifdef FW_NET
#include <framework/net/connection.h> #include <framework/net/connection.h>
@@ -163,10 +164,14 @@ void Application::close()
std::string Application::getOs() std::string Application::getOs()
{ {
#if defined(WIN32) #if defined(ANDROID)
return "android";
#elif defined(IOS)
return "ios";
#elif defined(WIN32)
return "windows"; return "windows";
#elif defined(__APPLE__) #elif defined(__APPLE__)
return "mac"; return "macos";
#elif __linux #elif __linux
return "linux"; return "linux";
#else #else

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,14 +24,15 @@
#include "graphics.h" #include "graphics.h"
#include <framework/core/eventdispatcher.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)) if(!setupSize(size, buildMipmaps))
return; return;
for(uint i=0;i<frames.size();++i) { 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; m_framesDelay = framesDelay;

View File

@@ -29,7 +29,7 @@
class AnimatedTexture : public Texture class AnimatedTexture : public Texture
{ {
public: 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 ~AnimatedTexture();
virtual bool buildHardwareMipmaps(); virtual bool buildHardwareMipmaps();

View File

@@ -33,15 +33,15 @@
#include <fstream> #include <fstream>
#if defined(_MSC_VER) && _MSC_VER >= 1300 #if defined(_MSC_VER) && _MSC_VER >= 1300
#define swap16(data) _byteswap_ushort(data) #define lswap16(data) _byteswap_ushort(data)
#define swap32(data) _byteswap_ulong(data) #define lswap32(data) _byteswap_ulong(data)
#elif __linux__ #elif __linux__
#include <byteswap.h> #include <byteswap.h>
#define swap16(data) bswap_16(data) #define lswap16(data) bswap_16(data)
#define swap32(data) bswap_32(data) #define lswap32(data) bswap_32(data)
#else #else
#define swap16(data) (((data >> 8) & 255) | ((data & 255) << 8)) #define lswap16(data) (((data >> 8) & 255) | ((data & 255) << 8))
#define swap32(data) ((swap16(data) << 16) | swap16(data >> 16)) #define lswap32(data) ((swap16(data) << 16) | swap16(data >> 16))
#endif #endif
#define PNG_ZBUF_SIZE 32768 #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) 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 crc = crc32(0, Z_NULL, 0);
unsigned int len = swap32(length); unsigned int len = lswap32(length);
f.write((char*)&len, 4); f.write((char*)&len, 4);
f.write(name, 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 = crc32(crc, data, length);
} }
crc = swap32(crc); crc = lswap32(crc);
f.write((char*)&crc, 4); 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 mCompression;
unsigned char mFilterMethod; unsigned char mFilterMethod;
unsigned char mInterlaceMethod; 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 zstream1;
z_stream zstream2; z_stream zstream2;

View File

@@ -34,6 +34,7 @@ class BitmapFont;
class CachedText; class CachedText;
class FrameBuffer; class FrameBuffer;
class FrameBufferManager; class FrameBufferManager;
class GraphicsContext;
class Shader; class Shader;
class ShaderProgram; class ShaderProgram;
class PainterShaderProgram; 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<BitmapFont> BitmapFontPtr;
typedef stdext::shared_object_ptr<CachedText> CachedTextPtr; typedef stdext::shared_object_ptr<CachedText> CachedTextPtr;
typedef stdext::shared_object_ptr<FrameBuffer> FrameBufferPtr; 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<Shader> ShaderPtr;
typedef stdext::shared_object_ptr<ShaderProgram> ShaderProgramPtr; typedef stdext::shared_object_ptr<ShaderProgram> ShaderProgramPtr;
typedef stdext::shared_object_ptr<PainterShaderProgram> PainterShaderProgramPtr; typedef stdext::shared_object_ptr<PainterShaderProgram> PainterShaderProgramPtr;

View File

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

View File

@@ -44,6 +44,7 @@
typedef char GLchar; typedef char GLchar;
// define OpenGL ES 2.0 API just to make compile, it wont actually be used // 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 glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { }
inline void glBindFramebuffer (GLenum target, GLuint framebuffer) { } inline void glBindFramebuffer (GLenum target, GLuint framebuffer) { }
inline void glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers) { } 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) bool Graphics::selectPainterEngine(PainterEngine painterEngine)
{ {
// TODO: remove this
#ifdef DIRECTX
painterEngine = Painter_DirectX9;
#endif
Painter *painter = nullptr; Painter *painter = nullptr;
Painter *fallbackPainter = nullptr; Painter *fallbackPainter = nullptr;
PainterEngine fallbackPainterEngine = Painter_Any; PainterEngine fallbackPainterEngine = Painter_Any;
#ifdef PAINTER_DX9 #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 // always prefer DirectX9 on Windows
if(g_painterDX9) { if(g_painterDX9) {
if(!painter && (painterEngine == Painter_DirectX9 || painterEngine == Painter_Any)) { if(!painter && (painterEngine == Painter_DirectX9 || painterEngine == Painter_Any)) {
@@ -238,6 +240,7 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
if(g_painter) if(g_painter)
g_painter->unbind(); g_painter->unbind();
painter->bind(); painter->bind();
g_window.setGraphicsContext(painter->getGraphicsContext());
g_painter = painter; g_painter = painter;
} }
@@ -253,6 +256,11 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
void Graphics::resize(const Size& size) void Graphics::resize(const Size& size)
{ {
m_viewportSize = size; m_viewportSize = size;
#ifdef PAINTER_DX9
if(g_painterDX9)
g_painterDX9->setResolution(size);
#endif
#ifdef PAINTER_OGL1 #ifdef PAINTER_OGL1
if(g_painterOGL1) if(g_painterOGL1)
g_painterOGL1->setResolution(size); 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/graphics/graphics.h>
#include <framework/platform/platformwindow.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() 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_glTextureId = 0;
m_oldStateIndex = 0; m_oldStateIndex = 0;
m_color = Color::white; m_color = Color::white;
@@ -35,6 +53,7 @@ PainterOGL::PainterOGL()
m_shaderProgram = nullptr; m_shaderProgram = nullptr;
m_texture = nullptr; m_texture = nullptr;
m_alphaWriting = false; m_alphaWriting = false;
setResolution(g_window.getSize()); setResolution(g_window.getSize());
} }
@@ -286,6 +305,7 @@ void PainterOGL::updateGlBlendEquation()
{ {
if(!g_graphics.canUseBlendEquation()) if(!g_graphics.canUseBlendEquation())
return; return;
if(m_blendEquation == BlendEquation_Add) if(m_blendEquation == BlendEquation_Add)
glBlendEquation(0x8006); // GL_FUNC_ADD glBlendEquation(0x8006); // GL_FUNC_ADD
else if(m_blendEquation == BlendEquation_Max) 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/declarations.h>
#include <framework/graphics/coordsbuffer.h> #include <framework/graphics/coordsbuffer.h>
#include <framework/graphics/graphicscontext.h>
#include <framework/graphics/paintershaderprogram.h> #include <framework/graphics/paintershaderprogram.h>
#include <framework/graphics/texture.h> #include <framework/graphics/texture.h>
@@ -50,7 +51,7 @@ public:
Painter(); Painter();
virtual ~Painter() { } virtual ~Painter() {}
virtual void bind() { } virtual void bind() { }
virtual void unbind() { } virtual void unbind() { }
@@ -95,6 +96,7 @@ public:
float getOpacity() { return m_opacity; } float getOpacity() { return m_opacity; }
Rect getClipRect() { return m_clipRect; } Rect getClipRect() { return m_clipRect; }
CompositionMode getCompositionMode() { return m_compositionMode; } CompositionMode getCompositionMode() { return m_compositionMode; }
GraphicsContextPtr getGraphicsContext() { return m_graphicsContext; }
virtual void setCompositionMode(CompositionMode compositionMode) = 0; virtual void setCompositionMode(CompositionMode compositionMode) = 0;
@@ -116,6 +118,7 @@ protected:
Size m_resolution; Size m_resolution;
float m_opacity; float m_opacity;
Rect m_clipRect; Rect m_clipRect;
GraphicsContextPtr m_graphicsContext;
}; };
extern Painter *g_painter; 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; 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() Texture::~Texture()
{ {
#ifndef NDEBUG #ifndef NDEBUG
assert(!g_app.isTerminated()); assert(!g_app.isTerminated());
#endif #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_size = size;
m_glSize = glSize; setupTranformMatrix(size, size);
setupTranformMatrix();
return true; return true;
} }
void Texture::setupWrap() void Texture::setupTranformMatrix(const Size& textureSize, const Size& realSize)
{
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()
{ {
if(m_upsideDown) { if(m_upsideDown) {
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f, m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
0.0f, -1.0f/m_glSize.height(), 0.0f, 0.0f, -1.0f/textureSize.height(), 0.0f,
0.0f, m_size.height()/(float)m_glSize.height(), 1.0f }; 0.0f, realSize.height()/(float)textureSize.height(), 1.0f };
} else { } else {
m_transformMatrix = { 1.0f/m_glSize.width(), 0.0f, 0.0f, m_transformMatrix = { 1.0f/textureSize.width(), 0.0f, 0.0f,
0.0f, 1.0f/m_glSize.height(), 0.0f, 0.0f, 1.0f/textureSize.height(), 0.0f,
0.0f, 0.0f, 1.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: public:
Texture(); Texture();
Texture(const Size& size);
Texture(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
virtual ~Texture(); virtual ~Texture();
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false, bool compress = false); virtual void setSmooth(bool) {}
void bind(); virtual void setRepeat(bool) {}
void copyFromScreen(const Rect& screenRect); virtual void setUpsideDown(bool) {}
virtual bool buildHardwareMipmaps();
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 setTime(ticks_t time) { m_time = time; }
void setupTranformMatrix(const Size& textureSize, const Size& realSize);
uint getId() { return m_id; } uint getId() { return m_id; }
ticks_t getTime() { return m_time; } ticks_t getTime() { return m_time; }
int getWidth() { return m_size.width(); } int getWidth() { return m_size.width(); }
int getHeight() { return m_size.height(); } int getHeight() { return m_size.height(); }
const Size& getSize() { return m_size; } const Size& getSize() { return m_size; }
const Size& getGlSize() { return m_glSize; }
const Matrix3& getTransformMatrix() { return m_transformMatrix; } const Matrix3& getTransformMatrix() { return m_transformMatrix; }
bool isEmpty() { return m_id == 0; } bool isEmpty() { return m_id == 0; }
bool hasRepeat() { return m_repeat; } bool hasRepeat() { return m_repeat; }
@@ -56,13 +55,6 @@ public:
virtual bool isAnimatedTexture() { return false; } virtual bool isAnimatedTexture() { return false; }
protected: 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; uint m_id;
ticks_t m_time; ticks_t m_time;
Size m_size; Size m_size;

View File

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

View File

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

View File

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

View File

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

View File

@@ -27,12 +27,13 @@
#include <framework/core/inputevent.h> #include <framework/core/inputevent.h>
#include <framework/core/timer.h> #include <framework/core/timer.h>
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
#include <framework/graphics/graphicscontext.h>
//@bindsingleton g_window //@bindsingleton g_window
class PlatformWindow class PlatformWindow
{ {
enum { enum {
KEY_PRESS_REPEAT_INTERVAL = 30, KEY_PRESS_REPEAT_INTERVAL = 30
}; };
typedef std::function<void(const Size&)> OnResizeCallback; typedef std::function<void(const Size&)> OnResizeCallback;
@@ -57,12 +58,16 @@ public:
virtual void setMouseCursor(int cursorId) = 0; virtual void setMouseCursor(int cursorId) = 0;
virtual void restoreMouseCursor() = 0; virtual void restoreMouseCursor() = 0;
virtual void showTextInput() { }
virtual void hideTextInput() { }
virtual void setTitle(const std::string& title) = 0; virtual void setTitle(const std::string& title) = 0;
virtual void setMinimumSize(const Size& minimumSize) = 0; virtual void setMinimumSize(const Size& minimumSize) = 0;
virtual void setFullscreen(bool fullscreen) = 0; virtual void setFullscreen(bool fullscreen) = 0;
virtual void setVerticalSync(bool enable) = 0; virtual void setVerticalSync(bool enable) = 0;
virtual void setIcon(const std::string& iconFile) = 0; virtual void setIcon(const std::string& iconFile) = 0;
virtual void setClipboardText(const std::string& text) = 0; virtual void setClipboardText(const std::string& text) = 0;
void setGraphicsContext(const GraphicsContextPtr& graphicsContext);
virtual Size getDisplaySize() = 0; virtual Size getDisplaySize() = 0;
virtual std::string getClipboardText() = 0; virtual std::string getClipboardText() = 0;
@@ -127,6 +132,8 @@ protected:
std::function<void()> m_onClose; std::function<void()> m_onClose;
OnResizeCallback m_onResize; OnResizeCallback m_onResize;
OnInputEventCallback m_onInputEvent; OnInputEventCallback m_onInputEvent;
GraphicsContextPtr m_graphicsContext;
}; };
extern PlatformWindow& g_window; 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. * THE SOFTWARE.
*/ */
#if !defined(WIN32) && defined(CRASH_HANDLER)
#include "crashhandler.h" #include "crashhandler.h"
#include <framework/global.h> #include <framework/global.h>
#include <framework/core/application.h> #include <framework/core/application.h>
@@ -133,5 +131,3 @@ void installCrashHandler()
sigaction(SIGFPE, &sa, NULL); // floating-point exception sigaction(SIGFPE, &sa, NULL); // floating-point exception
sigaction(SIGABRT, &sa, NULL); // process aborted (asserts) sigaction(SIGABRT, &sa, NULL); // process aborted (asserts)
} }
#endif

View File

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

View File

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

View File

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

View File

@@ -20,32 +20,33 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifdef WIN32
#include "win32window.h" #include "win32window.h"
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/core/application.h> #include <framework/core/application.h>
#include <framework/core/resourcemanager.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))) #define HSB_BIT_SET(p, n) (p[(n)/8] |= (128 >>((n)%8)))
WIN32Window::WIN32Window() WIN32Window::WIN32Window()
{ {
m_window = 0; m_window = 0;
m_instance = 0; m_instance = 0;
m_deviceContext = 0;
m_cursor = 0; m_cursor = 0;
m_minimumSize = Size(600,480); m_minimumSize = Size(600,480);
m_size = Size(600,480); m_size = Size(600,480);
m_hidden = true; m_hidden = true;
m_deviceContext = 0;
#ifdef OPENGL_ES #ifndef OPENGL_ES
m_eglConfig = 0; m_graphicsContext = GraphicsContextPtr(new GraphicsContextWGL);
m_eglContext = 0;
m_eglDisplay = 0;
m_eglSurface = 0;
#else #else
m_wglContext = 0; m_graphicsContext = GraphicsContextPtr(new GraphicsContextEGL);
#endif #endif
m_keyMap[VK_ESCAPE] = Fw::KeyEscape; m_keyMap[VK_ESCAPE] = Fw::KeyEscape;
@@ -203,30 +204,9 @@ WIN32Window::WIN32Window()
void WIN32Window::init() void WIN32Window::init()
{ {
m_instance = GetModuleHandle(NULL); 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(); internalCreateWindow();
internalCreateGLContext(); m_graphicsContext->create();
internalRestoreGLContext(); m_graphicsContext->restore();
} }
void WIN32Window::terminate() void WIN32Window::terminate()
@@ -241,7 +221,7 @@ void WIN32Window::terminate()
DestroyCursor(cursor); DestroyCursor(cursor);
m_cursors.clear(); m_cursors.clear();
internalDestroyGLContext(); m_graphicsContext->destroy();
if(m_deviceContext) { if(m_deviceContext) {
if(!ReleaseDC(m_window, m_deviceContext)) if(!ReleaseDC(m_window, m_deviceContext))
@@ -318,154 +298,6 @@ void WIN32Window::internalCreateWindow()
g_logger.fatal("GetDC failed"); 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) void WIN32Window::move(const Point& pos)
{ {
Rect clientRect(pos, getClientRect().size()); Rect clientRect(pos, getClientRect().size());
@@ -739,8 +571,8 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
break; break;
} }
if(m_visible && m_deviceContext) if(m_visible)
internalRestoreGLContext(); m_graphicsContext->restore();
Size size = Size(LOWORD(lParam), HIWORD(lParam)); Size size = Size(LOWORD(lParam), HIWORD(lParam));
size.setWidth(std::max(std::min(size.width(), 7680), 32)); 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() void WIN32Window::swapBuffers()
{ {
#ifdef OPENGL_ES m_graphicsContext->swapBuffers();
eglSwapBuffers(m_eglDisplay, m_eglSurface);
#else
SwapBuffers(m_deviceContext);
#endif
} }
void WIN32Window::showMouse() void WIN32Window::showMouse()
@@ -862,19 +690,7 @@ void WIN32Window::setFullscreen(bool fullscreen)
void WIN32Window::setVerticalSync(bool enable) void WIN32Window::setVerticalSync(bool enable)
{ {
#ifdef OPENGL_ES m_graphicsContext->setVerticalSync(enable);
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
} }
void WIN32Window::setIcon(const std::string& file) void WIN32Window::setIcon(const std::string& file)
@@ -967,11 +783,7 @@ std::string WIN32Window::getClipboardText()
std::string WIN32Window::getPlatformType() std::string WIN32Window::getPlatformType()
{ {
#ifndef OPENGL_ES return stdext::format("WIN32-%s", m_graphicsContext->getName());
return "WIN32-WGL";
#else
return "WIN32-EGL";
#endif
} }
Rect WIN32Window::getClientRect() Rect WIN32Window::getClientRect()
@@ -1019,5 +831,3 @@ Rect WIN32Window::adjustWindowRect(const Rect& clientRect)
} }
return rect; return rect;
} }
#endif

View File

@@ -24,28 +24,13 @@
#define WIN32WINDOW_H #define WIN32WINDOW_H
#include "platformwindow.h" #include "platformwindow.h"
#include <windows.h> #include <windows.h>
#ifdef OPENGL_ES
#include <EGL/egl.h>
#endif
#ifdef DIRECTX
#include <d3d9.h>
#endif
struct WindowProcProxy; struct WindowProcProxy;
class WIN32Window : public PlatformWindow class WIN32Window : public PlatformWindow
{ {
void internalCreateWindow(); 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); LRESULT windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
friend class WindowProcProxy; friend class WindowProcProxy;
@@ -82,6 +67,8 @@ public:
Size getDisplaySize(); Size getDisplaySize();
std::string getClipboardText(); std::string getClipboardText();
std::string getPlatformType(); std::string getPlatformType();
HWND getWindow() { return m_window; }
HDC getDisplay() { return m_deviceContext; }
protected: protected:
int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot); int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot);
@@ -92,26 +79,14 @@ private:
Rect adjustWindowRect(const Rect& rect); Rect adjustWindowRect(const Rect& rect);
std::vector<HCURSOR> m_cursors; std::vector<HCURSOR> m_cursors;
HDC m_deviceContext;
HWND m_window; HWND m_window;
HINSTANCE m_instance; HINSTANCE m_instance;
HDC m_deviceContext;
HCURSOR m_cursor; HCURSOR m_cursor;
HCURSOR m_defaultCursor; HCURSOR m_defaultCursor;
bool m_hidden; 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 #endif

View File

@@ -20,13 +20,17 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef WIN32
#include "x11window.h" #include "x11window.h"
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <unistd.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))) #define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
X11Window::X11Window() X11Window::X11Window()
@@ -44,15 +48,10 @@ X11Window::X11Window()
m_wmDelete = 0; m_wmDelete = 0;
m_minimumSize = Size(600,480); m_minimumSize = Size(600,480);
m_size = Size(600,480); m_size = Size(600,480);
#ifndef OPENGL_ES
#ifdef OPENGL_ES m_graphicsContext = GraphicsContextPtr(new GraphicsContextGLX);
m_eglConfig = 0;
m_eglContext = 0;
m_eglDisplay = 0;
m_eglSurface = 0;
#else #else
m_fbConfig = 0; m_graphicsContext = GraphicsContextPtr(new GraphicsContextEGL);
m_glxContext = 0;
#endif #endif
m_keyMap[XK_Escape] = Fw::KeyEscape; m_keyMap[XK_Escape] = Fw::KeyEscape;
@@ -211,9 +210,7 @@ X11Window::X11Window()
void X11Window::init() void X11Window::init()
{ {
internalOpenDisplay(); internalOpenDisplay();
internalCheckGL(); m_graphicsContext->create();
internalChooseGLVisual();
internalCreateGLContext();
internalCreateWindow(); internalCreateWindow();
} }
@@ -243,7 +240,7 @@ void X11Window::terminate()
m_colormap = 0; m_colormap = 0;
} }
internalDestroyGLContext(); m_graphicsContext->destroy();
if(m_visual) { if(m_visual) {
XFree(m_visual); XFree(m_visual);
@@ -331,7 +328,7 @@ void X11Window::internalCreateWindow()
if(!internalSetupWindowInput()) if(!internalSetupWindowInput())
g_logger.warning("Input of special keys may be messed up, because window input initialization failed"); g_logger.warning("Input of special keys may be messed up, because window input initialization failed");
internalConnectGLContext(); m_graphicsContext->restore();
} }
bool X11Window::internalSetupWindowInput() bool X11Window::internalSetupWindowInput()
@@ -358,169 +355,6 @@ bool X11Window::internalSetupWindowInput()
return true; 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) void X11Window::move(const Point& pos)
{ {
m_position = pos; m_position = pos;
@@ -840,11 +674,7 @@ void X11Window::poll()
void X11Window::swapBuffers() void X11Window::swapBuffers()
{ {
#ifdef OPENGL_ES m_graphicsContext->swapBuffers();
eglSwapBuffers(m_eglDisplay, m_eglSurface);
#else
glXSwapBuffers(m_display, m_window);
#endif
} }
void X11Window::showMouse() void X11Window::showMouse()
@@ -968,20 +798,7 @@ void X11Window::setFullscreen(bool fullscreen)
void X11Window::setVerticalSync(bool enable) void X11Window::setVerticalSync(bool enable)
{ {
#ifdef OPENGL_ES m_graphicsContext->setVerticalSync(enable);
//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
} }
void X11Window::setIcon(const std::string& file) void X11Window::setIcon(const std::string& file)
@@ -1069,11 +886,5 @@ std::string X11Window::getClipboardText()
std::string X11Window::getPlatformType() std::string X11Window::getPlatformType()
{ {
#ifndef OPENGL_ES return stdext::format("X11-%s", m_graphicsContext->getName());
return "X11-GLX";
#else
return "X11-EGL";
#endif
} }
#endif

View File

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

View File

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

View File

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