diff --git a/CMakeLists.txt b/CMakeLists.txt index f1f2c1be0..9542da48c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8) -option(GLES "Set to ON if targeting OpenGL ES" ${GLES}) +option(GLES "Set to ON if targeting Embedded OpenGL" ${GLES}) option(GL "Set to ON if targeting Desktop OpenGL" ${GL}) option(RPI "Set to ON to enable the Raspberry PI video player (omxplayer)" ${RPI}) @@ -16,7 +16,7 @@ LIST(APPEND CMAKE_MODULE_PATH #------------------------------------------------------------------------------- #set up OpenGL system variable if(GLES) - set(GLSystem "OpenGL ES" CACHE STRING "The OpenGL system to be used") + set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") elseif(GL) set(GLSystem "Desktop OpenGL" CACHE STRING "The OpenGL system to be used") #------------------------------------------------------------------------------- @@ -24,13 +24,13 @@ elseif(GL) elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/bcm_host.h") MESSAGE("bcm_host.h found") set(BCMHOST found) - set(GLSystem "OpenGL ES" CACHE STRING "The OpenGL system to be used") + set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") #------------------------------------------------------------------------------- #check if we're running on OSMC Vero4K elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib/libMali.so") MESSAGE("libMali.so found") set(VERO4K found) - set(GLSystem "OpenGL ES" CACHE STRING "The OpenGL system to be used") + set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") #------------------------------------------------------------------------------- #check if we're running on olinuxino / odroid / etc elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/libMali.so" OR @@ -39,12 +39,12 @@ elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/libMali.so" OR EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/arm-linux-gnueabihf/mali-egl/libmali.so" OR EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/arm-linux-gnueabihf/libmali.so") MESSAGE("libMali.so found") - set(GLSystem "OpenGL ES" CACHE STRING "The OpenGL system to be used") + set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") else() set(GLSystem "Desktop OpenGL" CACHE STRING "The OpenGL system to be used") endif(GLES) -set_property(CACHE GLSystem PROPERTY STRINGS "Desktop OpenGL" "OpenGL ES") +set_property(CACHE GLSystem PROPERTY STRINGS "Desktop OpenGL" "Embedded OpenGL") #finding necessary packages #------------------------------------------------------------------------------- @@ -109,9 +109,9 @@ endif() endif() if(${GLSystem} MATCHES "Desktop OpenGL") - add_definitions(-DUSE_OPENGL_DESKTOP) + add_definitions(-DUSE_OPENGL_21) else() - add_definitions(-DUSE_OPENGL_ES) + add_definitions(-DUSE_OPENGLES_10) endif() #------------------------------------------------------------------------------- diff --git a/es-app/src/SystemScreenSaver.cpp b/es-app/src/SystemScreenSaver.cpp index 1837b94aa..c5bcdf300 100644 --- a/es-app/src/SystemScreenSaver.cpp +++ b/es-app/src/SystemScreenSaver.cpp @@ -11,7 +11,6 @@ #include "FileFilterIndex.h" #include "Log.h" #include "PowerSaver.h" -#include "Renderer.h" #include "Sound.h" #include "SystemData.h" #include diff --git a/es-app/src/components/AsyncReqComponent.cpp b/es-app/src/components/AsyncReqComponent.cpp index 5a95ae82c..a4e5ff572 100644 --- a/es-app/src/components/AsyncReqComponent.cpp +++ b/es-app/src/components/AsyncReqComponent.cpp @@ -1,7 +1,7 @@ #include "components/AsyncReqComponent.h" +#include "renderers/Renderer.h" #include "HttpReq.h" -#include "Renderer.h" AsyncReqComponent::AsyncReqComponent(Window* window, std::shared_ptr req, std::function)> onSuccess, std::function onCancel) : GuiComponent(window), diff --git a/es-app/src/components/RatingComponent.cpp b/es-app/src/components/RatingComponent.cpp index 924a0cbcc..a56b00b06 100644 --- a/es-app/src/components/RatingComponent.cpp +++ b/es-app/src/components/RatingComponent.cpp @@ -1,7 +1,6 @@ #include "components/RatingComponent.h" #include "resources/TextureResource.h" -#include "Renderer.h" #include "ThemeData.h" RatingComponent::RatingComponent(Window* window) : GuiComponent(window), mColorShift(0xFFFFFFFF) @@ -76,38 +75,29 @@ void RatingComponent::onSizeChanged() void RatingComponent::updateVertices() { - const float numStars = NUM_RATING_STARS; + const float numStars = NUM_RATING_STARS; + const float h = Math::round(getSize().y()); // is the same as a single star's width + const float w = Math::round(h * mValue * numStars); + const float fw = Math::round(h * numStars); + const unsigned int color = Renderer::convertColor(mColorShift); - const float h = Math::round(getSize().y()); // is the same as a single star's width - const float w = Math::round(h * mValue * numStars); - const float fw = Math::round(h * numStars); + mVertices[0] = { { 0.0f, 0.0f }, { 0.0f, 1.0f }, color }; + mVertices[1] = { { 0.0f, h }, { 0.0f, 0.0f }, color }; + mVertices[2] = { { w, 0.0f }, { mValue * numStars, 1.0f }, color }; + mVertices[3] = { { w, h }, { mValue * numStars, 0.0f }, color }; - mVertices[0].pos = Vector2f(0.0f, 0.0f); - mVertices[0].tex = Vector2f(0.0f, 1.0f); - mVertices[1].pos = Vector2f(w, h); - mVertices[1].tex = Vector2f(mValue * numStars, 0.0f); - mVertices[2].pos = Vector2f(0.0f, h); - mVertices[2].tex = Vector2f(0.0f, 0.0f); - - mVertices[3] = mVertices[0]; - mVertices[4].pos = Vector2f(w, 0.0f); - mVertices[4].tex = Vector2f(mValue * numStars, 1.0f); - mVertices[5] = mVertices[1]; - - mVertices[6] = mVertices[4]; - mVertices[7].pos = Vector2f(fw, h); - mVertices[7].tex = Vector2f(numStars, 0.0f); - mVertices[8] = mVertices[1]; - - mVertices[9] = mVertices[6]; - mVertices[10].pos = Vector2f(fw, 0.0f); - mVertices[10].tex = Vector2f(numStars, 1.0f); - mVertices[11] = mVertices[7]; + mVertices[4] = { { 0.0f, 0.0f }, { 0.0f, 1.0f }, color }; + mVertices[5] = { { 0.0f, h }, { 0.0f, 0.0f }, color }; + mVertices[6] = { { fw, 0.0f }, { numStars, 1.0f }, color }; + mVertices[7] = { { fw, h }, { numStars, 0.0f }, color }; } void RatingComponent::updateColors() { - Renderer::buildGLColorArray(mColors, mColorShift, 12); + const unsigned int color = Renderer::convertColor(mColorShift); + + for(int i = 0; i < 8; ++i) + mVertices[i].col = color; } void RatingComponent::render(const Transform4x4f& parentTrans) @@ -116,30 +106,11 @@ void RatingComponent::render(const Transform4x4f& parentTrans) trans.round(); Renderer::setMatrix(trans); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, mColors); - mFilledTexture->bind(); - glDrawArrays(GL_TRIANGLES, 0, 6); + Renderer::drawTriangleStrips(&mVertices[0], 4); mUnfilledTexture->bind(); - glDrawArrays(GL_TRIANGLES, 6, 6); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); + Renderer::drawTriangleStrips(&mVertices[4], 4); renderChildren(trans); } diff --git a/es-app/src/components/RatingComponent.h b/es-app/src/components/RatingComponent.h index 6c47f00d2..ae2c3ae7e 100644 --- a/es-app/src/components/RatingComponent.h +++ b/es-app/src/components/RatingComponent.h @@ -2,9 +2,8 @@ #ifndef ES_APP_COMPONENTS_RATING_COMPONENT_H #define ES_APP_COMPONENTS_RATING_COMPONENT_H +#include "renderers/Renderer.h" #include "GuiComponent.h" -#include "platform.h" -#include GLHEADER class TextureResource; @@ -43,14 +42,7 @@ private: float mValue; - struct Vertex - { - Vector2f pos; - Vector2f tex; - } mVertices[12]; - - - GLubyte mColors[12*4]; + Renderer::Vertex mVertices[8]; unsigned int mColorShift; diff --git a/es-app/src/guis/GuiInfoPopup.cpp b/es-app/src/guis/GuiInfoPopup.cpp index a7fff0951..e759e27f7 100644 --- a/es-app/src/guis/GuiInfoPopup.cpp +++ b/es-app/src/guis/GuiInfoPopup.cpp @@ -3,7 +3,6 @@ #include "components/ComponentGrid.h" #include "components/NinePatchComponent.h" #include "components/TextComponent.h" -#include "Renderer.h" #include GuiInfoPopup::GuiInfoPopup(Window* window, std::string message, int duration) : diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 59d8ae415..1f544779b 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -18,6 +18,7 @@ #include "VolumeControl.h" #include #include +#include "platform.h" GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window) { diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 6c1fe80ef..de0a0339e 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -306,9 +306,6 @@ int main(int argc, char* argv[]) return 1; } - std::string glExts = (const char*)glGetString(GL_EXTENSIONS); - LOG(LogInfo) << "Checking available OpenGL extensions..."; - LOG(LogInfo) << " ARB_texture_non_power_of_two: " << (glExts.find("ARB_texture_non_power_of_two") != std::string::npos ? "ok" : "MISSING"); if(splashScreen) { std::string progressText = "Loading..."; diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index cdd5b1ea1..b3e48911a 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -5,7 +5,6 @@ #include "views/UIModeController.h" #include "views/ViewController.h" #include "Log.h" -#include "Renderer.h" #include "Settings.h" #include "SystemData.h" #include "Window.h" diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index eec5e9fdb..d1735edf1 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -2,9 +2,9 @@ #ifndef ES_APP_VIEWS_VIEW_CONTROLLER_H #define ES_APP_VIEWS_VIEW_CONTROLLER_H +#include "renderers/Renderer.h" #include "FileData.h" #include "GuiComponent.h" -#include "Renderer.h" #include class IGameListView; diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index 988981593..0c65897bb 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -2,9 +2,9 @@ #ifndef ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H #define ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H +#include "renderers/Renderer.h" #include "FileData.h" #include "GuiComponent.h" -#include "Renderer.h" class ThemeData; class Window; diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 9e4302f1e..050305557 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -14,7 +14,6 @@ set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/MameNames.h ${CMAKE_CURRENT_SOURCE_DIR}/src/platform.h ${CMAKE_CURRENT_SOURCE_DIR}/src/PowerSaver.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.h ${CMAKE_CURRENT_SOURCE_DIR}/src/ThemeData.h @@ -64,6 +63,9 @@ set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3f.h ${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector4f.h + # Renderers + ${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer.h + # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h @@ -90,8 +92,6 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/MameNames.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/platform.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/PowerSaver.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_draw_gl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_init_sdlgl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Scripting.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.cpp @@ -137,6 +137,11 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3f.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector4f.cpp + # Renderer + ${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GL21.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GLES10.cpp + # Resources ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index 9b7d22aa2..e29f2fcf9 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -2,8 +2,8 @@ #include "animations/Animation.h" #include "animations/AnimationController.h" +#include "renderers/Renderer.h" #include "Log.h" -#include "Renderer.h" #include "ThemeData.h" #include "Window.h" #include diff --git a/es-core/src/HelpStyle.cpp b/es-core/src/HelpStyle.cpp index 383ce821e..3d3d4d619 100644 --- a/es-core/src/HelpStyle.cpp +++ b/es-core/src/HelpStyle.cpp @@ -1,7 +1,6 @@ #include "HelpStyle.h" #include "resources/Font.h" -#include "Renderer.h" HelpStyle::HelpStyle() { diff --git a/es-core/src/Renderer.h b/es-core/src/Renderer.h deleted file mode 100644 index 358cf4031..000000000 --- a/es-core/src/Renderer.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#ifndef ES_CORE_RENDERER_H -#define ES_CORE_RENDERER_H - -#include "math/Vector2i.h" -#include "platform.h" -#include GLHEADER - -class Font; -class GuiComponent; -class Transform4x4f; - -//The Renderer provides several higher-level functions for drawing (rectangles, text, etc.). -//Renderer_draw_gl.cpp has most of the higher-level functions and wrappers. -//Renderer_init_*.cpp has platform-specific renderer initialziation/deinitialziation code. (e.g. the Raspberry Pi sets up dispmanx/OpenGL ES) -namespace Renderer -{ - bool init(); - void deinit(); - - unsigned int getWindowWidth(); - unsigned int getWindowHeight(); - unsigned int getScreenWidth(); - unsigned int getScreenHeight(); - unsigned int getScreenOffsetX(); - unsigned int getScreenOffsetY(); - unsigned int getScreenRotate(); - - void buildGLColorArray(GLubyte* ptr, unsigned int color, unsigned int vertCount); - - //graphics commands - void swapBuffers(); - - void pushClipRect(Vector2i pos, Vector2i dim); - void popClipRect(); - - void setMatrix(const Transform4x4f& transform); - - void drawRect(int x, int y, int w, int h, unsigned int color, GLenum blend_sfactor = GL_SRC_ALPHA, GLenum blend_dfactor = GL_ONE_MINUS_SRC_ALPHA); - void drawRect(float x, float y, float w, float h, unsigned int color, GLenum blend_sfactor = GL_SRC_ALPHA, GLenum blend_dfactor = GL_ONE_MINUS_SRC_ALPHA); -} - -#endif // ES_CORE_RENDERER_H diff --git a/es-core/src/Renderer_draw_gl.cpp b/es-core/src/Renderer_draw_gl.cpp deleted file mode 100644 index cac28c5d4..000000000 --- a/es-core/src/Renderer_draw_gl.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "Renderer.h" - -#include "math/Misc.h" -#include "Log.h" -#include - -namespace Renderer { - struct ClipRect { - ClipRect(const int x, const int y, const int w, const int h) : - x(x), y(y), w(w), h(h) {}; - int x; - int y; - int w; - int h; - }; - - std::stack clipStack; - - void setColor4bArray(GLubyte* array, unsigned int color) - { - array[0] = ((color & 0xff000000) >> 24) & 255; - array[1] = ((color & 0x00ff0000) >> 16) & 255; - array[2] = ((color & 0x0000ff00) >> 8) & 255; - array[3] = ((color & 0x000000ff) ) & 255; - } - - void buildGLColorArray(GLubyte* ptr, unsigned int color, unsigned int vertCount) - { - unsigned int colorGl; - setColor4bArray((GLubyte*)&colorGl, color); - for(unsigned int i = 0; i < vertCount; i++) - { - ((GLuint*)ptr)[i] = colorGl; - } - } - - void pushClipRect(Vector2i pos, Vector2i dim) - { - ClipRect box(pos.x(), pos.y(), dim.x(), dim.y()); - if(box.w == 0) - box.w = Renderer::getScreenWidth() - box.x; - if(box.h == 0) - box.h = Renderer::getScreenHeight() - box.y; - - //glScissor starts at the bottom left of the window - //so (0, 0, 1, 1) is the bottom left pixel - //everything else uses y+ = down, so flip it to be consistent - switch(Renderer::getScreenRotate()) - { - case 0: { box = ClipRect(box.x, Renderer::getWindowHeight() - (box.y + box.h), box.w, box.h); } break; - case 1: { box = ClipRect(Renderer::getScreenHeight() - (box.y + box.h), Renderer::getWindowWidth() - (box.x + box.w), box.h, box.w); } break; - case 2: { box = ClipRect(Renderer::getScreenWidth() - (box.x + box.w), Renderer::getWindowHeight() - Renderer::getScreenHeight() + box.y, box.w, box.h); } break; - case 3: { box = ClipRect(box.y, Renderer::getWindowWidth() - Renderer::getScreenWidth() + box.x, box.h, box.w); } break; - } - - switch(Renderer::getScreenRotate()) - { - case 0: { box.x += Renderer::getScreenOffsetX(); box.y -= Renderer::getScreenOffsetY(); } break; - case 1: { box.x += Renderer::getScreenOffsetY(); box.y -= Renderer::getScreenOffsetX(); } break; - case 2: { box.x += Renderer::getScreenOffsetX(); box.y -= Renderer::getScreenOffsetY(); } break; - case 3: { box.x += Renderer::getScreenOffsetY(); box.y -= Renderer::getScreenOffsetX(); } break; - } - - //make sure the box fits within clipStack.top(), and clip further accordingly - if(clipStack.size()) - { - const ClipRect& top = clipStack.top(); - if(top.x > box.x) - box.x = top.x; - if(top.y > box.y) - box.y = top.y; - if(top.x + top.w < box.x + box.w) - box.w = (top.x + top.w) - box.x; - if(top.y + top.h < box.y + box.h) - box.h = (top.y + top.h) - box.y; - } - - if(box.w < 0) - box.w = 0; - if(box.h < 0) - box.h = 0; - - clipStack.push(box); - - glScissor(box.x, box.y, box.w, box.h); - glEnable(GL_SCISSOR_TEST); - } - - void popClipRect() - { - if(clipStack.empty()) - { - LOG(LogError) << "Tried to popClipRect while the stack was empty!"; - return; - } - - clipStack.pop(); - if(clipStack.empty()) - { - glDisable(GL_SCISSOR_TEST); - }else{ - const ClipRect& top = clipStack.top(); - glScissor(top.x, top.y, top.w, top.h); - } - } - - void drawRect(float x, float y, float w, float h, unsigned int color, GLenum blend_sfactor, GLenum blend_dfactor) - { - drawRect((int)Math::round(x), (int)Math::round(y), (int)Math::round(w), (int)Math::round(h), color, blend_sfactor, blend_dfactor); - } - - void drawRect(int x, int y, int w, int h, unsigned int color, GLenum blend_sfactor, GLenum blend_dfactor) - { -#ifdef USE_OPENGL_ES - GLshort points[12]; -#else - GLint points[12]; -#endif - - points[0] = x; points [1] = y; - points[2] = x; points[3] = y + h; - points[4] = x + w; points[5] = y; - - points[6] = x + w; points[7] = y; - points[8] = x; points[9] = y + h; - points[10] = x + w; points[11] = y + h; - - GLubyte colors[6*4]; - buildGLColorArray(colors, color, 6); - - glEnable(GL_BLEND); - glBlendFunc(blend_sfactor, blend_dfactor); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - -#ifdef USE_OPENGL_ES - glVertexPointer(2, GL_SHORT, 0, points); -#else - glVertexPointer(2, GL_INT, 0, points); -#endif - glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - glDisable(GL_BLEND); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } - - void setMatrix(const Transform4x4f& matrix) - { - glLoadMatrixf((GLfloat*)&matrix); - } -}; diff --git a/es-core/src/Renderer_init_sdlgl.cpp b/es-core/src/Renderer_init_sdlgl.cpp deleted file mode 100644 index f87cddd0c..000000000 --- a/es-core/src/Renderer_init_sdlgl.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include "Renderer.h" - -#include "resources/ResourceManager.h" -#include "ImageIO.h" -#include "Log.h" -#include "Settings.h" -#include - -#ifdef USE_OPENGL_ES - #define glOrtho glOrthof -#endif - -namespace Renderer -{ - static bool initialCursorState; - - unsigned int windowWidth = 0; - unsigned int windowHeight = 0; - unsigned int screenWidth = 0; - unsigned int screenHeight = 0; - unsigned int screenOffsetX = 0; - unsigned int screenOffsetY = 0; - unsigned int screenRotate = 0; - - unsigned int getWindowWidth() { return windowWidth; } - unsigned int getWindowHeight() { return windowHeight; } - unsigned int getScreenWidth() { return screenWidth; } - unsigned int getScreenHeight() { return screenHeight; } - unsigned int getScreenOffsetX() { return screenOffsetX; } - unsigned int getScreenOffsetY() { return screenOffsetY; } - unsigned int getScreenRotate() { return screenRotate; } - - SDL_Window* sdlWindow = NULL; - SDL_GLContext sdlContext = NULL; - - bool createSurface() - { - LOG(LogInfo) << "Creating surface..."; - - if(SDL_Init(SDL_INIT_VIDEO) != 0) - { - LOG(LogError) << "Error initializing SDL!\n " << SDL_GetError(); - return false; - } - - //hide mouse cursor early - initialCursorState = SDL_ShowCursor(0) == 1; - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - // multisample anti-aliasing - //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); - -#ifdef USE_OPENGL_ES - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); -#endif - - SDL_DisplayMode dispMode; - SDL_GetDesktopDisplayMode(0, &dispMode); - windowWidth = Settings::getInstance()->getInt("WindowWidth") ? Settings::getInstance()->getInt("WindowWidth") : dispMode.w; - windowHeight = Settings::getInstance()->getInt("WindowHeight") ? Settings::getInstance()->getInt("WindowHeight") : dispMode.h; - screenWidth = Settings::getInstance()->getInt("ScreenWidth") ? Settings::getInstance()->getInt("ScreenWidth") : windowWidth; - screenHeight = Settings::getInstance()->getInt("ScreenHeight") ? Settings::getInstance()->getInt("ScreenHeight") : windowHeight; - screenOffsetX = Settings::getInstance()->getInt("ScreenOffsetX") ? Settings::getInstance()->getInt("ScreenOffsetX") : 0; - screenOffsetY = Settings::getInstance()->getInt("ScreenOffsetY") ? Settings::getInstance()->getInt("ScreenOffsetY") : 0; - screenRotate = Settings::getInstance()->getInt("ScreenRotate") ? Settings::getInstance()->getInt("ScreenRotate") : 0; - - sdlWindow = SDL_CreateWindow("EmulationStation", - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - windowWidth, windowHeight, - SDL_WINDOW_OPENGL | (Settings::getInstance()->getBool("Windowed") ? 0 : (Settings::getInstance()->getBool("FullscreenBorderless") ? SDL_WINDOW_BORDERLESS : SDL_WINDOW_FULLSCREEN))); - - if(sdlWindow == NULL) - { - LOG(LogError) << "Error creating SDL window!\n\t" << SDL_GetError(); - return false; - } - - LOG(LogInfo) << "Created window successfully."; - - //support screen rotation - if((screenRotate == 1) || (screenRotate == 3)) - { - int temp; - temp = windowWidth; - windowWidth = windowHeight; - windowHeight = temp; - temp = screenWidth; - screenWidth = screenHeight; - screenHeight = temp; - temp = screenOffsetX; - screenOffsetX = screenOffsetY; - screenOffsetY = temp; - } - - //set an icon for the window - size_t width = 0; - size_t height = 0; - ResourceData resData = ResourceManager::getInstance()->getFileData(":/window_icon_256.png"); - std::vector rawData = ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height); - if (!rawData.empty()) - { - ImageIO::flipPixelsVert(rawData.data(), width, height); - - //SDL interprets each pixel as a 32-bit number, so our masks must depend on the endianness (byte order) of the machine - #if SDL_BYTEORDER == SDL_BIG_ENDIAN - Uint32 rmask = 0xff000000; Uint32 gmask = 0x00ff0000; Uint32 bmask = 0x0000ff00; Uint32 amask = 0x000000ff; - #else - Uint32 rmask = 0x000000ff; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x00ff0000; Uint32 amask = 0xff000000; - #endif - //try creating SDL surface from logo data - SDL_Surface * logoSurface = SDL_CreateRGBSurfaceFrom((void *)rawData.data(), (int)width, (int)height, 32, (int)(width * 4), rmask, gmask, bmask, amask); - if (logoSurface != NULL) - { - SDL_SetWindowIcon(sdlWindow, logoSurface); - SDL_FreeSurface(logoSurface); - } - } - - sdlContext = SDL_GL_CreateContext(sdlWindow); - - // vsync - if(Settings::getInstance()->getBool("VSync")) - { - // SDL_GL_SetSwapInterval(0) for immediate updates (no vsync, default), - // 1 for updates synchronized with the vertical retrace, - // or -1 for late swap tearing. - // SDL_GL_SetSwapInterval returns 0 on success, -1 on error. - // if vsync is requested, try normal vsync; if that doesn't work, try late swap tearing - // if that doesn't work, report an error - if(SDL_GL_SetSwapInterval(1) != 0 && SDL_GL_SetSwapInterval(-1) != 0) - LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")"; - } - else - SDL_GL_SetSwapInterval(0); - - return true; - } - - void destroySurface() - { - SDL_GL_DeleteContext(sdlContext); - sdlContext = NULL; - - SDL_DestroyWindow(sdlWindow); - sdlWindow = NULL; - - //show mouse cursor - SDL_ShowCursor(initialCursorState); - - SDL_Quit(); - } - - bool init() - { - if(!createSurface()) - return false; - - //gotta flip y since y=0 is at the bottom - switch(screenRotate) - { - case 0: - { - glViewport(screenOffsetX, windowHeight - screenHeight - screenOffsetY, screenWidth, screenHeight); - glMatrixMode(GL_PROJECTION); - glOrtho(0, screenWidth, screenHeight, 0, -1.0, 1.0); - } - break; - - case 1: - { - glViewport(screenOffsetY, windowWidth - screenWidth - screenOffsetX, screenHeight, screenWidth); - glMatrixMode(GL_PROJECTION); - glOrtho(0, screenHeight, screenWidth, 0, -1.0, 1.0); - glRotatef(90, 0, 0, 1); - glTranslatef(0, screenHeight * -1.0f, 0); - } - break; - - case 2: - { - glViewport(screenOffsetX, windowHeight - screenHeight - screenOffsetY, screenWidth, screenHeight); - glMatrixMode(GL_PROJECTION); - glOrtho(0, screenWidth, screenHeight, 0, -1.0, 1.0); - glRotatef(180, 0, 0, 1); - glTranslatef(screenWidth * -1.0f, screenHeight * -1.0f, 0); - } - break; - - case 3: - { - glViewport(screenOffsetY, windowWidth - screenWidth - screenOffsetX, screenHeight, screenWidth); - glMatrixMode(GL_PROJECTION); - glOrtho(0, screenHeight, screenWidth, 0, -1.0, 1.0); - glRotatef(270, 0, 0, 1); - glTranslatef(screenWidth * -1.0f, 0, 0); - } - break; - } - - glMatrixMode(GL_MODELVIEW); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - return true; - } - - void deinit() - { - destroySurface(); - } - - void swapBuffers() - { - SDL_GL_SwapWindow(sdlWindow); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } -}; diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 0f33e5e24..d3873a215 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -6,7 +6,6 @@ #include "resources/TextureResource.h" #include "InputManager.h" #include "Log.h" -#include "Renderer.h" #include "Scripting.h" #include #include diff --git a/es-core/src/components/BusyComponent.cpp b/es-core/src/components/BusyComponent.cpp index 17f36df08..a3049811f 100644 --- a/es-core/src/components/BusyComponent.cpp +++ b/es-core/src/components/BusyComponent.cpp @@ -3,7 +3,6 @@ #include "components/AnimatedImageComponent.h" #include "components/ImageComponent.h" #include "components/TextComponent.h" -#include "Renderer.h" // animation definition AnimationFrame BUSY_ANIMATION_FRAMES[] = { diff --git a/es-core/src/components/ButtonComponent.cpp b/es-core/src/components/ButtonComponent.cpp index 949604641..21e235bb4 100644 --- a/es-core/src/components/ButtonComponent.cpp +++ b/es-core/src/components/ButtonComponent.cpp @@ -2,7 +2,6 @@ #include "resources/Font.h" #include "utils/StringUtil.h" -#include "Renderer.h" ButtonComponent::ButtonComponent(Window* window, const std::string& text, const std::string& helpText, const std::function& func) : GuiComponent(window), mBox(window, ":/button.png"), diff --git a/es-core/src/components/ComponentGrid.cpp b/es-core/src/components/ComponentGrid.cpp index 066f9a3f0..10d2fdd14 100644 --- a/es-core/src/components/ComponentGrid.cpp +++ b/es-core/src/components/ComponentGrid.cpp @@ -1,6 +1,5 @@ #include "components/ComponentGrid.h" -#include "Renderer.h" #include "Settings.h" using namespace GridFlags; @@ -151,6 +150,7 @@ void ComponentGrid::updateSeparators() { mLines.clear(); + const unsigned int color = Renderer::convertColor(0xC6C7C6FF); bool drawAll = Settings::getInstance()->getBool("DebugGrid"); Vector2f pos; @@ -174,28 +174,25 @@ void ComponentGrid::updateSeparators() if(it->border & BORDER_TOP || drawAll) { - mLines.push_back(Vert(pos.x(), pos.y())); - mLines.push_back(Vert(pos.x() + size.x(), pos.y())); + mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); } if(it->border & BORDER_BOTTOM || drawAll) { - mLines.push_back(Vert(pos.x(), pos.y() + size.y())); - mLines.push_back(Vert(pos.x() + size.x(), mLines.back().y)); + mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x() + size.x(), mLines.back().pos.y() }, { 0.0f, 0.0f }, color } ); } if(it->border & BORDER_LEFT || drawAll) { - mLines.push_back(Vert(pos.x(), pos.y())); - mLines.push_back(Vert(pos.x(), pos.y() + size.y())); + mLines.push_back( { { pos.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); } if(it->border & BORDER_RIGHT || drawAll) { - mLines.push_back(Vert(pos.x() + size.x(), pos.y())); - mLines.push_back(Vert(mLines.back().x, pos.y() + size.y())); + mLines.push_back( { { pos.x() + size.x(), pos.y() }, { 0.0f, 0.0f }, color } ); + mLines.push_back( { { mLines.back().pos.x(), pos.y() + size.y() }, { 0.0f, 0.0f }, color } ); } } - - mLineColors.reserve(mLines.size()); - Renderer::buildGLColorArray((GLubyte*)mLineColors.data(), 0xC6C7C6FF, (unsigned int)mLines.size()); } void ComponentGrid::onSizeChanged() @@ -365,20 +362,8 @@ void ComponentGrid::render(const Transform4x4f& parentTrans) if(mLines.size()) { Renderer::setMatrix(trans); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(2, GL_FLOAT, 0, &mLines[0].x); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, mLineColors.data()); - - glDrawArrays(GL_LINES, 0, (GLsizei)mLines.size()); - - glDisable(GL_BLEND); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + Renderer::bindTexture(0); + Renderer::drawLines(&mLines[0], mLines.size()); } } diff --git a/es-core/src/components/ComponentGrid.h b/es-core/src/components/ComponentGrid.h index aa6519175..567f5d919 100644 --- a/es-core/src/components/ComponentGrid.h +++ b/es-core/src/components/ComponentGrid.h @@ -3,6 +3,7 @@ #define ES_CORE_COMPONENTS_COMPONENT_GRID_H #include "math/Vector2i.h" +#include "renderers/Renderer.h" #include "GuiComponent.h" namespace GridFlags @@ -96,15 +97,7 @@ private: float* mRowHeights; float* mColWidths; - struct Vert - { - Vert(float xi = 0, float yi = 0) : x(xi), y(yi) {}; - float x; - float y; - }; - - std::vector mLines; - std::vector mLineColors; + std::vector mLines; // Update position & size void updateCellComponent(const GridEntry& cell); diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index c2c42d8f3..74b6dfde6 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -1,7 +1,5 @@ #include "components/ComponentList.h" -#include "Renderer.h" - #define TOTAL_HORIZONTAL_PADDING_PX 20 ComponentList::ComponentList(Window* window) : IList(window, LIST_SCROLL_STYLE_SLOW, LIST_NEVER_LOOP) @@ -204,10 +202,8 @@ void ComponentList::render(const Transform4x4f& parentTrans) // (1 - dst) + 0x77 const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0xFFFFFFFF, - GL_ONE_MINUS_DST_COLOR, GL_ZERO); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0x777777FF, - GL_ONE, GL_ONE); + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0xFFFFFFFF, Renderer::Blend::ONE_MINUS_DST_COLOR, Renderer::Blend::ZERO); + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, 0x777777FF, Renderer::Blend::ONE, Renderer::Blend::ONE); // hack to draw 2px dark on left/right of the bar Renderer::drawRect(0.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, 0x878787FF); diff --git a/es-core/src/components/DateTimeComponent.cpp b/es-core/src/components/DateTimeComponent.cpp index 0052f11ad..2883b9056 100644 --- a/es-core/src/components/DateTimeComponent.cpp +++ b/es-core/src/components/DateTimeComponent.cpp @@ -2,7 +2,6 @@ #include "utils/StringUtil.h" #include "Log.h" -#include "Renderer.h" #include "Settings.h" DateTimeComponent::DateTimeComponent(Window* window) : TextComponent(window), mDisplayRelative(false) diff --git a/es-core/src/components/DateTimeEditComponent.cpp b/es-core/src/components/DateTimeEditComponent.cpp index d4b6636a3..efe5a9443 100644 --- a/es-core/src/components/DateTimeEditComponent.cpp +++ b/es-core/src/components/DateTimeEditComponent.cpp @@ -2,7 +2,6 @@ #include "resources/Font.h" #include "utils/StringUtil.h" -#include "Renderer.h" DateTimeEditComponent::DateTimeEditComponent(Window* window, DisplayMode dispMode) : GuiComponent(window), mEditing(false), mEditIndex(0), mDisplayMode(dispMode), mRelativeUpdateAccumulator(0), diff --git a/es-core/src/components/GridTileComponent.cpp b/es-core/src/components/GridTileComponent.cpp index 745fede1a..842c268b2 100644 --- a/es-core/src/components/GridTileComponent.cpp +++ b/es-core/src/components/GridTileComponent.cpp @@ -2,7 +2,6 @@ #include "resources/TextureResource.h" #include "ThemeData.h" -#include "Renderer.h" GridTileComponent::GridTileComponent(Window* window) : GuiComponent(window), mBackground(window) { diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 14f5fac13..df86447a9 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -2,7 +2,6 @@ #include "resources/TextureResource.h" #include "Log.h" -#include "Renderer.h" #include "Settings.h" #include "ThemeData.h" @@ -268,51 +267,36 @@ void ImageComponent::updateVertices() // we go through this mess to make sure everything is properly rounded // if we just round vertices at the end, edge cases occur near sizes of 0.5 - Vector2f size(Math::round(mSize.x()), Math::round(mSize.y())); - Vector2f topLeft(size * mTopLeftCrop); - Vector2f bottomRight(size * mBottomRightCrop); + const Vector2f size = { Math::round(mSize.x()), Math::round(mSize.y()) }; + const Vector2f topLeft = { size * mTopLeftCrop }; + const Vector2f bottomRight = { size * mBottomRightCrop }; + const float px = mTexture->isTiled() ? mSize.x() / getTextureSize().x() : 1.0f; + const float py = mTexture->isTiled() ? mSize.y() / getTextureSize().y() : 1.0f; + const unsigned int color = Renderer::convertColor(mColorShift); - mVertices[0].pos = Vector2f(topLeft.x(), topLeft.y()); - mVertices[1].pos = Vector2f(topLeft.x(), bottomRight.y()); - mVertices[2].pos = Vector2f(bottomRight.x(), topLeft.y()); - - mVertices[3].pos = Vector2f(bottomRight.x(), topLeft.y()); - mVertices[4].pos = Vector2f(topLeft.x(), bottomRight.y()); - mVertices[5].pos = Vector2f(bottomRight.x(), bottomRight.y()); - - float px, py; - if(mTexture->isTiled()) - { - px = mSize.x() / getTextureSize().x(); - py = mSize.y() / getTextureSize().y(); - }else{ - px = 1; - py = 1; - } - - mVertices[0].tex = Vector2f(mTopLeftCrop.x(), py - mTopLeftCrop.y()); - mVertices[1].tex = Vector2f(mTopLeftCrop.x(), 1 - mBottomRightCrop.y()); - mVertices[2].tex = Vector2f(px * mBottomRightCrop.x(), py - mTopLeftCrop.y()); - - mVertices[3].tex = Vector2f(px * mBottomRightCrop.x(), py - mTopLeftCrop.y()); - mVertices[4].tex = Vector2f(mTopLeftCrop.x(), 1 - mBottomRightCrop.y()); - mVertices[5].tex = Vector2f(px * mBottomRightCrop.x(), 1 - mBottomRightCrop.y()); + mVertices[0] = { { topLeft.x(), topLeft.y() }, { mTopLeftCrop.x(), py - mTopLeftCrop.y() }, color }; + mVertices[1] = { { topLeft.x(), bottomRight.y() }, { mTopLeftCrop.x(), 1.0f - mBottomRightCrop.y() }, color }; + mVertices[2] = { { bottomRight.x(), topLeft.y() }, { mBottomRightCrop.x() * px, py - mTopLeftCrop.y() }, color }; + mVertices[3] = { { bottomRight.x(), bottomRight.y() }, { mBottomRightCrop.x() * px, 1.0f - mBottomRightCrop.y() }, color }; if(mFlipX) { - for(int i = 0; i < 6; i++) + for(int i = 0; i < 4; i++) mVertices[i].tex[0] = px - mVertices[i].tex[0]; } if(mFlipY) { - for(int i = 0; i < 6; i++) + for(int i = 0; i < 4; i++) mVertices[i].tex[1] = py - mVertices[i].tex[1]; } } void ImageComponent::updateColors() { - Renderer::buildGLColorArray(mColors, mColorShift, 6); + const unsigned int color = Renderer::convertColor(mColorShift); + + for(int i = 0; i < 4; ++i) + mVertices[i].col = color; } void ImageComponent::render(const Transform4x4f& parentTrans) @@ -334,27 +318,8 @@ void ImageComponent::render(const Transform4x4f& parentTrans) // texture is bound in this case but we want to handle a fade so it doesn't just 'jump' in // when it finally loads fadeIn(mTexture->bind()); + Renderer::drawTriangleStrips(&mVertices[0], 4); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, mColors); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); }else{ LOG(LogError) << "Image texture is not initialized!"; mTexture.reset(); diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index 7a93a0d85..9d3121c51 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -2,10 +2,9 @@ #ifndef ES_CORE_COMPONENTS_IMAGE_COMPONENT_H #define ES_CORE_COMPONENTS_IMAGE_COMPONENT_H +#include "renderers/Renderer.h" #include "math/Vector2i.h" #include "GuiComponent.h" -#include "platform.h" -#include GLHEADER class TextureResource; @@ -83,13 +82,7 @@ private: // Used internally whenever the resizing parameters or texture change. void resize(); - struct Vertex - { - Vector2f pos; - Vector2f tex; - } mVertices[6]; - - GLubyte mColors[6*4]; + Renderer::Vertex mVertices[4]; void updateVertices(); void updateColors(); diff --git a/es-core/src/components/MenuComponent.h b/es-core/src/components/MenuComponent.h index 7babd2d3a..ad2f69db1 100644 --- a/es-core/src/components/MenuComponent.h +++ b/es-core/src/components/MenuComponent.h @@ -7,7 +7,6 @@ #include "components/NinePatchComponent.h" #include "components/TextComponent.h" #include "utils/StringUtil.h" -#include "Renderer.h" class ButtonComponent; class ImageComponent; diff --git a/es-core/src/components/NinePatchComponent.cpp b/es-core/src/components/NinePatchComponent.cpp index fedf95115..d6c55ed0b 100644 --- a/es-core/src/components/NinePatchComponent.cpp +++ b/es-core/src/components/NinePatchComponent.cpp @@ -2,14 +2,13 @@ #include "resources/TextureResource.h" #include "Log.h" -#include "Renderer.h" #include "ThemeData.h" NinePatchComponent::NinePatchComponent(Window* window, const std::string& path, unsigned int edgeColor, unsigned int centerColor) : GuiComponent(window), mCornerSize(16, 16), mEdgeColor(edgeColor), mCenterColor(centerColor), mPath(path), - mVertices(NULL), mColors(NULL) + mVertices(NULL) { if(!mPath.empty()) buildVertices(); @@ -19,15 +18,18 @@ NinePatchComponent::~NinePatchComponent() { if (mVertices != NULL) delete[] mVertices; - - if (mColors != NULL) - delete[] mColors; } void NinePatchComponent::updateColors() { - Renderer::buildGLColorArray(mColors, mEdgeColor, 6 * 9); - Renderer::buildGLColorArray(&mColors[4 * 6 * 4], mCenterColor, 6); + const unsigned int edgeColor = Renderer::convertColor(mEdgeColor); + const unsigned int centerColor = Renderer::convertColor(mCenterColor); + + for(int i = 0; i < 6*9; ++i) + mVertices[i].col = edgeColor; + + for(int i = 6*4; i < 6; ++i) + mVertices[(6*4)+i].col = mCenterColor; } void NinePatchComponent::buildVertices() @@ -35,61 +37,48 @@ void NinePatchComponent::buildVertices() if(mVertices != NULL) delete[] mVertices; - if(mColors != NULL) - delete[] mColors; - mTexture = TextureResource::get(mPath); if(mTexture->getSize() == Vector2i::Zero()) { mVertices = NULL; - mColors = NULL; LOG(LogWarning) << "NinePatchComponent missing texture!"; return; } - mVertices = new Vertex[6 * 9]; - mColors = new GLubyte[6 * 9 * 4]; - updateColors(); + mVertices = new Renderer::Vertex[6 * 9]; const Vector2f texSize = Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y()); - float imgSizeX[3] = {mCornerSize.x(), mSize.x() - mCornerSize.x() * 2, mCornerSize.x()}; - float imgSizeY[3] = {mCornerSize.y(), mSize.y() - mCornerSize.y() * 2, mCornerSize.y()}; - float imgPosX[3] = {0, imgSizeX[0], imgSizeX[0] + imgSizeX[1]}; - float imgPosY[3] = {0, imgSizeY[0], imgSizeY[0] + imgSizeY[1]}; + const float imgSizeX[3] = { mCornerSize.x(), mSize.x() - mCornerSize.x() * 2, mCornerSize.x()}; + const float imgSizeY[3] = { mCornerSize.y(), mSize.y() - mCornerSize.y() * 2, mCornerSize.y()}; + const float imgPosX[3] = { 0, imgSizeX[0], imgSizeX[0] + imgSizeX[1]}; + const float imgPosY[3] = { 0, imgSizeY[0], imgSizeY[0] + imgSizeY[1]}; //the "1 +" in posY and "-" in sizeY is to deal with texture coordinates having a bottom left corner origin vs. verticies having a top left origin - float texSizeX[3] = {mCornerSize.x() / texSize.x(), (texSize.x() - mCornerSize.x() * 2) / texSize.x(), mCornerSize.x() / texSize.x()}; - float texSizeY[3] = {-mCornerSize.y() / texSize.y(), -(texSize.y() - mCornerSize.y() * 2) / texSize.y(), -mCornerSize.y() / texSize.y()}; - float texPosX[3] = {0, texSizeX[0], texSizeX[0] + texSizeX[1]}; - float texPosY[3] = {1, 1 + texSizeY[0], 1 + texSizeY[0] + texSizeY[1]}; + const float texSizeX[3] = { mCornerSize.x() / texSize.x(), (texSize.x() - mCornerSize.x() * 2) / texSize.x(), mCornerSize.x() / texSize.x() }; + const float texSizeY[3] = { -mCornerSize.y() / texSize.y(), -(texSize.y() - mCornerSize.y() * 2) / texSize.y(), -mCornerSize.y() / texSize.y() }; + const float texPosX[3] = { 0, texSizeX[0], texSizeX[0] + texSizeX[1] }; + const float texPosY[3] = { 1, 1 + texSizeY[0], 1 + texSizeY[0] + texSizeY[1] }; int v = 0; for(int slice = 0; slice < 9; slice++) { - int sliceX = slice % 3; - int sliceY = slice / 3; + const int sliceX = slice % 3; + const int sliceY = slice / 3; + const Vector2f imgPos = Vector2f(imgPosX[sliceX], imgPosY[sliceY]); + const Vector2f imgSize = Vector2f(imgSizeX[sliceX], imgSizeY[sliceY]); + const Vector2f texPos = Vector2f(texPosX[sliceX], texPosY[sliceY]); + const Vector2f texSize = Vector2f(texSizeX[sliceX], texSizeY[sliceY]); - Vector2f imgPos = Vector2f(imgPosX[sliceX], imgPosY[sliceY]); - Vector2f imgSize = Vector2f(imgSizeX[sliceX], imgSizeY[sliceY]); + mVertices[v + 1] = { { imgPos.x() , imgPos.y() }, { texPos.x(), texPos.y() }, 0 }; + mVertices[v + 2] = { { imgPos.x() , imgPos.y() + imgSize.y() }, { texPos.x(), texPos.y() + texSize.y() }, 0 }; + mVertices[v + 3] = { { imgPos.x() + imgSize.x(), imgPos.y() }, { texPos.x() + texSize.x(), texPos.y() }, 0 }; + mVertices[v + 4] = { { imgPos.x() + imgSize.x(), imgPos.y() + imgSize.y() }, { texPos.x() + texSize.x(), texPos.y() + texSize.y() }, 0 }; - mVertices[v + 0].pos = imgPos; - mVertices[v + 1].pos = imgPos + Vector2f(0, imgSize.y()); - mVertices[v + 2].pos = imgPos + Vector2f(imgSize.x(), 0); - mVertices[v + 3].pos = mVertices[v + 2].pos; - mVertices[v + 4].pos = mVertices[v + 1].pos; - mVertices[v + 5].pos = imgPos + imgSize; - - Vector2f texPos = Vector2f(texPosX[sliceX], texPosY[sliceY]); - Vector2f texSize = Vector2f(texSizeX[sliceX], texSizeY[sliceY]); - - mVertices[v + 0].tex = texPos; - mVertices[v + 1].tex = texPos + Vector2f(0, texSize.y()); - mVertices[v + 2].tex = texPos + Vector2f(texSize.x(), 0); - mVertices[v + 3].tex = mVertices[v + 2].tex; - mVertices[v + 4].tex = mVertices[v + 1].tex; - mVertices[v + 5].tex = texPos + texSize; + // make duplicates of first and last vertex so this can be rendered as a triangle strip + mVertices[v + 0] = mVertices[v + 1]; + mVertices[v + 5] = mVertices[v + 4]; v += 6; } @@ -99,6 +88,8 @@ void NinePatchComponent::buildVertices() { mVertices[i].pos.round(); } + + updateColors(); } void NinePatchComponent::render(const Transform4x4f& parentTrans) @@ -111,27 +102,7 @@ void NinePatchComponent::render(const Transform4x4f& parentTrans) Renderer::setMatrix(trans); mTexture->bind(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, mColors); - - glDrawArrays(GL_TRIANGLES, 0, 6 * 9); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); + Renderer::drawTriangleStrips(&mVertices[0], 6*9); } renderChildren(trans); diff --git a/es-core/src/components/NinePatchComponent.h b/es-core/src/components/NinePatchComponent.h index af9e3b934..584dc61e3 100644 --- a/es-core/src/components/NinePatchComponent.h +++ b/es-core/src/components/NinePatchComponent.h @@ -2,9 +2,8 @@ #ifndef ES_CORE_COMPONENTS_NINE_PATCH_COMPONENT_H #define ES_CORE_COMPONENTS_NINE_PATCH_COMPONENT_H +#include "renderers/Renderer.h" #include "GuiComponent.h" -#include "platform.h" -#include GLHEADER class TextureResource; @@ -45,14 +44,7 @@ private: void buildVertices(); void updateColors(); - struct Vertex - { - Vector2f pos; - Vector2f tex; - }; - - Vertex* mVertices; - GLubyte* mColors; + Renderer::Vertex* mVertices; std::string mPath; Vector2f mCornerSize; diff --git a/es-core/src/components/ScrollableContainer.cpp b/es-core/src/components/ScrollableContainer.cpp index cedc547ce..c0e6e6961 100644 --- a/es-core/src/components/ScrollableContainer.cpp +++ b/es-core/src/components/ScrollableContainer.cpp @@ -1,6 +1,7 @@ #include "components/ScrollableContainer.h" -#include "Renderer.h" +#include "math/Vector2i.h" +#include "renderers/Renderer.h" #define AUTO_SCROLL_RESET_DELAY 3000 // ms to reset to top after we reach the bottom #define AUTO_SCROLL_DELAY 1000 // ms to wait before we start to scroll diff --git a/es-core/src/components/SliderComponent.cpp b/es-core/src/components/SliderComponent.cpp index 619c79835..c3b49ed18 100644 --- a/es-core/src/components/SliderComponent.cpp +++ b/es-core/src/components/SliderComponent.cpp @@ -1,7 +1,6 @@ #include "components/SliderComponent.h" #include "resources/Font.h" -#include "Renderer.h" #define MOVE_REPEAT_DELAY 500 #define MOVE_REPEAT_RATE 40 diff --git a/es-core/src/components/SwitchComponent.cpp b/es-core/src/components/SwitchComponent.cpp index ec549020b..dd01b1807 100644 --- a/es-core/src/components/SwitchComponent.cpp +++ b/es-core/src/components/SwitchComponent.cpp @@ -1,7 +1,6 @@ #include "SwitchComponent.h" #include "resources/Font.h" -#include "Renderer.h" SwitchComponent::SwitchComponent(Window* window, bool state) : GuiComponent(window), mImage(window), mState(state) { diff --git a/es-core/src/components/TextComponent.cpp b/es-core/src/components/TextComponent.cpp index d1fc995f4..b5a22760a 100644 --- a/es-core/src/components/TextComponent.cpp +++ b/es-core/src/components/TextComponent.cpp @@ -2,7 +2,6 @@ #include "utils/StringUtil.h" #include "Log.h" -#include "Renderer.h" #include "Settings.h" TextComponent::TextComponent(Window* window) : GuiComponent(window), diff --git a/es-core/src/components/TextEditComponent.cpp b/es-core/src/components/TextEditComponent.cpp index c90ff504b..c5b2bce5b 100644 --- a/es-core/src/components/TextEditComponent.cpp +++ b/es-core/src/components/TextEditComponent.cpp @@ -2,7 +2,6 @@ #include "resources/Font.h" #include "utils/StringUtil.h" -#include "Renderer.h" #define TEXT_PADDING_HORIZ 10 #define TEXT_PADDING_VERT 2 diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index 6cd5f082a..3b9e9a7cf 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -3,7 +3,6 @@ #include "resources/ResourceManager.h" #include "utils/FileSystemUtil.h" #include "PowerSaver.h" -#include "Renderer.h" #include "ThemeData.h" #include "Window.h" #include diff --git a/es-core/src/components/VideoPlayerComponent.cpp b/es-core/src/components/VideoPlayerComponent.cpp index 0b0948e42..62711aecb 100644 --- a/es-core/src/components/VideoPlayerComponent.cpp +++ b/es-core/src/components/VideoPlayerComponent.cpp @@ -1,9 +1,9 @@ #ifdef _RPI_ #include "components/VideoPlayerComponent.h" +#include "renderers/Renderer.h" #include "utils/StringUtil.h" #include "AudioManager.h" -#include "Renderer.h" #include "Settings.h" #include #include @@ -115,7 +115,7 @@ void VideoPlayerComponent::startVideo() case 1: { - const int x1 = (int)(Renderer::getScreenOffsetY() + Renderer::getScreenHeight() - y - mSize.y()); + const int x1 = (int)(Renderer::getScreenWidth() - Renderer::getScreenOffsetY() - y - mSize.y()); const int y1 = (int)(Renderer::getScreenOffsetX() + x); const int x2 = (int)(x1 + mSize.y()); const int y2 = (int)(y1 + mSize.x()); @@ -125,8 +125,8 @@ void VideoPlayerComponent::startVideo() case 2: { - const int x1 = (int)(Renderer::getScreenOffsetX() + Renderer::getScreenWidth() - x - mSize.x()); - const int y1 = (int)(Renderer::getScreenOffsetY() + Renderer::getScreenHeight() - y - mSize.y()); + const int x1 = (int)(Renderer::getScreenWidth() - Renderer::getScreenOffsetX() - x - mSize.x()); + const int y1 = (int)(Renderer::getScreenHeight() - Renderer::getScreenOffsetY() - y - mSize.y()); const int x2 = (int)(x1 + mSize.x()); const int y2 = (int)(y1 + mSize.y()); sprintf(buf1, "%d,%d,%d,%d", x1, y1, x2, y2); @@ -136,7 +136,7 @@ void VideoPlayerComponent::startVideo() case 3: { const int x1 = (int)(Renderer::getScreenOffsetY() + y); - const int y1 = (int)(Renderer::getScreenOffsetX() + Renderer::getScreenWidth() - x - mSize.x()); + const int y1 = (int)(Renderer::getScreenHeight() - Renderer::getScreenOffsetX() - x - mSize.x()); const int x2 = (int)(x1 + mSize.y()); const int y2 = (int)(y1 + mSize.x()); sprintf(buf1, "%d,%d,%d,%d", x1, y1, x2, y2); diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp index 91f7532e4..19f00c09f 100644 --- a/es-core/src/components/VideoVlcComponent.cpp +++ b/es-core/src/components/VideoVlcComponent.cpp @@ -1,9 +1,9 @@ #include "components/VideoVlcComponent.h" +#include "renderers/Renderer.h" #include "resources/TextureResource.h" #include "utils/StringUtil.h" #include "PowerSaver.h" -#include "Renderer.h" #include "Settings.h" #include #include @@ -132,8 +132,6 @@ void VideoVlcComponent::resize() void VideoVlcComponent::render(const Transform4x4f& parentTrans) { VideoComponent::render(parentTrans); - float x, y; - Transform4x4f trans = parentTrans * getTransform(); GuiComponent::renderChildren(trans); @@ -141,73 +139,24 @@ void VideoVlcComponent::render(const Transform4x4f& parentTrans) if (mIsPlaying && mContext.valid) { - float tex_offs_x = 0.0f; - float tex_offs_y = 0.0f; - float x2; - float y2; + const unsigned int fadeIn = (unsigned int)(Math::clamp(0.0f, mFadeIn, 1.0f) * 255.0f); + const unsigned int color = Renderer::convertColor((fadeIn << 24) | (fadeIn << 16) | (fadeIn << 8) | 255); + Renderer::Vertex vertices[4]; - x = 0.0; - y = 0.0; - x2 = mSize.x(); - y2 = mSize.y(); - - // Define a structure to contain the data for each vertex - struct Vertex - { - Vector2f pos; - Vector2f tex; - Vector4f colour; - } vertices[6]; - - // We need two triangles to cover the rectangular area - vertices[0].pos[0] = x; vertices[0].pos[1] = y; - vertices[1].pos[0] = x; vertices[1].pos[1] = y2; - vertices[2].pos[0] = x2; vertices[2].pos[1] = y; - - vertices[3].pos[0] = x2; vertices[3].pos[1] = y; - vertices[4].pos[0] = x; vertices[4].pos[1] = y2; - vertices[5].pos[0] = x2; vertices[5].pos[1] = y2; - - // Texture coordinates - vertices[0].tex[0] = -tex_offs_x; vertices[0].tex[1] = -tex_offs_y; - vertices[1].tex[0] = -tex_offs_x; vertices[1].tex[1] = 1.0f + tex_offs_y; - vertices[2].tex[0] = 1.0f + tex_offs_x; vertices[2].tex[1] = -tex_offs_y; - - vertices[3].tex[0] = 1.0f + tex_offs_x; vertices[3].tex[1] = -tex_offs_y; - vertices[4].tex[0] = -tex_offs_x; vertices[4].tex[1] = 1.0f + tex_offs_y; - vertices[5].tex[0] = 1.0f + tex_offs_x; vertices[5].tex[1] = 1.0f + tex_offs_y; - - // Colours - use this to fade the video in and out - for (int i = 0; i < (4 * 6); ++i) { - if ((i%4) < 3) - vertices[i / 4].colour[i % 4] = mFadeIn; - else - vertices[i / 4].colour[i % 4] = 1.0f; - } - - glEnable(GL_TEXTURE_2D); + vertices[0] = { { 0.0f , 0.0f }, { 0.0f, 0.0f }, color }; + vertices[1] = { { 0.0f , mSize.y() }, { 0.0f, 1.0f }, color }; + vertices[2] = { { mSize.x(), 0.0f }, { 1.0f, 0.0f }, color }; + vertices[3] = { { mSize.x(), mSize.y() }, { 1.0f, 1.0f }, color }; // Build a texture for the video frame mTexture->initFromPixels((unsigned char*)mContext.surface->pixels, mContext.surface->w, mContext.surface->h); mTexture->bind(); // Render it - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glColorPointer(4, GL_FLOAT, sizeof(Vertex), &vertices[0].colour); - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].pos); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].tex); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - } else { + Renderer::drawTriangleStrips(&vertices[0], 4); + } + else + { VideoComponent::renderSnapshot(parentTrans); } } diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index faadbf4ac..6632945e6 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -6,7 +6,6 @@ #include "utils/StringUtil.h" #include "InputManager.h" #include "PowerSaver.h" -#include "Renderer.h" #include "Window.h" #define HOLD_TIME 1000 diff --git a/es-core/src/platform.h b/es-core/src/platform.h index 7ffaf5d31..9c5220bc3 100644 --- a/es-core/src/platform.h +++ b/es-core/src/platform.h @@ -4,21 +4,9 @@ #include -//the Makefile defines one of these: -//#define USE_OPENGL_ES -//#define USE_OPENGL_DESKTOP - -#ifdef USE_OPENGL_ES - #define GLHEADER -#endif - -#ifdef USE_OPENGL_DESKTOP - //why the hell this naming inconsistency exists is well beyond me - #ifdef WIN32 - #define sleep Sleep - #endif - - #define GLHEADER +//why the hell this naming inconsistency exists is well beyond me +#ifdef WIN32 + #define sleep Sleep #endif int runShutdownCommand(); // shut down the system (returns 0 if successful) diff --git a/es-core/src/renderers/Renderer.cpp b/es-core/src/renderers/Renderer.cpp new file mode 100644 index 000000000..b107f1d29 --- /dev/null +++ b/es-core/src/renderers/Renderer.cpp @@ -0,0 +1,269 @@ +#include "renderers/Renderer.h" + +#include "math/Transform4x4f.h" +#include "math/Vector2i.h" +#include "resources/ResourceManager.h" +#include "ImageIO.h" +#include "Log.h" +#include "Settings.h" + +#include +#include + +namespace Renderer +{ + static std::stack clipStack; + static SDL_Window* sdlWindow = nullptr; + static int windowWidth = 0; + static int windowHeight = 0; + static int screenWidth = 0; + static int screenHeight = 0; + static int screenOffsetX = 0; + static int screenOffsetY = 0; + static int screenRotate = 0; + static bool initialCursorState = 1; + + static void setIcon() + { + size_t width = 0; + size_t height = 0; + ResourceData resData = ResourceManager::getInstance()->getFileData(":/window_icon_256.png"); + std::vector rawData = ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height); + + if(!rawData.empty()) + { + ImageIO::flipPixelsVert(rawData.data(), width, height); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + unsigned int rmask = 0xFF000000; + unsigned int gmask = 0x00FF0000; + unsigned int bmask = 0x0000FF00; + unsigned int amask = 0x000000FF; +#else + unsigned int rmask = 0x000000FF; + unsigned int gmask = 0x0000FF00; + unsigned int bmask = 0x00FF0000; + unsigned int amask = 0xFF000000; +#endif + // try creating SDL surface from logo data + SDL_Surface* logoSurface = SDL_CreateRGBSurfaceFrom((void*)rawData.data(), (int)width, (int)height, 32, (int)(width * 4), rmask, gmask, bmask, amask); + + if(logoSurface != nullptr) + { + SDL_SetWindowIcon(sdlWindow, logoSurface); + SDL_FreeSurface(logoSurface); + } + } + + } // setIcon + + static bool createWindow() + { + LOG(LogInfo) << "Creating window..."; + + if(SDL_Init(SDL_INIT_VIDEO) != 0) + { + LOG(LogError) << "Error initializing SDL!\n " << SDL_GetError(); + return false; + } + + initialCursorState = (SDL_ShowCursor(0) != 0); + + SDL_DisplayMode dispMode; + SDL_GetDesktopDisplayMode(0, &dispMode); + windowWidth = Settings::getInstance()->getInt("WindowWidth") ? Settings::getInstance()->getInt("WindowWidth") : dispMode.w; + windowHeight = Settings::getInstance()->getInt("WindowHeight") ? Settings::getInstance()->getInt("WindowHeight") : dispMode.h; + screenWidth = Settings::getInstance()->getInt("ScreenWidth") ? Settings::getInstance()->getInt("ScreenWidth") : windowWidth; + screenHeight = Settings::getInstance()->getInt("ScreenHeight") ? Settings::getInstance()->getInt("ScreenHeight") : windowHeight; + screenOffsetX = Settings::getInstance()->getInt("ScreenOffsetX") ? Settings::getInstance()->getInt("ScreenOffsetX") : 0; + screenOffsetY = Settings::getInstance()->getInt("ScreenOffsetY") ? Settings::getInstance()->getInt("ScreenOffsetY") : 0; + screenRotate = Settings::getInstance()->getInt("ScreenRotate") ? Settings::getInstance()->getInt("ScreenRotate") : 0; + + setupWindow(); + + unsigned int windowFlags = (Settings::getInstance()->getBool("Windowed") ? 0 : (Settings::getInstance()->getBool("FullscreenBorderless") ? SDL_WINDOW_BORDERLESS : SDL_WINDOW_FULLSCREEN)) | getWindowFlags(); + + if((sdlWindow = SDL_CreateWindow("EmulationStation", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, windowFlags)) == nullptr) + { + LOG(LogError) << "Error creating SDL window!\n\t" << SDL_GetError(); + return false; + } + + LOG(LogInfo) << "Created window successfully."; + + createContext(); + setIcon(); + setSwapInterval(); + + return true; + + } // createWindow + + static void destroyWindow() + { + destroyContext(); + + SDL_DestroyWindow(sdlWindow); + sdlWindow = nullptr; + + SDL_ShowCursor(initialCursorState); + + SDL_Quit(); + + } // destroyWindow + + bool init() + { + if(!createWindow()) + return false; + + Transform4x4f projection = Transform4x4f::Identity(); + Rect viewport = Rect(0, 0, 0, 0); + + switch(screenRotate) + { + case 0: + { + viewport.x = screenOffsetX; + viewport.y = screenOffsetY; + viewport.w = screenWidth; + viewport.h = screenHeight; + + projection.orthoProjection(0, screenWidth, screenHeight, 0, -1.0, 1.0); + } + break; + + case 1: + { + viewport.x = windowWidth - screenOffsetY - screenHeight; + viewport.y = screenOffsetX; + viewport.w = screenHeight; + viewport.h = screenWidth; + + projection.orthoProjection(0, screenHeight, screenWidth, 0, -1.0, 1.0); + projection.rotate((float)ES_DEG_TO_RAD(90), {0, 0, 1}); + projection.translate({0, screenHeight * -1.0f, 0}); + } + break; + + case 2: + { + viewport.x = windowWidth - screenOffsetX - screenWidth; + viewport.y = windowHeight - screenOffsetY - screenHeight; + viewport.w = screenWidth; + viewport.h = screenHeight; + + projection.orthoProjection(0, screenWidth, screenHeight, 0, -1.0, 1.0); + projection.rotate((float)ES_DEG_TO_RAD(180), {0, 0, 1}); + projection.translate({screenWidth * -1.0f, screenHeight * -1.0f, 0}); + } + break; + + case 3: + { + viewport.x = screenOffsetY; + viewport.y = windowHeight - screenOffsetX - screenWidth; + viewport.w = screenHeight; + viewport.h = screenWidth; + + projection.orthoProjection(0, screenHeight, screenWidth, 0, -1.0, 1.0); + projection.rotate((float)ES_DEG_TO_RAD(270), {0, 0, 1}); + projection.translate({screenWidth * -1.0f, 0, 0}); + } + break; + } + + setViewport(viewport); + setProjection(projection); + swapBuffers(); + + return true; + + } // init + + void deinit() + { + destroyWindow(); + + } // deinit + + void pushClipRect(const Vector2i& _pos, const Vector2i& _size) + { + Rect box(_pos.x(), _pos.y(), _size.x(), _size.y()); + + if(box.w == 0) box.w = screenWidth - box.x; + if(box.h == 0) box.h = screenHeight - box.y; + + switch(screenRotate) + { + case 0: { box = Rect(screenOffsetX + box.x, screenOffsetY + box.y, box.w, box.h); } break; + case 1: { box = Rect(windowWidth - screenOffsetY - box.y - box.h, screenOffsetX + box.x, box.h, box.w); } break; + case 2: { box = Rect(windowWidth - screenOffsetX - box.x - box.w, windowHeight - screenOffsetY - box.y - box.h, box.w, box.h); } break; + case 3: { box = Rect(screenOffsetY + box.y, windowHeight - screenOffsetX - box.x - box.w, box.h, box.w); } break; + } + + // make sure the box fits within clipStack.top(), and clip further accordingly + if(clipStack.size()) + { + const Rect& top = clipStack.top(); + if( top.x > box.x) box.x = top.x; + if( top.y > box.y) box.y = top.y; + if((top.x + top.w) < (box.x + box.w)) box.w = (top.x + top.w) - box.x; + if((top.y + top.h) < (box.y + box.h)) box.h = (top.y + top.h) - box.y; + } + + if(box.w < 0) box.w = 0; + if(box.h < 0) box.h = 0; + + clipStack.push(box); + + setScissor(box); + + } // pushClipRect + + void popClipRect() + { + if(clipStack.empty()) + { + LOG(LogError) << "Tried to popClipRect while the stack was empty!"; + return; + } + + clipStack.pop(); + + if(clipStack.empty()) setScissor(Rect(0, 0, 0, 0)); + else setScissor(clipStack.top()); + + } // popClipRect + + void drawRect(const float _x, const float _y, const float _w, const float _h, const unsigned int _color, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + drawRect((int)Math::round(_x), (int)Math::round(_y), (int)Math::round(_w), (int)Math::round(_h), _color, _srcBlendFactor, _dstBlendFactor); + + } // drawRect + + void drawRect(const int _x, const int _y, const int _w, const int _h, const unsigned int _color, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + const unsigned int color = convertColor(_color); + Vertex vertices[4]; + + vertices[0] = { { (float)(_x ), (float)(_y ) }, { 0.0f, 0.0f }, color }; + vertices[1] = { { (float)(_x ), (float)(_y + _h) }, { 0.0f, 0.0f }, color }; + vertices[2] = { { (float)(_x + _w), (float)(_y ) }, { 0.0f, 0.0f }, color }; + vertices[3] = { { (float)(_x + _w), (float)(_y + _h) }, { 0.0f, 0.0f }, color }; + + bindTexture(0); + drawTriangleStrips(vertices, 4, _srcBlendFactor, _dstBlendFactor); + + } // drawRect + + SDL_Window* getSDLWindow() { return sdlWindow; } + int getWindowWidth() { return windowWidth; } + int getWindowHeight() { return windowHeight; } + int getScreenWidth() { return screenWidth; } + int getScreenHeight() { return screenHeight; } + int getScreenOffsetX() { return screenOffsetX; } + int getScreenOffsetY() { return screenOffsetY; } + int getScreenRotate() { return screenRotate; } + +} // Renderer:: diff --git a/es-core/src/renderers/Renderer.h b/es-core/src/renderers/Renderer.h new file mode 100644 index 000000000..3a409d7a7 --- /dev/null +++ b/es-core/src/renderers/Renderer.h @@ -0,0 +1,102 @@ +#pragma once +#ifndef ES_CORE_RENDERER_RENDERER_H +#define ES_CORE_RENDERER_RENDERER_H + +#include "math/Vector2f.h" + +class Transform4x4f; +class Vector2i; +struct SDL_Window; + +namespace Renderer +{ + namespace Blend + { + enum Factor + { + ZERO = 0, + ONE = 1, + SRC_COLOR = 2, + ONE_MINUS_SRC_COLOR = 3, + SRC_ALPHA = 4, + ONE_MINUS_SRC_ALPHA = 5, + DST_COLOR = 6, + ONE_MINUS_DST_COLOR = 7, + DST_ALPHA = 8, + ONE_MINUS_DST_ALPHA = 9 + + }; // Factor + + } // Blend:: + + namespace Texture + { + enum Type + { + RGBA = 0, + ALPHA = 1 + + }; // Type + + } // Texture:: + + struct Rect + { + Rect(const int _x, const int _y, const int _w, const int _h) : x(_x), y(_y), w(_w), h(_h) { } + + int x; + int y; + int w; + int h; + + }; // Rect + + struct Vertex + { + Vertex() { } + Vertex(const Vector2f& _pos, const Vector2f& _tex, const unsigned int _col) : pos(_pos), tex(_tex), col(_col) { } + + Vector2f pos; + Vector2f tex; + unsigned int col; + + }; // Vertex + + bool init (); + void deinit (); + void pushClipRect (const Vector2i& _pos, const Vector2i& _size); + void popClipRect (); + void drawRect (const float _x, const float _y, const float _w, const float _h, const unsigned int _color, const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA, const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA); + void drawRect (const int _x, const int _y, const int _w, const int _h, const unsigned int _color, const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA, const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA); + + SDL_Window* getSDLWindow (); + int getWindowWidth (); + int getWindowHeight (); + int getScreenWidth (); + int getScreenHeight (); + int getScreenOffsetX(); + int getScreenOffsetY(); + int getScreenRotate (); + + // API specific + unsigned int convertColor (const unsigned int _color); + unsigned int getWindowFlags (); + void setupWindow (); + void createContext (); + void destroyContext (); + unsigned int createTexture (const Texture::Type _type, const bool _linear, const bool _repeat, const unsigned int _width, const unsigned int _height, void* _data); + void destroyTexture (const unsigned int _texture); + void updateTexture (const unsigned int _texture, const Texture::Type _type, const unsigned int _x, const unsigned _y, const unsigned int _width, const unsigned int _height, void* _data); + void bindTexture (const unsigned int _texture); + void drawLines (const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA, const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA); + void drawTriangleStrips(const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA, const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA); + void setProjection (const Transform4x4f& _projection); + void setMatrix (const Transform4x4f& _matrix); + void setViewport (const Rect& _viewport); + void setScissor (const Rect& _scissor); + void setSwapInterval (); + void swapBuffers (); + +} // Renderer:: + +#endif // ES_CORE_RENDERER_RENDERER_H diff --git a/es-core/src/renderers/Renderer_GL21.cpp b/es-core/src/renderers/Renderer_GL21.cpp new file mode 100644 index 000000000..479940981 --- /dev/null +++ b/es-core/src/renderers/Renderer_GL21.cpp @@ -0,0 +1,251 @@ +#if defined(USE_OPENGL_21) + +#include "renderers/Renderer.h" +#include "Log.h" +#include "Settings.h" + +#include +#include + +namespace Renderer +{ + static SDL_GLContext sdlContext = nullptr; + + static GLenum convertBlendFactor(const Blend::Factor _blendFactor) + { + switch(_blendFactor) + { + case Blend::ZERO: { return GL_ZERO; } break; + case Blend::ONE: { return GL_ONE; } break; + case Blend::SRC_COLOR: { return GL_SRC_COLOR; } break; + case Blend::ONE_MINUS_SRC_COLOR: { return GL_ONE_MINUS_SRC_COLOR; } break; + case Blend::SRC_ALPHA: { return GL_SRC_ALPHA; } break; + case Blend::ONE_MINUS_SRC_ALPHA: { return GL_ONE_MINUS_SRC_ALPHA; } break; + case Blend::DST_COLOR: { return GL_DST_COLOR; } break; + case Blend::ONE_MINUS_DST_COLOR: { return GL_ONE_MINUS_DST_COLOR; } break; + case Blend::DST_ALPHA: { return GL_DST_ALPHA; } break; + case Blend::ONE_MINUS_DST_ALPHA: { return GL_ONE_MINUS_DST_ALPHA; } break; + default: { return GL_ZERO; } + } + + } // convertBlendFactor + + static GLenum convertTextureType(const Texture::Type _type) + { + switch(_type) + { + case Texture::RGBA: { return GL_RGBA; } break; + case Texture::ALPHA: { return GL_ALPHA; } break; + default: { return GL_ZERO; } + } + + } // convertTextureType + + unsigned int convertColor(const unsigned int _color) + { + // convert from rgba to abgr + unsigned char r = ((_color & 0xff000000) >> 24) & 255; + unsigned char g = ((_color & 0x00ff0000) >> 16) & 255; + unsigned char b = ((_color & 0x0000ff00) >> 8) & 255; + unsigned char a = ((_color & 0x000000ff) ) & 255; + + return ((a << 24) | (b << 16) | (g << 8) | (r)); + + } // convertColor + + unsigned int getWindowFlags() + { + return SDL_WINDOW_OPENGL; + + } // getWindowFlags + + void setupWindow() + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + + } // setupWindow + + void createContext() + { + sdlContext = SDL_GL_CreateContext(getSDLWindow()); + SDL_GL_MakeCurrent(getSDLWindow(), sdlContext); + + glClearColor(0.5f, 0.5f, 0.5f, 0.0f); + + std::string glExts = (const char*)glGetString(GL_EXTENSIONS); + LOG(LogInfo) << "Checking available OpenGL extensions..."; + LOG(LogInfo) << " ARB_texture_non_power_of_two: " << (glExts.find("ARB_texture_non_power_of_two") != std::string::npos ? "ok" : "MISSING"); + + } // createContext + + void destroyContext() + { + SDL_GL_DeleteContext(sdlContext); + sdlContext = nullptr; + + } // destroyContext + + unsigned int createTexture(const Texture::Type _type, const bool _linear, const bool _repeat, const unsigned int _width, const unsigned int _height, void* _data) + { + const GLenum type = convertTextureType(_type); + unsigned int texture; + + glGenTextures(1, &texture); + bindTexture(texture); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _linear ? GL_LINEAR : GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _linear ? GL_LINEAR : GL_NEAREST); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexImage2D(GL_TEXTURE_2D, 0, type, _width, _height, 0, type, GL_UNSIGNED_BYTE, _data); + + return texture; + + } // createTexture + + void destroyTexture(const unsigned int _texture) + { + glDeleteTextures(1, &_texture); + + } // destroyTexture + + void updateTexture(const unsigned int _texture, const Texture::Type _type, const unsigned int _x, const unsigned _y, const unsigned int _width, const unsigned int _height, void* _data) + { + bindTexture(_texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, _width, _height, convertTextureType(_type), GL_UNSIGNED_BYTE, _data); + bindTexture(0); + + } // updateTexture + + void bindTexture(const unsigned int _texture) + { + glBindTexture(GL_TEXTURE_2D, _texture); + + if(_texture == 0) glDisable(GL_TEXTURE_2D); + else glEnable(GL_TEXTURE_2D); + + } // bindTexture + + void drawLines(const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + glEnable(GL_BLEND); + glBlendFunc(convertBlendFactor(_srcBlendFactor), convertBlendFactor(_dstBlendFactor)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer( 2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex); + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col); + + glDrawArrays(GL_LINES, 0, _numVertices); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + + } // drawLines + + void drawTriangleStrips(const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + glEnable(GL_BLEND); + glBlendFunc(convertBlendFactor(_srcBlendFactor), convertBlendFactor(_dstBlendFactor)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer( 2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex); + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + + } // drawTriangleStrips + + void setProjection(const Transform4x4f& _projection) + { + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((GLfloat*)&_projection); + + } // setProjection + + void setMatrix(const Transform4x4f& _matrix) + { + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((GLfloat*)&_matrix); + + } // setMatrix + + void setViewport(const Rect& _viewport) + { + // glViewport starts at the bottom left of the window + glViewport( _viewport.x, getWindowHeight() - _viewport.y - _viewport.h, _viewport.w, _viewport.h); + + } // setViewport + + void setScissor(const Rect& _scissor) + { + if((_scissor.x == 0) && (_scissor.y == 0) && (_scissor.w == 0) && (_scissor.h == 0)) + { + glDisable(GL_SCISSOR_TEST); + } + else + { + // glScissor starts at the bottom left of the window + glScissor(_scissor.x, getWindowHeight() - _scissor.y - _scissor.h, _scissor.w, _scissor.h); + glEnable(GL_SCISSOR_TEST); + } + + } // setScissor + + void setSwapInterval() + { + // vsync + if(Settings::getInstance()->getBool("VSync")) + { + // SDL_GL_SetSwapInterval(0) for immediate updates (no vsync, default), + // 1 for updates synchronized with the vertical retrace, + // or -1 for late swap tearing. + // SDL_GL_SetSwapInterval returns 0 on success, -1 on error. + // if vsync is requested, try normal vsync; if that doesn't work, try late swap tearing + // if that doesn't work, report an error + if(SDL_GL_SetSwapInterval(1) != 0 && SDL_GL_SetSwapInterval(-1) != 0) + LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")"; + } + else + SDL_GL_SetSwapInterval(0); + + } // setSwapInterval + + void swapBuffers() + { + SDL_GL_SwapWindow(getSDLWindow()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + } // swapBuffers + +} // Renderer:: + +#endif // USE_OPENGL_21 diff --git a/es-core/src/renderers/Renderer_GLES10.cpp b/es-core/src/renderers/Renderer_GLES10.cpp new file mode 100644 index 000000000..1d402822e --- /dev/null +++ b/es-core/src/renderers/Renderer_GLES10.cpp @@ -0,0 +1,251 @@ +#if defined(USE_OPENGLES_10) + +#include "renderers/Renderer.h" +#include "Log.h" +#include "Settings.h" + +#include +#include + +namespace Renderer +{ + static SDL_GLContext sdlContext = nullptr; + + static GLenum convertBlendFactor(const Blend::Factor _blendFactor) + { + switch(_blendFactor) + { + case Blend::ZERO: { return GL_ZERO; } break; + case Blend::ONE: { return GL_ONE; } break; + case Blend::SRC_COLOR: { return GL_SRC_COLOR; } break; + case Blend::ONE_MINUS_SRC_COLOR: { return GL_ONE_MINUS_SRC_COLOR; } break; + case Blend::SRC_ALPHA: { return GL_SRC_ALPHA; } break; + case Blend::ONE_MINUS_SRC_ALPHA: { return GL_ONE_MINUS_SRC_ALPHA; } break; + case Blend::DST_COLOR: { return GL_DST_COLOR; } break; + case Blend::ONE_MINUS_DST_COLOR: { return GL_ONE_MINUS_DST_COLOR; } break; + case Blend::DST_ALPHA: { return GL_DST_ALPHA; } break; + case Blend::ONE_MINUS_DST_ALPHA: { return GL_ONE_MINUS_DST_ALPHA; } break; + default: { return GL_ZERO; } + } + + } // convertBlendFactor + + static GLenum convertTextureType(const Texture::Type _type) + { + switch(_type) + { + case Texture::RGBA: { return GL_RGBA; } break; + case Texture::ALPHA: { return GL_ALPHA; } break; + default: { return GL_ZERO; } + } + + } // convertTextureType + + unsigned int convertColor(const unsigned int _color) + { + // convert from rgba to abgr + unsigned char r = ((_color & 0xff000000) >> 24) & 255; + unsigned char g = ((_color & 0x00ff0000) >> 16) & 255; + unsigned char b = ((_color & 0x0000ff00) >> 8) & 255; + unsigned char a = ((_color & 0x000000ff) ) & 255; + + return ((a << 24) | (b << 16) | (g << 8) | (r)); + + } // convertColor + + unsigned int getWindowFlags() + { + return SDL_WINDOW_OPENGL; + + } // getWindowFlags + + void setupWindow() + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0); + + } // setupWindow + + void createContext() + { + sdlContext = SDL_GL_CreateContext(getSDLWindow()); + SDL_GL_MakeCurrent(getSDLWindow(), sdlContext); + + glClearColor(0.5f, 0.5f, 0.5f, 0.0f); + + std::string glExts = (const char*)glGetString(GL_EXTENSIONS); + LOG(LogInfo) << "Checking available OpenGL extensions..."; + LOG(LogInfo) << " ARB_texture_non_power_of_two: " << (glExts.find("ARB_texture_non_power_of_two") != std::string::npos ? "ok" : "MISSING"); + + } // createContext + + void destroyContext() + { + SDL_GL_DeleteContext(sdlContext); + sdlContext = nullptr; + + } // destroyContext + + unsigned int createTexture(const Texture::Type _type, const bool _linear, const bool _repeat, const unsigned int _width, const unsigned int _height, void* _data) + { + const GLenum type = convertTextureType(_type); + unsigned int texture; + + glGenTextures(1, &texture); + bindTexture(texture); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _linear ? GL_LINEAR : GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _linear ? GL_LINEAR : GL_NEAREST); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexImage2D(GL_TEXTURE_2D, 0, type, _width, _height, 0, type, GL_UNSIGNED_BYTE, _data); + + return texture; + + } // createTexture + + void destroyTexture(const unsigned int _texture) + { + glDeleteTextures(1, &_texture); + + } // destroyTexture + + void updateTexture(const unsigned int _texture, const Texture::Type _type, const unsigned int _x, const unsigned _y, const unsigned int _width, const unsigned int _height, void* _data) + { + bindTexture(_texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, _width, _height, convertTextureType(_type), GL_UNSIGNED_BYTE, _data); + bindTexture(0); + + } // updateTexture + + void bindTexture(const unsigned int _texture) + { + glBindTexture(GL_TEXTURE_2D, _texture); + + if(_texture == 0) glDisable(GL_TEXTURE_2D); + else glEnable(GL_TEXTURE_2D); + + } // bindTexture + + void drawLines(const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + glEnable(GL_BLEND); + glBlendFunc(convertBlendFactor(_srcBlendFactor), convertBlendFactor(_dstBlendFactor)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer( 2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex); + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col); + + glDrawArrays(GL_LINES, 0, _numVertices); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + + } // drawLines + + void drawTriangleStrips(const Vertex* _vertices, const unsigned int _numVertices, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) + { + glEnable(GL_BLEND); + glBlendFunc(convertBlendFactor(_srcBlendFactor), convertBlendFactor(_dstBlendFactor)); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer( 2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex); + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + + } // drawTriangleStrips + + void setProjection(const Transform4x4f& _projection) + { + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((GLfloat*)&_projection); + + } // setProjection + + void setMatrix(const Transform4x4f& _matrix) + { + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((GLfloat*)&_matrix); + + } // setMatrix + + void setViewport(const Rect& _viewport) + { + // glViewport starts at the bottom left of the window + glViewport( _viewport.x, getWindowHeight() - _viewport.y - _viewport.h, _viewport.w, _viewport.h); + + } // setViewport + + void setScissor(const Rect& _scissor) + { + if((_scissor.x == 0) && (_scissor.y == 0) && (_scissor.w == 0) && (_scissor.h == 0)) + { + glDisable(GL_SCISSOR_TEST); + } + else + { + // glScissor starts at the bottom left of the window + glScissor(_scissor.x, getWindowHeight() - _scissor.y - _scissor.h, _scissor.w, _scissor.h); + glEnable(GL_SCISSOR_TEST); + } + + } // setScissor + + void setSwapInterval() + { + // vsync + if(Settings::getInstance()->getBool("VSync")) + { + // SDL_GL_SetSwapInterval(0) for immediate updates (no vsync, default), + // 1 for updates synchronized with the vertical retrace, + // or -1 for late swap tearing. + // SDL_GL_SetSwapInterval returns 0 on success, -1 on error. + // if vsync is requested, try normal vsync; if that doesn't work, try late swap tearing + // if that doesn't work, report an error + if(SDL_GL_SetSwapInterval(1) != 0 && SDL_GL_SetSwapInterval(-1) != 0) + LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")"; + } + else + SDL_GL_SetSwapInterval(0); + + } // setSwapInterval + + void swapBuffers() + { + SDL_GL_SwapWindow(getSDLWindow()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + } // swapBuffers + +} // Renderer:: + +#endif // USE_OPENGLES_10 diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index f0e93e61c..c84f059bd 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -1,9 +1,13 @@ #include "resources/Font.h" +#include "renderers/Renderer.h" #include "utils/FileSystemUtil.h" #include "utils/StringUtil.h" #include "Log.h" -#include "Renderer.h" + +#ifdef WIN32 +#include +#endif FT_Library Font::sLibrary = NULL; @@ -171,27 +175,14 @@ bool Font::FontTexture::findEmpty(const Vector2i& size, Vector2i& cursor_out) void Font::FontTexture::initTexture() { assert(textureId == 0); - - glGenTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, textureSize.x(), textureSize.y(), 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL); + textureId = Renderer::createTexture(Renderer::Texture::ALPHA, false, false, textureSize.x(), textureSize.y(), nullptr); } void Font::FontTexture::deinitTexture() { if(textureId != 0) { - glDeleteTextures(1, &textureId); + Renderer::destroyTexture(textureId); textureId = 0; } } @@ -355,9 +346,7 @@ Font::Glyph* Font::getGlyph(unsigned int id) glyph.bearing = Vector2f((float)g->metrics.horiBearingX / 64.0f, (float)g->metrics.horiBearingY / 64.0f); // upload glyph bitmap to texture - glBindTexture(GL_TEXTURE_2D, tex->textureId); - glTexSubImage2D(GL_TEXTURE_2D, 0, cursor.x(), cursor.y(), glyphSize.x(), glyphSize.y(), GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer); - glBindTexture(GL_TEXTURE_2D, 0); + Renderer::updateTexture(tex->textureId, Renderer::Texture::ALPHA, cursor.x(), cursor.y(), glyphSize.x(), glyphSize.y(), g->bitmap.buffer); // update max glyph height if(glyphSize.y() > mMaxGlyphHeight) @@ -392,11 +381,8 @@ void Font::rebuildTextures() Vector2i glyphSize((int)(it->second.texSize.x() * tex->textureSize.x()), (int)(it->second.texSize.y() * tex->textureSize.y())); // upload to texture - glBindTexture(GL_TEXTURE_2D, tex->textureId); - glTexSubImage2D(GL_TEXTURE_2D, 0, cursor.x(), cursor.y(), glyphSize.x(), glyphSize.y(), GL_ALPHA, GL_UNSIGNED_BYTE, glyphSlot->bitmap.buffer); + Renderer::updateTexture(tex->textureId, Renderer::Texture::ALPHA, cursor.x(), cursor.y(), glyphSize.x(), glyphSize.y(), glyphSlot->bitmap.buffer); } - - glBindTexture(GL_TEXTURE_2D, 0); } void Font::renderTextCache(TextCache* cache) @@ -413,27 +399,8 @@ void Font::renderTextCache(TextCache* cache) auto vertexList = *it; - glBindTexture(GL_TEXTURE_2D, *it->textureIdPtr); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(TextCache::Vertex), &it->verts[0].pos); - glTexCoordPointer(2, GL_FLOAT, sizeof(TextCache::Vertex), &it->verts[0].tex); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, it->colors.data()); - - glDrawArrays(GL_TRIANGLES, 0, (GLsizei)(it->verts.size())); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); + Renderer::bindTexture(*it->textureIdPtr); + Renderer::drawTriangleStrips(&it->verts[0], it->verts.size()); } } @@ -605,7 +572,7 @@ TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsign float y = offset[1] + (yBot + yTop)/2.0f; // vertices by texture - std::map< FontTexture*, std::vector > vertMap; + std::map< FontTexture*, std::vector > vertMap; size_t cursor = 0; while(cursor < text.length()) @@ -628,37 +595,23 @@ TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsign if(glyph == NULL) continue; - std::vector& verts = vertMap[glyph->texture]; + std::vector& verts = vertMap[glyph->texture]; size_t oldVertSize = verts.size(); verts.resize(oldVertSize + 6); - TextCache::Vertex* tri = verts.data() + oldVertSize; + Renderer::Vertex* vertices = verts.data() + oldVertSize; - const float glyphStartX = x + glyph->bearing.x(); + const float glyphStartX = x + glyph->bearing.x(); + const Vector2i& textureSize = glyph->texture->textureSize; + const unsigned int convertedColor = Renderer::convertColor(color); - const Vector2i& textureSize = glyph->texture->textureSize; + vertices[1] = { { Math::round(glyphStartX ), Math::round(y - glyph->bearing.y() ) }, { glyph->texPos.x(), glyph->texPos.y() }, convertedColor }; + vertices[2] = { { Math::round(glyphStartX ), Math::round(y - glyph->bearing.y() + (glyph->texSize.y() * textureSize.y())) }, { glyph->texPos.x(), glyph->texPos.y() + glyph->texSize.y() }, convertedColor }; + vertices[3] = { { Math::round(glyphStartX + glyph->texSize.x() * textureSize.x()), Math::round(y - glyph->bearing.y() ) }, { glyph->texPos.x() + glyph->texSize.x(), glyph->texPos.y() }, convertedColor }; + vertices[4] = { { Math::round(glyphStartX + glyph->texSize.x() * textureSize.x()), Math::round(y - glyph->bearing.y() + (glyph->texSize.y() * textureSize.y())) }, { glyph->texPos.x() + glyph->texSize.x(), glyph->texPos.y() + glyph->texSize.y() }, convertedColor }; - // triangle 1 - // round to fix some weird "cut off" text bugs - tri[0].pos = Vector2f(Math::round(glyphStartX), Math::round(y + (glyph->texSize.y() * textureSize.y() - glyph->bearing.y()))); - tri[1].pos = Vector2f(Math::round(glyphStartX + glyph->texSize.x() * textureSize.x()), Math::round(y - glyph->bearing.y())); - tri[2].pos = Vector2f(tri[0].pos.x(), tri[1].pos.y()); - - //tri[0].tex = Vector2f(0, 0); - //tri[0].tex = Vector2f(1, 1); - //tri[0].tex = Vector2f(0, 1); - - tri[0].tex = Vector2f(glyph->texPos.x(), glyph->texPos.y() + glyph->texSize.y()); - tri[1].tex = Vector2f(glyph->texPos.x() + glyph->texSize.x(), glyph->texPos.y()); - tri[2].tex = Vector2f(tri[0].tex.x(), tri[1].tex.y()); - - // triangle 2 - tri[3].pos = tri[0].pos; - tri[4].pos = tri[1].pos; - tri[5].pos = Vector2f(tri[1].pos.x(), tri[0].pos.y()); - - tri[3].tex = tri[0].tex; - tri[4].tex = tri[1].tex; - tri[5].tex = Vector2f(tri[1].tex.x(), tri[0].tex.y()); + // make duplicates of first and last vertex so this can be rendered as a triangle strip + vertices[0] = vertices[1]; + vertices[5] = vertices[4]; // advance x += glyph->advance.x(); @@ -677,9 +630,6 @@ TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsign vertList.textureIdPtr = &it->first->textureId; vertList.verts = it->second; - - vertList.colors.resize(4 * it->second.size()); - Renderer::buildGLColorArray(vertList.colors.data(), color, (unsigned int)(it->second.size())); } clearFaceCache(); @@ -694,8 +644,11 @@ TextCache* Font::buildTextCache(const std::string& text, float offsetX, float of void TextCache::setColor(unsigned int color) { - for(auto it = vertexLists.cbegin(); it != vertexLists.cend(); it++) - Renderer::buildGLColorArray((GLubyte*)(it->colors.data()), color, (unsigned int)(it->verts.size())); + const unsigned int convertedColor = Renderer::convertColor(color); + + for(auto it = vertexLists.begin(); it != vertexLists.end(); it++) + for(auto it2 = it->verts.begin(); it2 != it->verts.end(); it2++) + it2->col = convertedColor; } std::shared_ptr Font::getFromTheme(const ThemeData::ThemeElement* elem, unsigned int properties, const std::shared_ptr& orig) diff --git a/es-core/src/resources/Font.h b/es-core/src/resources/Font.h index 585c89246..72a201f9c 100644 --- a/es-core/src/resources/Font.h +++ b/es-core/src/resources/Font.h @@ -4,8 +4,8 @@ #include "math/Vector2f.h" #include "math/Vector2i.h" +#include "renderers/Renderer.h" #include "resources/ResourceManager.h" -#include "Renderer.h" #include "ThemeData.h" #include #include FT_FREETYPE_H @@ -74,7 +74,7 @@ private: struct FontTexture { - GLuint textureId; + unsigned int textureId; Vector2i textureSize; Vector2i writePos; @@ -141,17 +141,11 @@ private: class TextCache { protected: - struct Vertex - { - Vector2f pos; - Vector2f tex; - }; struct VertexList { - GLuint* textureIdPtr; // this is a pointer because the texture ID can change during deinit/reinit (when launching a game) - std::vector verts; - std::vector colors; + std::vector verts; + unsigned int* textureIdPtr; // this is a pointer because the texture ID can change during deinit/reinit (when launching a game) }; std::vector vertexLists; diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp index f493a91c4..11cc75637 100644 --- a/es-core/src/resources/TextureData.cpp +++ b/es-core/src/resources/TextureData.cpp @@ -1,11 +1,10 @@ #include "resources/TextureData.h" #include "math/Misc.h" +#include "renderers/Renderer.h" #include "resources/ResourceManager.h" #include "ImageIO.h" #include "Log.h" -#include "platform.h" -#include GLHEADER #include #include #include @@ -162,7 +161,7 @@ bool TextureData::uploadAndBind() std::unique_lock lock(mMutex); if (mTextureID != 0) { - glBindTexture(GL_TEXTURE_2D, mTextureID); + Renderer::bindTexture(mTextureID); } else { @@ -174,19 +173,9 @@ bool TextureData::uploadAndBind() // Make sure we're ready to upload if ((mWidth == 0) || (mHeight == 0) || (mDataRGBA == nullptr)) return false; - glGetError(); - //now for the openGL texture stuff - glGenTextures(1, &mTextureID); - glBindTexture(GL_TEXTURE_2D, mTextureID); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)mWidth, (GLsizei)mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mDataRGBA); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + // Upload texture + mTextureID = Renderer::createTexture(Renderer::Texture::RGBA, true, mTile, mWidth, mHeight, mDataRGBA); } return true; } @@ -196,7 +185,7 @@ void TextureData::releaseVRAM() std::unique_lock lock(mMutex); if (mTextureID != 0) { - glDeleteTextures(1, &mTextureID); + Renderer::destroyTexture(mTextureID); mTextureID = 0; } } diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h index 3ac6f239e..44dc92623 100644 --- a/es-core/src/resources/TextureData.h +++ b/es-core/src/resources/TextureData.h @@ -2,8 +2,6 @@ #ifndef ES_CORE_RESOURCES_TEXTURE_DATA_H #define ES_CORE_RESOURCES_TEXTURE_DATA_H -#include "platform.h" -#include GLHEADER #include #include @@ -53,7 +51,7 @@ private: std::mutex mMutex; bool mTile; std::string mPath; - GLuint mTextureID; + unsigned int mTextureID; unsigned char* mDataRGBA; size_t mWidth; size_t mHeight;