Merge pull request #584 from tomaz82/cleanup_renderer

Cleanup renderer
This commit is contained in:
John Rassa 2019-08-25 09:54:35 -04:00 committed by GitHub
commit f0c64073db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 1094 additions and 884 deletions

View file

@ -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()
#-------------------------------------------------------------------------------

View file

@ -11,7 +11,6 @@
#include "FileFilterIndex.h"
#include "Log.h"
#include "PowerSaver.h"
#include "Renderer.h"
#include "Sound.h"
#include "SystemData.h"
#include <unordered_map>

View file

@ -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<HttpReq> req, std::function<void(std::shared_ptr<HttpReq>)> onSuccess, std::function<void()> onCancel)
: GuiComponent(window),

View file

@ -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);
}

View file

@ -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;

View file

@ -3,7 +3,6 @@
#include "components/ComponentGrid.h"
#include "components/NinePatchComponent.h"
#include "components/TextComponent.h"
#include "Renderer.h"
#include <SDL_timer.h>
GuiInfoPopup::GuiInfoPopup(Window* window, std::string message, int duration) :

View file

@ -18,6 +18,7 @@
#include "VolumeControl.h"
#include <SDL_events.h>
#include <algorithm>
#include "platform.h"
GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MENU"), mVersion(window)
{

View file

@ -323,9 +323,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...";

View file

@ -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"

View file

@ -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 <vector>
class IGameListView;

View file

@ -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;

View file

@ -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

View file

@ -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 <algorithm>

View file

@ -1,7 +1,6 @@
#include "HelpStyle.h"
#include "resources/Font.h"
#include "Renderer.h"
HelpStyle::HelpStyle()
{

View file

@ -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

View file

@ -1,154 +0,0 @@
#include "Renderer.h"
#include "math/Misc.h"
#include "Log.h"
#include <stack>
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<ClipRect> 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);
}
};

View file

@ -1,222 +0,0 @@
#include "Renderer.h"
#include "resources/ResourceManager.h"
#include "ImageIO.h"
#include "Log.h"
#include "Settings.h"
#include <SDL.h>
#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<unsigned char> 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);
}
};

View file

@ -6,7 +6,6 @@
#include "resources/TextureResource.h"
#include "InputManager.h"
#include "Log.h"
#include "Renderer.h"
#include "Scripting.h"
#include <algorithm>
#include <iomanip>

View file

@ -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[] = {

View file

@ -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<void()>& func) : GuiComponent(window),
mBox(window, ":/button.png"),

View file

@ -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());
}
}

View file

@ -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<Vert> mLines;
std::vector<unsigned int> mLineColors;
std::vector<Renderer::Vertex> mLines;
// Update position & size
void updateCellComponent(const GridEntry& cell);

View file

@ -1,7 +1,5 @@
#include "components/ComponentList.h"
#include "Renderer.h"
#define TOTAL_HORIZONTAL_PADDING_PX 20
ComponentList::ComponentList(Window* window) : IList<ComponentListRow, void*>(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);

View file

@ -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)

View file

@ -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),

View file

@ -2,7 +2,6 @@
#include "resources/TextureResource.h"
#include "ThemeData.h"
#include "Renderer.h"
GridTileComponent::GridTileComponent(Window* window) : GuiComponent(window), mBackground(window)
{

View file

@ -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();

View file

@ -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();

View file

@ -7,7 +7,6 @@
#include "components/NinePatchComponent.h"
#include "components/TextComponent.h"
#include "utils/StringUtil.h"
#include "Renderer.h"
class ButtonComponent;
class ImageComponent;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -2,7 +2,6 @@
#include "utils/StringUtil.h"
#include "Log.h"
#include "Renderer.h"
#include "Settings.h"
TextComponent::TextComponent(Window* window) : GuiComponent(window),

View file

@ -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

View file

@ -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 <SDL_timer.h>

View file

@ -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 <fcntl.h>
#include <unistd.h>
@ -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);

View file

@ -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 <vlc/vlc.h>
#include <SDL_mutex.h>
@ -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);
}
}

View file

@ -6,7 +6,6 @@
#include "utils/StringUtil.h"
#include "InputManager.h"
#include "PowerSaver.h"
#include "Renderer.h"
#include "Window.h"
#define HOLD_TIME 1000

View file

@ -49,6 +49,45 @@ const Vector3f Transform4x4f::operator*(const Vector3f& _other) const
} // operator*
Transform4x4f& Transform4x4f::orthoProjection(float _left, float _right, float _bottom, float _top, float _near, float _far)
{
float* tm = (float*)this;
const float o[6] = { 2 / (_right - _left),
2 / (_top - _bottom),
-2 / (_far - _near),
-(_right + _left) / (_right - _left),
-(_top + _bottom) / (_top - _bottom),
-(_far + _near) / (_far - _near) };
const float temp[12] = { tm[ 0] * o[0],
tm[ 1] * o[0],
tm[ 2] * o[0],
tm[ 4] * o[1],
tm[ 5] * o[1],
tm[ 6] * o[1],
tm[ 8] * o[2],
tm[ 9] * o[2],
tm[10] * o[2],
tm[ 0] * o[3] + tm[ 4] * o[4] + tm[ 8] * o[5] + tm[12],
tm[ 1] * o[3] + tm[ 5] * o[4] + tm[ 9] * o[5] + tm[13],
tm[ 2] * o[3] + tm[ 6] * o[4] + tm[10] * o[5] + tm[14] };
tm[ 0] = temp[ 0];
tm[ 1] = temp[ 1];
tm[ 2] = temp[ 2];
tm[ 4] = temp[ 3];
tm[ 5] = temp[ 4];
tm[ 6] = temp[ 5];
tm[ 8] = temp[ 6];
tm[ 9] = temp[ 7];
tm[10] = temp[ 8];
tm[12] = temp[ 9];
tm[13] = temp[10];
tm[14] = temp[11];
return *this;
} // orthoProjection
Transform4x4f& Transform4x4f::invert(const Transform4x4f& _other)
{
float* tm = (float*)this;

View file

@ -25,14 +25,15 @@ public:
inline const Vector4f& r2() const { return mR2; }
inline const Vector4f& r3() const { return mR3; }
Transform4x4f& invert (const Transform4x4f& _other);
Transform4x4f& scale (const Vector3f& _scale);
Transform4x4f& rotate (const float _angle, const Vector3f& _axis);
Transform4x4f& rotateX (const float _angle);
Transform4x4f& rotateY (const float _angle);
Transform4x4f& rotateZ (const float _angle);
Transform4x4f& translate(const Vector3f& _translation);
Transform4x4f& round ();
Transform4x4f& orthoProjection(float _left, float _right, float _bottom, float _top, float _near, float _far);
Transform4x4f& invert (const Transform4x4f& _other);
Transform4x4f& scale (const Vector3f& _scale);
Transform4x4f& rotate (const float _angle, const Vector3f& _axis);
Transform4x4f& rotateX (const float _angle);
Transform4x4f& rotateY (const float _angle);
Transform4x4f& rotateZ (const float _angle);
Transform4x4f& translate (const Vector3f& _translation);
Transform4x4f& round ();
inline Vector3f& translation() { return mR3.v3(); }
inline const Vector3f& translation() const { return mR3.v3(); }

View file

@ -4,21 +4,9 @@
#include <string>
//the Makefile defines one of these:
//#define USE_OPENGL_ES
//#define USE_OPENGL_DESKTOP
#ifdef USE_OPENGL_ES
#define GLHEADER <GLES/gl.h>
#endif
#ifdef USE_OPENGL_DESKTOP
//why the hell this naming inconsistency exists is well beyond me
#ifdef WIN32
#define sleep Sleep
#endif
#define GLHEADER <SDL_opengl.h>
//why the hell this naming inconsistency exists is well beyond me
#ifdef WIN32
#define sleep Sleep
#endif
enum QuitMode

View file

@ -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 <SDL.h>
#include <stack>
namespace Renderer
{
static std::stack<Rect> 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<unsigned char> 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::

View file

@ -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

View file

@ -0,0 +1,251 @@
#if defined(USE_OPENGL_21)
#include "renderers/Renderer.h"
#include "Log.h"
#include "Settings.h"
#include <SDL_opengl.h>
#include <SDL.h>
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

View file

@ -0,0 +1,251 @@
#if defined(USE_OPENGLES_10)
#include "renderers/Renderer.h"
#include "Log.h"
#include "Settings.h"
#include <GLES/gl.h>
#include <SDL.h>
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

View file

@ -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 <Windows.h>
#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<TextCache::Vertex> > vertMap;
std::map< FontTexture*, std::vector<Renderer::Vertex> > 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<TextCache::Vertex>& verts = vertMap[glyph->texture];
std::vector<Renderer::Vertex>& 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> Font::getFromTheme(const ThemeData::ThemeElement* elem, unsigned int properties, const std::shared_ptr<Font>& orig)

View file

@ -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 <ft2build.h>
#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<Vertex> verts;
std::vector<GLubyte> colors;
std::vector<Renderer::Vertex> verts;
unsigned int* textureIdPtr; // this is a pointer because the texture ID can change during deinit/reinit (when launching a game)
};
std::vector<VertexList> vertexLists;

View file

@ -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 <nanosvg/nanosvg.h>
#include <nanosvg/nanosvgrast.h>
#include <assert.h>
@ -162,7 +161,7 @@ bool TextureData::uploadAndBind()
std::unique_lock<std::mutex> 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<std::mutex> lock(mMutex);
if (mTextureID != 0)
{
glDeleteTextures(1, &mTextureID);
Renderer::destroyTexture(mTextureID);
mTextureID = 0;
}
}

View file

@ -2,8 +2,6 @@
#ifndef ES_CORE_RESOURCES_TEXTURE_DATA_H
#define ES_CORE_RESOURCES_TEXTURE_DATA_H
#include "platform.h"
#include GLHEADER
#include <mutex>
#include <string>
@ -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;