mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 15:15:37 +00:00
Refactored the rendering code into proper classes.
This commit is contained in:
parent
4f21d94aa5
commit
f0c35d8509
|
@ -1163,7 +1163,7 @@ void FileData::launchGame()
|
|||
// flickering and to avoid showing the game launch message briefly when returning
|
||||
// from the game.
|
||||
if (!runInBackground)
|
||||
Renderer::swapBuffers();
|
||||
Renderer::getInstance()->swapBuffers();
|
||||
|
||||
Scripting::fireEvent("game-start", romPath, getSourceFileData()->metadata.get("name"),
|
||||
getSourceFileData()->getSystem()->getName(),
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
#include "views/ViewController.h"
|
||||
|
||||
MediaViewer::MediaViewer()
|
||||
: mVideo {nullptr}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mVideo {nullptr}
|
||||
, mImage {nullptr}
|
||||
{
|
||||
Window::getInstance()->setMediaViewer(this);
|
||||
|
@ -77,11 +78,11 @@ void MediaViewer::update(int deltaTime)
|
|||
void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
||||
{
|
||||
glm::mat4 trans {Renderer::getIdentity()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
// Render a black background below the game media.
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
|
||||
if (mVideo && !mDisplayingImage) {
|
||||
mVideo->render(trans);
|
||||
|
@ -112,17 +113,17 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
|||
}
|
||||
|
||||
if (shaders != 0)
|
||||
Renderer::shaderPostprocessing(shaders, videoParameters);
|
||||
mRenderer->shaderPostprocessing(shaders, videoParameters);
|
||||
}
|
||||
else if (mImage && mImage->hasImage() && mImage->getSize() != glm::vec2 {}) {
|
||||
mImage->render(trans);
|
||||
|
||||
if (mCurrentImageIndex == mScreenshotIndex &&
|
||||
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
else if (mCurrentImageIndex == mTitleScreenIndex &&
|
||||
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
|
||||
// This is necessary so that the video loops if viewing an image when
|
||||
// the video ends.
|
||||
|
|
|
@ -36,6 +36,7 @@ private:
|
|||
void showNext() override;
|
||||
void showPrevious() override;
|
||||
|
||||
Renderer* mRenderer;
|
||||
FileData* mGame;
|
||||
|
||||
bool mHasVideo;
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#define FADE_TIME 300.0f
|
||||
|
||||
Screensaver::Screensaver()
|
||||
: mWindow {Window::getInstance()}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mWindow {Window::getInstance()}
|
||||
, mState {STATE_INACTIVE}
|
||||
, mImageScreensaver {nullptr}
|
||||
, mVideoScreensaver {nullptr}
|
||||
|
@ -238,12 +239,12 @@ void Screensaver::renderScreensaver()
|
|||
{
|
||||
std::string screensaverType = Settings::getInstance()->getString("ScreensaverType");
|
||||
glm::mat4 trans {Renderer::getIdentity()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (mVideoScreensaver && screensaverType == "video") {
|
||||
// Render a black background below the video.
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
|
||||
// Only render the video if the state requires it.
|
||||
if (static_cast<int>(mState) >= STATE_FADE_IN_VIDEO)
|
||||
|
@ -251,8 +252,8 @@ void Screensaver::renderScreensaver()
|
|||
}
|
||||
else if (mImageScreensaver && screensaverType == "slideshow") {
|
||||
// Render a black background below the image.
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
|
||||
// Only render the image if the state requires it.
|
||||
if (static_cast<int>(mState) >= STATE_FADE_IN_VIDEO) {
|
||||
|
@ -268,11 +269,11 @@ void Screensaver::renderScreensaver()
|
|||
if (Settings::getInstance()->getString("ScreensaverType") == "slideshow") {
|
||||
if (mHasMediaFiles) {
|
||||
if (Settings::getInstance()->getBool("ScreensaverSlideshowScanlines"))
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_SCANLINES);
|
||||
if (Settings::getInstance()->getBool("ScreensaverSlideshowGameInfo") &&
|
||||
mGameOverlay) {
|
||||
if (mGameOverlayRectangleCoords.size() == 4) {
|
||||
Renderer::drawRect(
|
||||
mRenderer->drawRect(
|
||||
mGameOverlayRectangleCoords[0], mGameOverlayRectangleCoords[1],
|
||||
mGameOverlayRectangleCoords[2], mGameOverlayRectangleCoords[3],
|
||||
0x00000000 | mRectangleFadeIn, 0x00000000 | mRectangleFadeIn);
|
||||
|
@ -319,11 +320,11 @@ void Screensaver::renderScreensaver()
|
|||
}
|
||||
|
||||
if (shaders != 0)
|
||||
Renderer::shaderPostprocessing(shaders, videoParameters);
|
||||
mRenderer->shaderPostprocessing(shaders, videoParameters);
|
||||
|
||||
if (Settings::getInstance()->getBool("ScreensaverVideoGameInfo") && mGameOverlay) {
|
||||
if (mGameOverlayRectangleCoords.size() == 4) {
|
||||
Renderer::drawRect(
|
||||
mRenderer->drawRect(
|
||||
mGameOverlayRectangleCoords[0], mGameOverlayRectangleCoords[1],
|
||||
mGameOverlayRectangleCoords[2], mGameOverlayRectangleCoords[3],
|
||||
0x00000000 | mRectangleFadeIn, 0x00000000 | mRectangleFadeIn);
|
||||
|
@ -347,7 +348,7 @@ void Screensaver::renderScreensaver()
|
|||
Renderer::postProcessingParams dimParameters;
|
||||
dimParameters.dimming = mDimValue;
|
||||
dimParameters.saturation = mSaturationAmount;
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_CORE, dimParameters);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_CORE, dimParameters);
|
||||
if (mDimValue > 0.63)
|
||||
mDimValue = glm::clamp(mDimValue - 0.015f, 0.68f, 1.0f);
|
||||
if (mSaturationAmount > 0.0)
|
||||
|
@ -356,7 +357,7 @@ void Screensaver::renderScreensaver()
|
|||
else if (Settings::getInstance()->getString("ScreensaverType") == "black") {
|
||||
Renderer::postProcessingParams blackParameters;
|
||||
blackParameters.dimming = mDimValue;
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_CORE, blackParameters);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_CORE, blackParameters);
|
||||
if (mDimValue > 0.0)
|
||||
mDimValue = glm::clamp(mDimValue - 0.045f, 0.0f, 1.0f);
|
||||
}
|
||||
|
@ -567,8 +568,8 @@ void Screensaver::generateOverlayInfo()
|
|||
if (mGameName == "" || mSystemName == "")
|
||||
return;
|
||||
|
||||
float posX {Renderer::getWindowWidth() * 0.023f};
|
||||
float posY {Renderer::getWindowHeight() * 0.02f};
|
||||
float posX {mRenderer->getWindowWidth() * 0.023f};
|
||||
float posY {mRenderer->getWindowHeight() * 0.02f};
|
||||
|
||||
std::string favoriteChar;
|
||||
if (mCurrentGame && mCurrentGame->getFavorite())
|
||||
|
@ -595,7 +596,7 @@ void Screensaver::generateOverlayInfo()
|
|||
else
|
||||
textSizeX = mGameOverlayFont[0].get()->sizeText(systemName).x;
|
||||
|
||||
float marginX {Renderer::getWindowWidth() * 0.01f};
|
||||
float marginX {mRenderer->getWindowWidth() * 0.01f};
|
||||
|
||||
mGameOverlayRectangleCoords.clear();
|
||||
mGameOverlayRectangleCoords.push_back(posX - marginX);
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
STATE_SCREENSAVER_ACTIVE
|
||||
};
|
||||
|
||||
Renderer* mRenderer;
|
||||
Window* mWindow;
|
||||
STATE mState;
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "scrapers/Scraper.h"
|
||||
#include "views/ViewController.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
GuiGamelistOptions::GuiGamelistOptions(SystemData* system)
|
||||
: mMenu {"OPTIONS"}
|
||||
, mSystem {system}
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#include "utils/StringUtil.h"
|
||||
|
||||
GuiLaunchScreen::GuiLaunchScreen()
|
||||
: mBackground {":/graphics/frame.svg"}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mBackground {":/graphics/frame.svg"}
|
||||
, mGrid {nullptr}
|
||||
, mMarquee {nullptr}
|
||||
{
|
||||
|
@ -224,7 +225,7 @@ void GuiLaunchScreen::render(const glm::mat4& /*parentTrans*/)
|
|||
setScale(mScaleUp);
|
||||
|
||||
glm::mat4 trans {Renderer::getIdentity() * getTransform()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
GuiComponent::renderChildren(trans);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
void render(const glm::mat4& parentTrans) override;
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
NinePatchComponent mBackground;
|
||||
ComponentGrid* mGrid;
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
#define FAILED_VERIFICATION_RETRIES 8
|
||||
|
||||
GuiScraperSearch::GuiScraperSearch(SearchType type, unsigned int scrapeCount)
|
||||
: mGrid {glm::ivec2 {5, 3}}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mGrid {glm::ivec2 {5, 3}}
|
||||
, mSearchType {type}
|
||||
, mScrapeCount {scrapeCount}
|
||||
, mRefinedSearch {false}
|
||||
|
@ -630,10 +631,10 @@ void GuiScraperSearch::render(const glm::mat4& parentTrans)
|
|||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
|
||||
renderChildren(trans);
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x00000009, 0x00000009);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x00000009, 0x00000009);
|
||||
|
||||
if (mBlockAccept) {
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
mBusyAnim.render(trans);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ private:
|
|||
// Resolve any metadata assets that need to be downloaded and return.
|
||||
void returnResult(ScraperSearchResult result);
|
||||
|
||||
Renderer* mRenderer;
|
||||
ComponentGrid mGrid;
|
||||
|
||||
std::shared_ptr<TextComponent> mResultName;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "views/GamelistView.h"
|
||||
#include "views/ViewController.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
GuiSettings::GuiSettings(std::string title)
|
||||
: mMenu {title}
|
||||
, mGoToSystem {nullptr}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
namespace
|
||||
{
|
||||
SDL_Event event {};
|
||||
Renderer* renderer {nullptr};
|
||||
Window* window {nullptr};
|
||||
int lastTime {0};
|
||||
|
||||
|
@ -474,7 +475,7 @@ void applicationLoop()
|
|||
window->update(deltaTime);
|
||||
window->render();
|
||||
|
||||
Renderer::swapBuffers();
|
||||
renderer->swapBuffers();
|
||||
Log::flush();
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
}
|
||||
|
@ -601,6 +602,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
renderer = Renderer::getInstance();
|
||||
window = Window::getInstance();
|
||||
ViewController::getInstance();
|
||||
CollectionSystemsManager::getInstance();
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
GamelistView::GamelistView(FileData* root)
|
||||
: GamelistBase {root}
|
||||
, mLegacyMode {false}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mViewStyle {ViewController::BASIC}
|
||||
, mLegacyMode {false}
|
||||
{
|
||||
mViewStyle = ViewController::getInstance()->getState().viewstyle;
|
||||
|
||||
|
@ -247,9 +248,9 @@ void GamelistView::render(const glm::mat4& parentTrans)
|
|||
glm::ivec2 size {static_cast<int>(std::round(mSize.x * scaleX)),
|
||||
static_cast<int>(std::round(mSize.y * scaleY))};
|
||||
|
||||
Renderer::pushClipRect(pos, size);
|
||||
mRenderer->pushClipRect(pos, size);
|
||||
renderChildren(trans);
|
||||
Renderer::popClipRect();
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
|
||||
HelpStyle GamelistView::getHelpStyle()
|
||||
|
|
|
@ -102,8 +102,9 @@ private:
|
|||
void legacyInitMDLabels();
|
||||
void legacyInitMDValues();
|
||||
|
||||
bool mLegacyMode;
|
||||
Renderer* mRenderer;
|
||||
ViewController::GamelistViewStyle mViewStyle;
|
||||
bool mLegacyMode;
|
||||
|
||||
std::shared_ptr<ThemeData> mTheme;
|
||||
std::vector<GuiComponent*> mThemeExtras;
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
#endif
|
||||
|
||||
SystemView::SystemView()
|
||||
: mCamOffset {0.0f}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mCamOffset {0.0f}
|
||||
, mFadeOpacity {0.0f}
|
||||
, mPreviousScrollVelocity {0}
|
||||
, mUpdatedGameCount {false}
|
||||
|
@ -1048,7 +1049,7 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
|||
elementTrans = glm::translate(elementTrans,
|
||||
glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f});
|
||||
|
||||
Renderer::pushClipRect(
|
||||
mRenderer->pushClipRect(
|
||||
glm::ivec2 {static_cast<int>(glm::round(elementTrans[3].x)),
|
||||
static_cast<int>(glm::round(elementTrans[3].y))},
|
||||
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
|
||||
|
@ -1081,7 +1082,7 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
|||
mLegacySystemInfo->render(elementTrans);
|
||||
}
|
||||
|
||||
Renderer::popClipRect();
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ private:
|
|||
void legacyApplyTheme(const std::shared_ptr<ThemeData>& theme);
|
||||
void renderElements(const glm::mat4& parentTrans, bool abovePrimary);
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::unique_ptr<CarouselComponent> mCarousel;
|
||||
std::unique_ptr<TextComponent> mLegacySystemInfo;
|
||||
std::vector<SystemViewElements> mSystemElements;
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#include "views/SystemView.h"
|
||||
|
||||
ViewController::ViewController() noexcept
|
||||
: mNoGamesMessageBox {nullptr}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mNoGamesMessageBox {nullptr}
|
||||
, mCurrentView {nullptr}
|
||||
, mPreviousView {nullptr}
|
||||
, mSkipView {nullptr}
|
||||
|
@ -201,7 +202,7 @@ void ViewController::invalidAlternativeEmulatorDialog()
|
|||
void ViewController::goToStart(bool playTransition)
|
||||
{
|
||||
// Needed to avoid segfaults during emergency shutdown.
|
||||
if (Renderer::getSDLWindow() == nullptr)
|
||||
if (mRenderer->getSDLWindow() == nullptr)
|
||||
return;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
@ -287,7 +288,7 @@ void ViewController::cancelViewTransitions()
|
|||
|
||||
void ViewController::stopScrolling()
|
||||
{
|
||||
if (Renderer::getSDLWindow() == nullptr)
|
||||
if (mRenderer->getSDLWindow() == nullptr)
|
||||
return;
|
||||
|
||||
mSystemListView->stopScrolling();
|
||||
|
@ -905,9 +906,9 @@ void ViewController::render(const glm::mat4& parentTrans)
|
|||
// Fade out.
|
||||
if (mFadeOpacity) {
|
||||
unsigned int fadeColor = 0x00000000 | static_cast<unsigned char>(mFadeOpacity * 255);
|
||||
Renderer::setMatrix(parentTrans);
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
fadeColor, fadeColor);
|
||||
mRenderer->setMatrix(parentTrans);
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
fadeColor, fadeColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -999,7 +1000,7 @@ void ViewController::reloadGamelistView(GamelistView* view, bool reloadTheme)
|
|||
|
||||
void ViewController::reloadAll()
|
||||
{
|
||||
if (Renderer::getSDLWindow() == nullptr)
|
||||
if (mRenderer->getSDLWindow() == nullptr)
|
||||
return;
|
||||
|
||||
cancelViewTransitions();
|
||||
|
|
|
@ -151,6 +151,7 @@ private:
|
|||
|
||||
void launch(FileData* game);
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::string mNoGamesErrorMessage;
|
||||
std::string mRomDirectory;
|
||||
GuiMsgBox* mNoGamesMessageBox;
|
||||
|
|
|
@ -74,6 +74,7 @@ set(CORE_HEADERS
|
|||
|
||||
# Renderers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GL21.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Shader_GL21.h
|
||||
|
||||
# Resources
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
#define CLOCK_BACKGROUND_CREATION false
|
||||
|
||||
Window::Window() noexcept
|
||||
: mScreensaver {nullptr}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mScreensaver {nullptr}
|
||||
, mMediaViewer {nullptr}
|
||||
, mLaunchScreen {nullptr}
|
||||
, mInfoPopup {nullptr}
|
||||
|
@ -102,7 +103,7 @@ GuiComponent* Window::peekGui()
|
|||
|
||||
bool Window::init()
|
||||
{
|
||||
if (!Renderer::init()) {
|
||||
if (!mRenderer->init()) {
|
||||
LOG(LogError) << "Renderer failed to initialize.";
|
||||
return false;
|
||||
}
|
||||
|
@ -146,7 +147,7 @@ void Window::deinit()
|
|||
|
||||
InputManager::getInstance().deinit();
|
||||
ResourceManager::getInstance().unloadAll();
|
||||
Renderer::deinit();
|
||||
mRenderer->deinit();
|
||||
}
|
||||
|
||||
void Window::input(InputConfig* config, Input input)
|
||||
|
@ -476,16 +477,16 @@ void Window::render()
|
|||
// Also dim the background slightly.
|
||||
backgroundParameters.dimming = 0.60f;
|
||||
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_CORE |
|
||||
Renderer::SHADER_BLUR_HORIZONTAL |
|
||||
Renderer::SHADER_BLUR_VERTICAL,
|
||||
backgroundParameters, &processedTexture[0]);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_CORE |
|
||||
Renderer::SHADER_BLUR_HORIZONTAL |
|
||||
Renderer::SHADER_BLUR_VERTICAL,
|
||||
backgroundParameters, &processedTexture[0]);
|
||||
}
|
||||
else {
|
||||
// Dim the background slightly.
|
||||
backgroundParameters.dimming = 0.60f;
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_CORE, backgroundParameters,
|
||||
&processedTexture[0]);
|
||||
mRenderer->shaderPostprocessing(Renderer::SHADER_CORE, backgroundParameters,
|
||||
&processedTexture[0]);
|
||||
}
|
||||
|
||||
mPostprocessedBackground->initFromPixels(
|
||||
|
@ -546,10 +547,10 @@ void Window::render()
|
|||
|
||||
// Render the quick list scrolling overlay, which is triggered in IList.
|
||||
if (mListScrollOpacity != 0.0f) {
|
||||
Renderer::setMatrix(Renderer::getIdentity());
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x00000000 | static_cast<unsigned char>(mListScrollOpacity * 255.0f),
|
||||
0x00000000 | static_cast<unsigned char>(mListScrollOpacity * 255.0f));
|
||||
mRenderer->setMatrix(Renderer::getIdentity());
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x00000000 | static_cast<unsigned char>(mListScrollOpacity * 255.0f),
|
||||
0x00000000 | static_cast<unsigned char>(mListScrollOpacity * 255.0f));
|
||||
|
||||
glm::vec2 offset {mListScrollFont->sizeText(mListScrollText)};
|
||||
offset.x = (Renderer::getScreenWidth() - offset.x) * 0.5f;
|
||||
|
@ -604,7 +605,7 @@ void Window::render()
|
|||
mLaunchScreen->render(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DisplayGPUStatistics") && mFrameDataText) {
|
||||
Renderer::setMatrix(Renderer::getIdentity());
|
||||
mRenderer->setMatrix(Renderer::getIdentity());
|
||||
mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get());
|
||||
}
|
||||
}
|
||||
|
@ -612,9 +613,9 @@ void Window::render()
|
|||
void Window::renderLoadingScreen(std::string text)
|
||||
{
|
||||
glm::mat4 trans {Renderer::getIdentity()};
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||
0x000000FF, 0x000000FF);
|
||||
|
||||
ImageComponent splash(true);
|
||||
splash.setImage(":/graphics/splash.svg");
|
||||
|
@ -629,11 +630,11 @@ void Window::renderLoadingScreen(std::string text)
|
|||
float x {std::round((Renderer::getScreenWidth() - cache->metrics.size.x) / 2.0f)};
|
||||
float y {std::round(Renderer::getScreenHeight() * 0.835f)};
|
||||
trans = glm::translate(trans, glm::vec3 {x, y, 0.0f});
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
font->renderTextCache(cache);
|
||||
delete cache;
|
||||
|
||||
Renderer::swapBuffers();
|
||||
mRenderer->swapBuffers();
|
||||
}
|
||||
|
||||
void Window::renderListScrollOverlay(const float opacity, const std::string& text)
|
||||
|
|
|
@ -159,6 +159,7 @@ private:
|
|||
// Returns true if at least one component on the stack is processing.
|
||||
bool isProcessing();
|
||||
|
||||
Renderer* mRenderer;
|
||||
HelpComponent* mHelp;
|
||||
ImageComponent* mBackgroundOverlay;
|
||||
float mBackgroundOverlayOpacity;
|
||||
|
|
|
@ -17,7 +17,8 @@ ButtonComponent::ButtonComponent(const std::string& text,
|
|||
const std::function<void()>& func,
|
||||
bool upperCase,
|
||||
bool flatStyle)
|
||||
: mBox {":/graphics/button.svg"}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mBox {":/graphics/button.svg"}
|
||||
, mFont {Font::get(FONT_SIZE_MEDIUM)}
|
||||
, mPadding {0.0f, 0.0f, 0.0f, 0.0f}
|
||||
, mFocused {false}
|
||||
|
@ -112,16 +113,16 @@ void ButtonComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
if (mFlatStyle) {
|
||||
if (mFocused) {
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||
mSize.y - mPadding.y - mPadding.w, mFlatColorFocused,
|
||||
mFlatColorFocused);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||
mSize.y - mPadding.y - mPadding.w, mFlatColorFocused,
|
||||
mFlatColorFocused);
|
||||
}
|
||||
else {
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||
mSize.y - mPadding.y - mPadding.w, mFlatColorUnfocused,
|
||||
mFlatColorUnfocused);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z,
|
||||
mSize.y - mPadding.y - mPadding.w, mFlatColorUnfocused,
|
||||
mFlatColorUnfocused);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -134,13 +135,13 @@ void ButtonComponent::render(const glm::mat4& parentTrans)
|
|||
trans = glm::translate(trans, centerOffset);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
Renderer::drawRect(centerOffset.x, 0.0f, mTextCache->metrics.size.x, mSize.y,
|
||||
0x00000033, 0x00000033);
|
||||
Renderer::drawRect(mBox.getPosition().x, 0.0f, mBox.getSize().x, mSize.y, 0x0000FF33,
|
||||
0x0000FF33);
|
||||
mRenderer->drawRect(centerOffset.x, 0.0f, mTextCache->metrics.size.x, mSize.y,
|
||||
0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(mBox.getPosition().x, 0.0f, mBox.getSize().x, mSize.y, 0x0000FF33,
|
||||
0x0000FF33);
|
||||
}
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
mTextCache->setColor(getCurTextColor());
|
||||
mFont->renderTextCache(mTextCache.get());
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
unsigned int getCurTextColor() const;
|
||||
void updateImage();
|
||||
|
||||
Renderer* mRenderer;
|
||||
NinePatchComponent mBox;
|
||||
|
||||
std::shared_ptr<Font> mFont;
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace
|
|||
|
||||
CarouselComponent::CarouselComponent()
|
||||
: IList<CarouselElement, SystemData*> {LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mCamOffset {0.0f}
|
||||
, mPreviousScrollVelocity {0}
|
||||
, mType {HORIZONTAL}
|
||||
|
@ -194,11 +195,11 @@ void CarouselComponent::render(const glm::mat4& parentTrans)
|
|||
carouselTrans, glm::vec3 {mOrigin.x * mSize.x * -1.0f, mOrigin.y * mSize.y * -1.0f, 0.0f});
|
||||
|
||||
glm::vec2 clipPos {carouselTrans[3].x, carouselTrans[3].y};
|
||||
Renderer::setMatrix(carouselTrans);
|
||||
mRenderer->setMatrix(carouselTrans);
|
||||
|
||||
// Background box behind logos.
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, mCarouselColor, mCarouselColorEnd,
|
||||
mColorGradientHorizontal);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, mCarouselColor, mCarouselColorEnd,
|
||||
mColorGradientHorizontal);
|
||||
|
||||
// Draw logos.
|
||||
// logoSpacing will also include the size of the logo itself.
|
||||
|
|
|
@ -68,6 +68,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
std::function<void(CursorState state)> mCursorChangedCallback;
|
||||
std::function<void()> mCancelTransitionsCallback;
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
using namespace GridFlags;
|
||||
|
||||
ComponentGrid::ComponentGrid(const glm::ivec2& gridDimensions)
|
||||
: mGridSize {gridDimensions}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mGridSize {gridDimensions}
|
||||
, mCursor {0, 0}
|
||||
{
|
||||
assert(gridDimensions.x > 0 && gridDimensions.y > 0);
|
||||
|
@ -429,9 +430,9 @@ void ComponentGrid::render(const glm::mat4& parentTrans)
|
|||
|
||||
// Draw cell separators.
|
||||
for (size_t i = 0; i < mSeparators.size(); ++i) {
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(mSeparators[i][0], mSeparators[i][1], mSeparators[i][2],
|
||||
mSeparators[i][3], 0xC6C7C6FF, 0xC6C7C6FF);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawRect(mSeparators[i][0], mSeparators[i][1], mSeparators[i][2],
|
||||
mSeparators[i][3], 0xC6C7C6FF, 0xC6C7C6FF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ private:
|
|||
const GridEntry* getCellAt(int x, int y) const;
|
||||
const GridEntry* getCellAt(const glm::ivec2& pos) const { return getCellAt(pos.x, pos.y); }
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::vector<std::vector<float>> mSeparators;
|
||||
glm::ivec2 mGridSize;
|
||||
std::vector<GridEntry> mCells;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
ComponentList::ComponentList()
|
||||
: IList<ComponentListRow, void*> {LIST_SCROLL_STYLE_SLOW, LIST_NEVER_LOOP}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mFocused {false}
|
||||
, mSetupCompleted {false}
|
||||
, mBottomCameraOffset {false}
|
||||
|
@ -294,8 +295,8 @@ void ComponentList::render(const glm::mat4& parentTrans)
|
|||
const int clipRectSizeX {static_cast<int>(std::round(dim.x))};
|
||||
const int clipRectSizeY {static_cast<int>(std::round(dim.y))};
|
||||
|
||||
Renderer::pushClipRect(glm::ivec2 {clipRectPosX, clipRectPosY},
|
||||
glm::ivec2 {clipRectSizeX, clipRectSizeY});
|
||||
mRenderer->pushClipRect(glm::ivec2 {clipRectPosX, clipRectPosY},
|
||||
glm::ivec2 {clipRectSizeX, clipRectSizeY});
|
||||
|
||||
// Scroll the camera.
|
||||
trans = glm::translate(trans, glm::vec3 {0.0f, -mCameraOffset, 0.0f});
|
||||
|
@ -374,20 +375,21 @@ void ComponentList::render(const glm::mat4& parentTrans)
|
|||
}
|
||||
|
||||
// Custom rendering.
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
// Draw selector bar.
|
||||
if (mFocused) {
|
||||
const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data);
|
||||
|
||||
if (mOpacity == 1.0f) {
|
||||
Renderer::drawRect(0.0f, mSelectorBarOffset, std::ceil(mSize.x), selectedRowHeight,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, false, mOpacity, mDimming,
|
||||
Renderer::Blend::ONE_MINUS_DST_COLOR, Renderer::Blend::ZERO);
|
||||
mRenderer->drawRect(0.0f, mSelectorBarOffset, std::ceil(mSize.x), selectedRowHeight,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, false, mOpacity, mDimming,
|
||||
Renderer::BlendFactor::ONE_MINUS_DST_COLOR,
|
||||
Renderer::BlendFactor::ZERO);
|
||||
|
||||
Renderer::drawRect(0.0f, mSelectorBarOffset, std::ceil(mSize.x), selectedRowHeight,
|
||||
0x777777FF, 0x777777FF, false, mOpacity, mDimming,
|
||||
Renderer::Blend::ONE, Renderer::Blend::ONE);
|
||||
mRenderer->drawRect(0.0f, mSelectorBarOffset, std::ceil(mSize.x), selectedRowHeight,
|
||||
0x777777FF, 0x777777FF, false, mOpacity, mDimming,
|
||||
Renderer::BlendFactor::ONE, Renderer::BlendFactor::ONE);
|
||||
}
|
||||
|
||||
for (auto it = drawAfterCursor.cbegin(); it != drawAfterCursor.cend(); ++it)
|
||||
|
@ -395,20 +397,20 @@ void ComponentList::render(const glm::mat4& parentTrans)
|
|||
|
||||
// Reset matrix if one of these components changed it.
|
||||
if (drawAfterCursor.size())
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
}
|
||||
|
||||
// Draw separators.
|
||||
float y = 0;
|
||||
for (unsigned int i = 0; i < mEntries.size(); ++i) {
|
||||
Renderer::drawRect(0.0f, y, std::ceil(mSize.x), 1.0f * Renderer::getScreenHeightModifier(),
|
||||
0xC6C7C6FF, 0xC6C7C6FF, false, mOpacity, mDimming);
|
||||
mRenderer->drawRect(0.0f, y, std::ceil(mSize.x), 1.0f * Renderer::getScreenHeightModifier(),
|
||||
0xC6C7C6FF, 0xC6C7C6FF, false, mOpacity, mDimming);
|
||||
y += getRowHeight(mEntries.at(i).data);
|
||||
}
|
||||
|
||||
Renderer::drawRect(0.0f, y, std::ceil(mSize.x), 1.0f * Renderer::getScreenHeightModifier(),
|
||||
0xC6C7C6FF, 0xC6C7C6FF, false, mOpacity, mDimming);
|
||||
Renderer::popClipRect();
|
||||
mRenderer->drawRect(0.0f, y, std::ceil(mSize.x), 1.0f * Renderer::getScreenHeightModifier(),
|
||||
0xC6C7C6FF, 0xC6C7C6FF, false, mOpacity, mDimming);
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
|
||||
float ComponentList::getRowHeight(const ComponentListRow& row) const
|
||||
|
|
|
@ -124,6 +124,7 @@ protected:
|
|||
void onCursorChanged(const CursorState& state) override;
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
bool mFocused;
|
||||
bool mSetupCompleted;
|
||||
bool mBottomCameraOffset;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
#include "utils/StringUtil.h"
|
||||
|
||||
DateTimeEditComponent::DateTimeEditComponent(bool alignRight, DisplayMode dispMode)
|
||||
: mEditing {false}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mEditing {false}
|
||||
, mEditIndex {0}
|
||||
, mDisplayMode {dispMode}
|
||||
, mKeyRepeatDir {0}
|
||||
|
@ -181,16 +182,16 @@ void DateTimeEditComponent::render(const glm::mat4& parentTrans)
|
|||
off.x += referenceSize - mTextCache->metrics.size.x;
|
||||
trans = glm::translate(trans, off);
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
if (mTextCache->metrics.size.x > 0.0f) {
|
||||
Renderer::drawRect(0.0f, 0.0f - off.y, mSize.x - off.x, mSize.y, 0x0000FF33,
|
||||
0x0000FF33);
|
||||
mRenderer->drawRect(0.0f, 0.0f - off.y, mSize.x - off.x, mSize.y, 0x0000FF33,
|
||||
0x0000FF33);
|
||||
}
|
||||
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
}
|
||||
|
||||
mTextCache->setColor((mColor & 0xFFFFFF00) | static_cast<int>(getOpacity() * 255.0f));
|
||||
|
@ -198,9 +199,9 @@ void DateTimeEditComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
if (mEditing && mTime != 0) {
|
||||
if (mEditIndex >= 0 && static_cast<unsigned int>(mEditIndex) < mCursorBoxes.size())
|
||||
Renderer::drawRect(mCursorBoxes[mEditIndex][0], mCursorBoxes[mEditIndex][1],
|
||||
mCursorBoxes[mEditIndex][2], mCursorBoxes[mEditIndex][3],
|
||||
0x00000022, 0x00000022);
|
||||
mRenderer->drawRect(mCursorBoxes[mEditIndex][0], mCursorBoxes[mEditIndex][1],
|
||||
mCursorBoxes[mEditIndex][2], mCursorBoxes[mEditIndex][3],
|
||||
0x00000022, 0x00000022);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define ES_CORE_COMPONENTS_DATE_TIME_EDIT_COMPONENT_H
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "renderers/Renderer.h"
|
||||
#include "utils/TimeUtil.h"
|
||||
|
||||
class TextCache;
|
||||
|
@ -66,6 +67,7 @@ private:
|
|||
void changeDate();
|
||||
void updateTextCache();
|
||||
|
||||
Renderer* mRenderer;
|
||||
Utils::Time::DateTime mTime;
|
||||
Utils::Time::DateTime mTimeBeforeEdit;
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
#include "ThemeData.h"
|
||||
|
||||
FlexboxComponent::FlexboxComponent(std::vector<FlexboxItem>& items)
|
||||
: mItems {items}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mItems {items}
|
||||
, mDirection {DEFAULT_DIRECTION}
|
||||
, mAlignment {DEFAULT_ALIGNMENT}
|
||||
, mLines {DEFAULT_LINES}
|
||||
|
@ -42,10 +43,10 @@ void FlexboxComponent::render(const glm::mat4& parentTrans)
|
|||
computeLayout();
|
||||
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugImage"))
|
||||
Renderer::drawRect(0.0f, 0.0f, ceilf(mSize.x), ceilf(mSize.y), 0xFF000033, 0xFF000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, ceilf(mSize.x), ceilf(mSize.y), 0xFF000033, 0xFF000033);
|
||||
|
||||
for (auto& item : mItems) {
|
||||
if (!item.visible)
|
||||
|
|
|
@ -81,6 +81,7 @@ private:
|
|||
// Calculate flexbox layout.
|
||||
void computeLayout();
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::vector<FlexboxItem>& mItems;
|
||||
|
||||
// Layout options.
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
#include "utils/StringUtil.h"
|
||||
|
||||
GIFAnimComponent::GIFAnimComponent()
|
||||
: mFrameSize {0}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mFrameSize {0}
|
||||
, mAnimFile {nullptr}
|
||||
, mAnimation {nullptr}
|
||||
, mFrame {nullptr}
|
||||
|
@ -466,10 +467,10 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
|
|||
}
|
||||
}
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugImage"))
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
|
||||
if (mTexture->getSize().x != 0.0f) {
|
||||
mTexture->bind();
|
||||
|
@ -493,6 +494,6 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
|
|||
vertices->convertBGRAToRGBA = true;
|
||||
|
||||
// Render it.
|
||||
Renderer::drawTriangleStrips(&vertices[0], 4);
|
||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ private:
|
|||
return ftell(reinterpret_cast<FILE*>(handle));
|
||||
}
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::shared_ptr<TextureResource> mTexture;
|
||||
std::vector<uint8_t> mPictureRGBA;
|
||||
size_t mFrameSize;
|
||||
|
|
|
@ -30,7 +30,8 @@ glm::vec2 ImageComponent::getSize() const
|
|||
}
|
||||
|
||||
ImageComponent::ImageComponent(bool forceLoad, bool dynamic)
|
||||
: mTargetSize {0, 0}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mTargetSize {0, 0}
|
||||
, mFlipX {false}
|
||||
, mFlipY {false}
|
||||
, mTargetIsMax {false}
|
||||
|
@ -396,14 +397,14 @@ void ImageComponent::render(const glm::mat4& parentTrans)
|
|||
return;
|
||||
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (mTexture && mOpacity > 0.0f) {
|
||||
if (Settings::getInstance()->getBool("DebugImage")) {
|
||||
glm::vec2 targetSizePos {(mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f}};
|
||||
Renderer::drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
|
||||
0xFF000033, 0xFF000033);
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
|
||||
0xFF000033, 0xFF000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
}
|
||||
// An image with zero size would normally indicate a corrupt image file.
|
||||
if (mTexture->getSize() != glm::ivec2 {}) {
|
||||
|
@ -422,7 +423,7 @@ void ImageComponent::render(const glm::mat4& parentTrans)
|
|||
mVertices->opacity = mThemeOpacity;
|
||||
mVertices->dimming = mDimming;
|
||||
|
||||
Renderer::drawTriangleStrips(&mVertices[0], 4);
|
||||
mRenderer->drawTriangleStrips(&mVertices[0], 4);
|
||||
}
|
||||
else {
|
||||
if (!mTexture) {
|
||||
|
|
|
@ -102,6 +102,7 @@ public:
|
|||
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
glm::vec2 mTargetSize;
|
||||
|
||||
bool mFlipX;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
#include "resources/ResourceManager.h"
|
||||
|
||||
LottieAnimComponent::LottieAnimComponent()
|
||||
: mCacheFrames {true}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mCacheFrames {true}
|
||||
, mMaxCacheSize {0}
|
||||
, mCacheSize {0}
|
||||
, mFrameSize {0}
|
||||
|
@ -53,8 +54,8 @@ LottieAnimComponent::LottieAnimComponent()
|
|||
|
||||
// Set component defaults.
|
||||
setOrigin(0.5f, 0.5f);
|
||||
setSize(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
||||
setPosition(Renderer::getScreenWidth() * 0.3f, Renderer::getScreenHeight() * 0.3f);
|
||||
setSize(mRenderer->getScreenWidth() * 0.2f, mRenderer->getScreenHeight() * 0.2f);
|
||||
setPosition(mRenderer->getScreenWidth() * 0.3f, mRenderer->getScreenHeight() * 0.3f);
|
||||
setDefaultZIndex(10.0f);
|
||||
setZIndex(10.0f);
|
||||
}
|
||||
|
@ -455,10 +456,10 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
|||
}
|
||||
}
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugImage"))
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||
|
||||
if (mTexture->getSize().x != 0.0f) {
|
||||
mTexture->bind();
|
||||
|
@ -482,6 +483,6 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
|||
vertices->convertBGRAToRGBA = true;
|
||||
|
||||
// Render it.
|
||||
Renderer::drawTriangleStrips(&vertices[0], 4);
|
||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
private:
|
||||
void render(const glm::mat4& parentTrans) override;
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::shared_ptr<TextureResource> mTexture;
|
||||
std::vector<uint8_t> mPictureRGBA;
|
||||
std::unordered_map<size_t, std::vector<uint8_t>> mFrameCache;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
NinePatchComponent::NinePatchComponent(const std::string& path,
|
||||
unsigned int edgeColor,
|
||||
unsigned int centerColor)
|
||||
: mVertices {nullptr}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mVertices {nullptr}
|
||||
, mPath {path}
|
||||
, mCornerSize {16.0f, 16.0f}
|
||||
, mSharpCorners {false}
|
||||
|
@ -131,10 +132,10 @@ void NinePatchComponent::render(const glm::mat4& parentTrans)
|
|||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
|
||||
if (mTexture && mVertices != nullptr) {
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
mVertices->opacity = mOpacity;
|
||||
mTexture->bind();
|
||||
Renderer::drawTriangleStrips(&mVertices[0], 6 * 9);
|
||||
mRenderer->drawTriangleStrips(&mVertices[0], 6 * 9);
|
||||
}
|
||||
|
||||
renderChildren(trans);
|
||||
|
|
|
@ -62,6 +62,7 @@ private:
|
|||
void buildVertices();
|
||||
void updateColors();
|
||||
|
||||
Renderer* mRenderer;
|
||||
Renderer::Vertex* mVertices;
|
||||
|
||||
std::string mPath;
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
#include "resources/TextureResource.h"
|
||||
|
||||
RatingComponent::RatingComponent(bool colorizeChanges)
|
||||
: mColorOriginalValue {DEFAULT_COLORSHIFT}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mColorOriginalValue {DEFAULT_COLORSHIFT}
|
||||
, mColorChangedValue {DEFAULT_COLORSHIFT}
|
||||
, mColorShift {DEFAULT_COLORSHIFT}
|
||||
, mColorShiftEnd {DEFAULT_COLORSHIFT}
|
||||
|
@ -152,12 +153,12 @@ void RatingComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (mOpacity > 0.0f) {
|
||||
if (Settings::getInstance()->getBool("DebugImage")) {
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.y * NUM_RATING_STARS, mSize.y, 0xFF000033,
|
||||
0xFF000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.y * NUM_RATING_STARS, mSize.y, 0xFF000033,
|
||||
0xFF000033);
|
||||
}
|
||||
|
||||
if (mUnfilledTexture->bind()) {
|
||||
|
@ -167,16 +168,16 @@ void RatingComponent::render(const glm::mat4& parentTrans)
|
|||
(mUnfilledColor & 0xFFFFFF00) + (mVertices[i].color & 0x000000FF);
|
||||
}
|
||||
|
||||
Renderer::drawTriangleStrips(&mVertices[4], 4);
|
||||
Renderer::bindTexture(0);
|
||||
mRenderer->drawTriangleStrips(&mVertices[4], 4);
|
||||
mRenderer->bindTexture(0);
|
||||
|
||||
if (mUnfilledColor != mColorShift)
|
||||
updateColors();
|
||||
}
|
||||
|
||||
if (mFilledTexture->bind()) {
|
||||
Renderer::drawTriangleStrips(&mVertices[0], 4);
|
||||
Renderer::bindTexture(0);
|
||||
mRenderer->drawTriangleStrips(&mVertices[0], 4);
|
||||
mRenderer->bindTexture(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ private:
|
|||
void updateVertices();
|
||||
void updateColors();
|
||||
|
||||
Renderer* mRenderer;
|
||||
float mValue;
|
||||
int mOriginalValue;
|
||||
unsigned int mColorOriginalValue;
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#include "resources/Font.h"
|
||||
|
||||
ScrollableContainer::ScrollableContainer()
|
||||
: mScrollPos {0.0f, 0.0f}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mScrollPos {0.0f, 0.0f}
|
||||
, mScrollDir {0.0f, 0.0f}
|
||||
, mClipSpacing {0.0f}
|
||||
, mAutoScrollDelay {0}
|
||||
|
@ -233,11 +234,11 @@ void ScrollableContainer::render(const glm::mat4& parentTrans)
|
|||
clipPos.y += static_cast<int>(mClipSpacing);
|
||||
clipDim.y -= static_cast<int>(mClipSpacing);
|
||||
|
||||
Renderer::pushClipRect(clipPos, clipDim);
|
||||
mRenderer->pushClipRect(clipPos, clipDim);
|
||||
|
||||
trans = glm::translate(trans, -glm::vec3 {mScrollPos.x, mScrollPos.y, 0.0f});
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
GuiComponent::renderChildren(trans);
|
||||
Renderer::popClipRect();
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define AUTO_SCROLL_SPEED 4.0f
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "renderers/Renderer.h"
|
||||
|
||||
class ScrollableContainer : public GuiComponent
|
||||
{
|
||||
|
@ -42,6 +43,7 @@ public:
|
|||
void render(const glm::mat4& parentTrans) override;
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
glm::vec2 mScrollPos;
|
||||
glm::vec2 mScrollDir;
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#define MOVE_REPEAT_RATE 40
|
||||
|
||||
SliderComponent::SliderComponent(float min, float max, float increment, const std::string& suffix)
|
||||
: mMin {min}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mMin {min}
|
||||
, mMax {max}
|
||||
, mSingleIncrement {increment}
|
||||
, mMoveRate {0.0f}
|
||||
|
@ -77,14 +78,14 @@ void SliderComponent::update(int deltaTime)
|
|||
void SliderComponent::render(const glm::mat4& parentTrans)
|
||||
{
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
Renderer::drawRect(
|
||||
mRenderer->drawRect(
|
||||
mSize.x - mTextCache->metrics.size.x, (mSize.y - mTextCache->metrics.size.y) / 2.0f,
|
||||
mTextCache->metrics.size.x, mTextCache->metrics.size.y, 0x0000FF33, 0x0000FF33);
|
||||
Renderer::drawRect(mSize.x - mTextCache->metrics.size.x, 0.0f, mTextCache->metrics.size.x,
|
||||
mSize.y, 0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(mSize.x - mTextCache->metrics.size.x, 0.0f, mTextCache->metrics.size.x,
|
||||
mSize.y, 0x00000033, 0x00000033);
|
||||
}
|
||||
|
||||
float width {mSize.x - mKnob.getSize().x -
|
||||
|
@ -97,8 +98,8 @@ void SliderComponent::render(const glm::mat4& parentTrans)
|
|||
mFont->renderTextCache(mTextCache.get());
|
||||
|
||||
// Render bar.
|
||||
Renderer::drawRect(mKnob.getSize().x / 2.0f, mSize.y / 2.0f - mBarHeight / 2.0f, width,
|
||||
mBarHeight, 0x777777FF, 0x777777FF);
|
||||
mRenderer->drawRect(mKnob.getSize().x / 2.0f, mSize.y / 2.0f - mBarHeight / 2.0f, width,
|
||||
mBarHeight, 0x777777FF, 0x777777FF);
|
||||
|
||||
// Render knob.
|
||||
mKnob.render(trans);
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
private:
|
||||
void onValueChanged();
|
||||
|
||||
Renderer* mRenderer;
|
||||
float mMin, mMax;
|
||||
float mValue;
|
||||
float mSingleIncrement;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
TextComponent::TextComponent()
|
||||
: mFont {Font::get(FONT_SIZE_MEDIUM)}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mColor {0x000000FF}
|
||||
, mBgColor {0x00000000}
|
||||
, mColorOpacity {1.0f}
|
||||
|
@ -39,6 +40,7 @@ TextComponent::TextComponent(const std::string& text,
|
|||
glm::vec2 size,
|
||||
unsigned int bgcolor)
|
||||
: mFont {nullptr}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mColor {0x000000FF}
|
||||
, mBgColor {0x00000000}
|
||||
, mColorOpacity {1.0f}
|
||||
|
@ -161,11 +163,11 @@ void TextComponent::render(const glm::mat4& parentTrans)
|
|||
return;
|
||||
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (mRenderBackground)
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, mBgColor, mBgColor, false,
|
||||
mOpacity * mThemeOpacity, mDimming);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, mBgColor, mBgColor, false,
|
||||
mOpacity * mThemeOpacity, mDimming);
|
||||
|
||||
if (mTextCache) {
|
||||
const glm::vec2& textSize {mTextCache->metrics.size};
|
||||
|
@ -191,29 +193,29 @@ void TextComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
// Draw the "textbox" area, what we are aligned within.
|
||||
if (Settings::getInstance()->getBool("DebugText"))
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
|
||||
|
||||
trans = glm::translate(trans, off);
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
// Draw the text area, where the text actually is located.
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
switch (mHorizontalAlignment) {
|
||||
case ALIGN_LEFT: {
|
||||
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_CENTER: {
|
||||
Renderer::drawRect((mSize.x - mTextCache->metrics.size.x) / 2.0f, 0.0f,
|
||||
mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
mRenderer->drawRect((mSize.x - mTextCache->metrics.size.x) / 2.0f, 0.0f,
|
||||
mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_RIGHT: {
|
||||
Renderer::drawRect(mSize.x - mTextCache->metrics.size.x, 0.0f,
|
||||
mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(mSize.x - mTextCache->metrics.size.x, 0.0f,
|
||||
mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -89,6 +89,7 @@ private:
|
|||
void calculateExtent();
|
||||
void onColorChanged();
|
||||
|
||||
Renderer* mRenderer;
|
||||
unsigned int mColor;
|
||||
unsigned int mBgColor;
|
||||
float mColorOpacity;
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
#define BLINKTIME 1000
|
||||
|
||||
TextEditComponent::TextEditComponent()
|
||||
: mFocused {false}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mFocused {false}
|
||||
, mEditing {false}
|
||||
, mCursor {0}
|
||||
, mBlinkTime {0}
|
||||
|
@ -304,16 +305,16 @@ void TextEditComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
glm::ivec2 clipDim {static_cast<int>(dimScaled.x - trans[3].x),
|
||||
static_cast<int>(dimScaled.y - trans[3].y)};
|
||||
Renderer::pushClipRect(clipPos, clipDim);
|
||||
mRenderer->pushClipRect(clipPos, clipDim);
|
||||
|
||||
trans = glm::translate(trans, glm::vec3 {-mScrollOffset.x, -mScrollOffset.y, 0.0f});
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
if (mTextCache)
|
||||
mFont->renderTextCache(mTextCache.get());
|
||||
|
||||
// Pop the clip early to allow the cursor to be drawn outside of the "text area".
|
||||
Renderer::popClipRect();
|
||||
mRenderer->popClipRect();
|
||||
|
||||
// Draw cursor.
|
||||
glm::vec2 cursorPos;
|
||||
|
@ -328,15 +329,15 @@ void TextEditComponent::render(const glm::mat4& parentTrans)
|
|||
float cursorHeight = mFont->getHeight() * 0.8f;
|
||||
|
||||
if (!mEditing) {
|
||||
Renderer::drawRect(cursorPos.x, cursorPos.y + (mFont->getHeight() - cursorHeight) / 2.0f,
|
||||
2.0f * Renderer::getScreenWidthModifier(), cursorHeight, 0xC7C7C7FF,
|
||||
0xC7C7C7FF);
|
||||
mRenderer->drawRect(cursorPos.x, cursorPos.y + (mFont->getHeight() - cursorHeight) / 2.0f,
|
||||
2.0f * Renderer::getScreenWidthModifier(), cursorHeight, 0xC7C7C7FF,
|
||||
0xC7C7C7FF);
|
||||
}
|
||||
|
||||
if (mEditing && mBlinkTime < BLINKTIME / 2) {
|
||||
Renderer::drawRect(cursorPos.x, cursorPos.y + (mFont->getHeight() - cursorHeight) / 2.0f,
|
||||
2.0f * Renderer::getScreenWidthModifier(), cursorHeight, 0x777777FF,
|
||||
0x777777FF);
|
||||
mRenderer->drawRect(cursorPos.x, cursorPos.y + (mFont->getHeight() - cursorHeight) / 2.0f,
|
||||
2.0f * Renderer::getScreenWidthModifier(), cursorHeight, 0x777777FF,
|
||||
0x777777FF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
glm::vec2 getTextAreaPos() const;
|
||||
glm::vec2 getTextAreaSize() const;
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::string mText;
|
||||
std::string mTextOrig;
|
||||
bool mFocused;
|
||||
|
|
|
@ -135,6 +135,7 @@ protected:
|
|||
void onCursorChanged(const CursorState& state) override;
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
int mLoopOffset;
|
||||
int mLoopOffset2;
|
||||
int mLoopTime;
|
||||
|
@ -164,6 +165,7 @@ private:
|
|||
|
||||
template <typename T> TextListComponent<T>::TextListComponent()
|
||||
{
|
||||
mRenderer = Renderer::getInstance();
|
||||
mLoopOffset = 0;
|
||||
mLoopOffset2 = 0;
|
||||
mLoopTime = 0;
|
||||
|
@ -232,17 +234,17 @@ template <typename T> void TextListComponent<T>::render(const glm::mat4& parentT
|
|||
mSelectorImage.render(trans);
|
||||
}
|
||||
else {
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.0f, (mCursor - startEntry) * entrySize + mSelectorOffsetY, mSize.x,
|
||||
mSelectorHeight, mSelectorColor, mSelectorColorEnd,
|
||||
mSelectorColorGradientHorizontal);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawRect(0.0f, (mCursor - startEntry) * entrySize + mSelectorOffsetY,
|
||||
mSize.x, mSelectorHeight, mSelectorColor, mSelectorColorEnd,
|
||||
mSelectorColorGradientHorizontal);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
Renderer::drawRect(mHorizontalMargin, 0.0f, mSize.x - mHorizontalMargin * 2.0f, mSize.y,
|
||||
0x00000033, 0x00000033);
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
|
||||
mRenderer->drawRect(mHorizontalMargin, 0.0f, mSize.x - mHorizontalMargin * 2.0f, mSize.y,
|
||||
0x00000033, 0x00000033);
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
|
||||
}
|
||||
|
||||
// Clip to inside margins.
|
||||
|
@ -250,7 +252,7 @@ template <typename T> void TextListComponent<T>::render(const glm::mat4& parentT
|
|||
dim.x = (trans[0].x * dim.x + trans[3].x) - trans[3].x;
|
||||
dim.y = (trans[1].y * dim.y + trans[3].y) - trans[3].y;
|
||||
|
||||
Renderer::pushClipRect(
|
||||
mRenderer->pushClipRect(
|
||||
glm::ivec2 {static_cast<int>(std::round(trans[3].x + mHorizontalMargin)),
|
||||
static_cast<int>(std::round(trans[3].y))},
|
||||
glm::ivec2 {static_cast<int>(std::round(dim.x - mHorizontalMargin * 2.0f)),
|
||||
|
@ -323,7 +325,7 @@ template <typename T> void TextListComponent<T>::render(const glm::mat4& parentT
|
|||
if (mLoopOffset == 0 && mLoopOffset2 == 0)
|
||||
mLoopScroll = false;
|
||||
|
||||
Renderer::setMatrix(drawTrans);
|
||||
mRenderer->setMatrix(drawTrans);
|
||||
font->renderTextCache(entry.data.textCache.get());
|
||||
|
||||
// Render currently selected row again if text is moved far enough for it to repeat.
|
||||
|
@ -332,12 +334,12 @@ template <typename T> void TextListComponent<T>::render(const glm::mat4& parentT
|
|||
drawTrans = trans;
|
||||
drawTrans = glm::translate(
|
||||
drawTrans, offset - glm::vec3 {static_cast<float>(mLoopOffset2), 0.0f, 0.0f});
|
||||
Renderer::setMatrix(drawTrans);
|
||||
mRenderer->setMatrix(drawTrans);
|
||||
font->renderTextCache(entry.data.textCache.get());
|
||||
}
|
||||
y += entrySize;
|
||||
}
|
||||
Renderer::popClipRect();
|
||||
mRenderer->popClipRect();
|
||||
List::listRenderTitleOverlay(trans);
|
||||
GuiComponent::renderChildren(trans);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "Window.h"
|
||||
#include "resources/TextureResource.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
|
@ -24,7 +26,8 @@ std::vector<std::string> VideoFFmpegComponent::sHWDecodedVideos;
|
|||
std::vector<std::string> VideoFFmpegComponent::sSWDecodedVideos;
|
||||
|
||||
VideoFFmpegComponent::VideoFFmpegComponent()
|
||||
: mRectangleOffset {0.0f, 0.0f}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mRectangleOffset {0.0f, 0.0f}
|
||||
, mFrameProcessingThread {nullptr}
|
||||
, mFormatContext {nullptr}
|
||||
, mVideoStream {nullptr}
|
||||
|
@ -133,7 +136,7 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
if (mIsPlaying && mFormatContext) {
|
||||
Renderer::Vertex vertices[4];
|
||||
Renderer::setMatrix(parentTrans);
|
||||
mRenderer->setMatrix(parentTrans);
|
||||
|
||||
unsigned int rectColor {0x000000FF};
|
||||
|
||||
|
@ -142,9 +145,9 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
|||
|
||||
// Render the black rectangle behind the video.
|
||||
if (mVideoRectangleCoords.size() == 4) {
|
||||
Renderer::drawRect(mVideoRectangleCoords[0], mVideoRectangleCoords[1],
|
||||
mVideoRectangleCoords[2], mVideoRectangleCoords[3], // Line break.
|
||||
rectColor, rectColor);
|
||||
mRenderer->drawRect(mVideoRectangleCoords[0], mVideoRectangleCoords[1],
|
||||
mVideoRectangleCoords[2], mVideoRectangleCoords[3], // Line break.
|
||||
rectColor, rectColor);
|
||||
}
|
||||
|
||||
// This is needed to avoid a slight gap before the video starts playing.
|
||||
|
@ -219,8 +222,8 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
|||
}
|
||||
|
||||
// Render it.
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawTriangleStrips(&vertices[0], 4);
|
||||
mRenderer->setMatrix(trans);
|
||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
||||
}
|
||||
else {
|
||||
if (mVisible)
|
||||
|
|
|
@ -84,6 +84,7 @@ private:
|
|||
static void detectHWDecoder();
|
||||
bool decoderInitHW();
|
||||
|
||||
Renderer* mRenderer;
|
||||
static enum AVHWDeviceType sDeviceType;
|
||||
static enum AVPixelFormat sPixelFormat;
|
||||
static std::vector<std::string> sSWDecodedVideos;
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#include <SDL2/SDL_timer.h>
|
||||
|
||||
GuiInfoPopup::GuiInfoPopup(std::string message, int duration)
|
||||
: mMessage {message}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mMessage {message}
|
||||
, mDuration {duration}
|
||||
, mAlpha {1.0f}
|
||||
, mRunning {true}
|
||||
|
@ -78,7 +79,7 @@ void GuiInfoPopup::render(const glm::mat4& /*parentTrans*/)
|
|||
glm::mat4 trans {getTransform() * Renderer::getIdentity()};
|
||||
if (mRunning && updateState()) {
|
||||
// If we're still supposed to be rendering it.
|
||||
Renderer::setMatrix(trans);
|
||||
mRenderer->setMatrix(trans);
|
||||
renderChildren(trans);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define ES_APP_GUIS_GUI_INFO_POPUP_H
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "renderers/Renderer.h"
|
||||
|
||||
class ComponentGrid;
|
||||
class NinePatchComponent;
|
||||
|
@ -27,6 +28,7 @@ public:
|
|||
private:
|
||||
bool updateState();
|
||||
|
||||
Renderer* mRenderer;
|
||||
ComponentGrid* mGrid;
|
||||
NinePatchComponent* mFrame;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// EmulationStation Desktop Edition
|
||||
// Renderer.cpp
|
||||
//
|
||||
// General rendering functions.
|
||||
// Generic rendering functions.
|
||||
//
|
||||
|
||||
#include "renderers/Renderer.h"
|
||||
|
@ -12,468 +12,386 @@
|
|||
#include "Log.h"
|
||||
#include "Settings.h"
|
||||
#include "Shader_GL21.h"
|
||||
#include "renderers/Renderer_GL21.h"
|
||||
#include "resources/ResourceManager.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stack>
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Renderer
|
||||
Renderer* Renderer::getInstance()
|
||||
{
|
||||
static std::stack<Rect> clipStack;
|
||||
static SDL_Window* sdlWindow {nullptr};
|
||||
static glm::mat4 mProjectionMatrix {};
|
||||
static glm::mat4 mProjectionMatrixRotated {};
|
||||
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 bool screenRotated {0};
|
||||
static bool initialCursorState {1};
|
||||
// Screen resolution modifiers relative to the 1920x1080 reference.
|
||||
static float screenHeightModifier {0.0f};
|
||||
static float screenWidthModifier {0.0f};
|
||||
static float screenAspectRatio {0.0f};
|
||||
static RendererOpenGL instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
static void setIcon()
|
||||
{
|
||||
size_t width {0};
|
||||
size_t height {0};
|
||||
ResourceData resData {
|
||||
ResourceManager::getInstance().getFileData(":/graphics/window_icon_256.png")};
|
||||
std::vector<unsigned char> rawData {
|
||||
ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height)};
|
||||
void Renderer::setIcon()
|
||||
{
|
||||
size_t width {0};
|
||||
size_t height {0};
|
||||
ResourceData resData {
|
||||
ResourceManager::getInstance().getFileData(":/graphics/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 (!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};
|
||||
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};
|
||||
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(
|
||||
static_cast<void*>(rawData.data()), static_cast<int>(width),
|
||||
static_cast<int>(height), 32, static_cast<int>((width * 4)), rmask, gmask, bmask,
|
||||
amask)};
|
||||
// Try creating SDL surface from logo data.
|
||||
SDL_Surface* logoSurface {SDL_CreateRGBSurfaceFrom(
|
||||
static_cast<void*>(rawData.data()), static_cast<int>(width), static_cast<int>(height),
|
||||
32, static_cast<int>((width * 4)), rmask, gmask, bmask, amask)};
|
||||
|
||||
if (logoSurface != nullptr) {
|
||||
SDL_SetWindowIcon(sdlWindow, logoSurface);
|
||||
SDL_FreeSurface(logoSurface);
|
||||
}
|
||||
if (logoSurface != nullptr) {
|
||||
SDL_SetWindowIcon(mSDLWindow, logoSurface);
|
||||
SDL_FreeSurface(logoSurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool createWindow()
|
||||
{
|
||||
LOG(LogInfo) << "Creating window...";
|
||||
bool Renderer::createWindow()
|
||||
{
|
||||
LOG(LogInfo) << "Creating window...";
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
LOG(LogError) << "Couldn't initialize SDL: " << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
LOG(LogError) << "Couldn't initialize SDL: " << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
initialCursorState = (SDL_ShowCursor(0) != 0);
|
||||
mInitialCursorState = (SDL_ShowCursor(0) != 0);
|
||||
|
||||
int displayIndex {Settings::getInstance()->getInt("DisplayIndex")};
|
||||
// Check that an invalid value has not been manually entered in the es_settings.xml file.
|
||||
if (displayIndex != 1 && displayIndex != 2 && displayIndex != 3 && displayIndex != 4) {
|
||||
Settings::getInstance()->setInt("DisplayIndex", 1);
|
||||
displayIndex = 0;
|
||||
}
|
||||
else {
|
||||
--displayIndex;
|
||||
}
|
||||
int displayIndex {Settings::getInstance()->getInt("DisplayIndex")};
|
||||
// Check that an invalid value has not been manually entered in the es_settings.xml file.
|
||||
if (displayIndex != 1 && displayIndex != 2 && displayIndex != 3 && displayIndex != 4) {
|
||||
Settings::getInstance()->setInt("DisplayIndex", 1);
|
||||
displayIndex = 0;
|
||||
}
|
||||
else {
|
||||
--displayIndex;
|
||||
}
|
||||
|
||||
int availableDisplays = SDL_GetNumVideoDisplays();
|
||||
if (displayIndex > availableDisplays - 1) {
|
||||
LOG(LogWarning) << "Requested display " << std::to_string(displayIndex + 1)
|
||||
<< " does not exist, changing to display 1";
|
||||
displayIndex = 0;
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Using display: " << std::to_string(displayIndex + 1);
|
||||
}
|
||||
int availableDisplays = SDL_GetNumVideoDisplays();
|
||||
if (displayIndex > availableDisplays - 1) {
|
||||
LOG(LogWarning) << "Requested display " << std::to_string(displayIndex + 1)
|
||||
<< " does not exist, changing to display 1";
|
||||
displayIndex = 0;
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Using display: " << std::to_string(displayIndex + 1);
|
||||
}
|
||||
|
||||
SDL_DisplayMode displayMode;
|
||||
SDL_GetDesktopDisplayMode(displayIndex, &displayMode);
|
||||
SDL_DisplayMode displayMode;
|
||||
SDL_GetDesktopDisplayMode(displayIndex, &displayMode);
|
||||
|
||||
#if defined(_WIN64)
|
||||
// Tell Windows that we're DPI aware so that we can set a physical resolution and
|
||||
// avoid any automatic DPI scaling.
|
||||
SetProcessDPIAware();
|
||||
// We need to set the resolution based on the actual display bounds as the numbers
|
||||
// returned by SDL_GetDesktopDisplayMode are calculated based on DPI scaling and
|
||||
// therefore do not necessarily reflect the physical display resolution.
|
||||
SDL_Rect displayBounds;
|
||||
SDL_GetDisplayBounds(displayIndex, &displayBounds);
|
||||
displayMode.w = displayBounds.w;
|
||||
displayMode.h = displayBounds.h;
|
||||
// Tell Windows that we're DPI aware so that we can set a physical resolution and
|
||||
// avoid any automatic DPI scaling.
|
||||
SetProcessDPIAware();
|
||||
// We need to set the resolution based on the actual display bounds as the numbers
|
||||
// returned by SDL_GetDesktopDisplayMode are calculated based on DPI scaling and
|
||||
// therefore do not necessarily reflect the physical display resolution.
|
||||
SDL_Rect displayBounds;
|
||||
SDL_GetDisplayBounds(displayIndex, &displayBounds);
|
||||
displayMode.w = displayBounds.w;
|
||||
displayMode.h = displayBounds.h;
|
||||
#endif
|
||||
|
||||
windowWidth = Settings::getInstance()->getInt("WindowWidth") ?
|
||||
Settings::getInstance()->getInt("WindowWidth") :
|
||||
displayMode.w;
|
||||
windowHeight = Settings::getInstance()->getInt("WindowHeight") ?
|
||||
Settings::getInstance()->getInt("WindowHeight") :
|
||||
displayMode.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;
|
||||
screenRotated = Settings::getInstance()->getBool("ScreenRotate");
|
||||
mWindowWidth = Settings::getInstance()->getInt("WindowWidth") ?
|
||||
Settings::getInstance()->getInt("WindowWidth") :
|
||||
displayMode.w;
|
||||
mWindowHeight = Settings::getInstance()->getInt("WindowHeight") ?
|
||||
Settings::getInstance()->getInt("WindowHeight") :
|
||||
displayMode.h;
|
||||
sScreenWidth = Settings::getInstance()->getInt("ScreenWidth") ?
|
||||
Settings::getInstance()->getInt("ScreenWidth") :
|
||||
mWindowWidth;
|
||||
sScreenHeight = Settings::getInstance()->getInt("ScreenHeight") ?
|
||||
Settings::getInstance()->getInt("ScreenHeight") :
|
||||
mWindowHeight;
|
||||
mScreenOffsetX = Settings::getInstance()->getInt("ScreenOffsetX") ?
|
||||
Settings::getInstance()->getInt("ScreenOffsetX") :
|
||||
0;
|
||||
mScreenOffsetY = Settings::getInstance()->getInt("ScreenOffsetY") ?
|
||||
Settings::getInstance()->getInt("ScreenOffsetY") :
|
||||
0;
|
||||
mScreenRotated = Settings::getInstance()->getBool("ScreenRotate");
|
||||
|
||||
// Prevent the application window from minimizing when switching windows (when launching
|
||||
// games or when manually switching windows using the task switcher).
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
// Prevent the application window from minimizing when switching windows (when launching
|
||||
// games or when manually switching windows using the task switcher).
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
#if defined(__unix__)
|
||||
// Disabling desktop composition can lead to better framerates and a more fluid user
|
||||
// interface, but with some drivers it can cause strange behaviors when returning to
|
||||
// the desktop.
|
||||
if (Settings::getInstance()->getBool("DisableComposition"))
|
||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "1");
|
||||
else
|
||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
||||
// Disabling desktop composition can lead to better framerates and a more fluid user
|
||||
// interface, but with some drivers it can cause strange behaviors when returning to
|
||||
// the desktop.
|
||||
if (Settings::getInstance()->getBool("DisableComposition"))
|
||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "1");
|
||||
else
|
||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
||||
#endif
|
||||
|
||||
bool userResolution = false;
|
||||
// Check if the user has changed the resolution from the command line.
|
||||
if (windowWidth != displayMode.w || windowHeight != displayMode.h)
|
||||
userResolution = true;
|
||||
bool userResolution = false;
|
||||
// Check if the user has changed the resolution from the command line.
|
||||
if (mWindowWidth != displayMode.w || mWindowHeight != displayMode.h)
|
||||
userResolution = true;
|
||||
|
||||
unsigned int windowFlags;
|
||||
setupWindow();
|
||||
unsigned int windowFlags;
|
||||
setup();
|
||||
|
||||
#if defined(_WIN64)
|
||||
// For Windows we use SDL_WINDOW_BORDERLESS as "real" full screen doesn't work properly.
|
||||
// The borderless mode seems to behave well and it's almost completely seamless, especially
|
||||
// with a hidden taskbar.
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
// If the resolution has been manually set from the command line, then keep the border.
|
||||
windowFlags = SDL_WINDOW_OPENGL;
|
||||
// For Windows we use SDL_WINDOW_BORDERLESS as "real" full screen doesn't work properly.
|
||||
// The borderless mode seems to behave well and it's almost completely seamless, especially
|
||||
// with a hidden taskbar.
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
// If the resolution has been manually set from the command line, then keep the border.
|
||||
windowFlags = SDL_WINDOW_OPENGL;
|
||||
#elif defined(__APPLE__)
|
||||
// Not sure if this could be a useful setting.
|
||||
// SDL_SetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, "0");
|
||||
// Not sure if this could be a useful setting.
|
||||
// SDL_SetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, "0");
|
||||
|
||||
// The SDL_WINDOW_BORDERLESS mode seems to be the only mode that somehow works on macOS
|
||||
// as a real fullscreen mode will do lots of weird stuff like preventing window switching
|
||||
// or refusing to let emulators run at all. SDL_WINDOW_FULLSCREEN_DESKTOP almost works, but
|
||||
// it "shuffles" windows when starting the emulator and won't return properly when the game
|
||||
// has exited. With SDL_WINDOW_BORDERLESS some emulators (like RetroArch) have to be
|
||||
// configured to run in fullscreen mode or switching to its window will not work, but
|
||||
// apart from that this mode works fine.
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
windowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
|
||||
// The SDL_WINDOW_BORDERLESS mode seems to be the only mode that somehow works on macOS
|
||||
// as a real fullscreen mode will do lots of weird stuff like preventing window switching
|
||||
// or refusing to let emulators run at all. SDL_WINDOW_FULLSCREEN_DESKTOP almost works, but
|
||||
// it "shuffles" windows when starting the emulator and won't return properly when the game
|
||||
// has exited. With SDL_WINDOW_BORDERLESS some emulators (like RetroArch) have to be
|
||||
// configured to run in fullscreen mode or switching to its window will not work, but
|
||||
// apart from that this mode works fine.
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
windowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
|
||||
#else
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
windowFlags = SDL_WINDOW_OPENGL;
|
||||
if (!userResolution)
|
||||
windowFlags = SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL;
|
||||
else
|
||||
windowFlags = SDL_WINDOW_OPENGL;
|
||||
#endif
|
||||
|
||||
if ((sdlWindow =
|
||||
SDL_CreateWindow("EmulationStation", SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),
|
||||
SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), windowWidth,
|
||||
windowHeight, windowFlags)) == nullptr) {
|
||||
LOG(LogError) << "Couldn't create SDL window. " << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
if ((mSDLWindow =
|
||||
SDL_CreateWindow("EmulationStation", SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),
|
||||
SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), mWindowWidth,
|
||||
mWindowHeight, windowFlags)) == nullptr) {
|
||||
LOG(LogError) << "Couldn't create SDL window. " << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// The code below is required as the high DPI scaling on macOS is very bizarre and is
|
||||
// measured in "points" rather than pixels (even though the naming convention sure looks
|
||||
// like pixels). For example there could be a 1920x1080 entry in the OS display settings
|
||||
// that actually corresponds to something like 3840x2160 pixels while at the same time
|
||||
// there is a separate 1080p entry which corresponds to a "real" 1920x1080 resolution.
|
||||
// Therefore the --resolution flag results in different things depending on whether a high
|
||||
// DPI screen is used. E.g. 1280x720 on a 4K display would actually end up as 2560x1440
|
||||
// which is incredibly strange. No point in struggling with this strangeness though,
|
||||
// instead we simply indicate the physical pixel dimensions in parenthesis in the log
|
||||
// file and make sure to double the window and screen sizes in case of a high DPI
|
||||
// display so that the full application window is used for rendering.
|
||||
int width = 0;
|
||||
SDL_GL_GetDrawableSize(sdlWindow, &width, nullptr);
|
||||
int scaleFactor = static_cast<int>(width / windowWidth);
|
||||
// The code below is required as the high DPI scaling on macOS is very bizarre and is
|
||||
// measured in "points" rather than pixels (even though the naming convention sure looks
|
||||
// like pixels). For example there could be a 1920x1080 entry in the OS display settings
|
||||
// that actually corresponds to something like 3840x2160 pixels while at the same time
|
||||
// there is a separate 1080p entry which corresponds to a "real" 1920x1080 resolution.
|
||||
// Therefore the --resolution flag results in different things depending on whether a high
|
||||
// DPI screen is used. E.g. 1280x720 on a 4K display would actually end up as 2560x1440
|
||||
// which is incredibly strange. No point in struggling with this strangeness though,
|
||||
// instead we simply indicate the physical pixel dimensions in parenthesis in the log
|
||||
// file and make sure to double the window and screen sizes in case of a high DPI
|
||||
// display so that the full application window is used for rendering.
|
||||
int width = 0;
|
||||
SDL_GL_GetDrawableSize(mSDLWindow, &width, nullptr);
|
||||
int scaleFactor = static_cast<int>(width / mWindowWidth);
|
||||
|
||||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h) << " (physical resolution "
|
||||
<< std::to_string(displayMode.w * scaleFactor) << "x"
|
||||
<< std::to_string(displayMode.h * scaleFactor) << ")";
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate)
|
||||
<< " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(windowWidth) << "x"
|
||||
<< std::to_string(windowHeight) << " (physical resolution "
|
||||
<< std::to_string(windowWidth * scaleFactor) << "x"
|
||||
<< std::to_string(windowHeight * scaleFactor) << ")";
|
||||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h) << " (physical resolution "
|
||||
<< std::to_string(displayMode.w * scaleFactor) << "x"
|
||||
<< std::to_string(displayMode.h * scaleFactor) << ")";
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(mWindowWidth) << "x"
|
||||
<< std::to_string(mWindowHeight) << " (physical resolution "
|
||||
<< std::to_string(mWindowWidth * scaleFactor) << "x"
|
||||
<< std::to_string(mWindowHeight * scaleFactor) << ")";
|
||||
|
||||
windowWidth *= scaleFactor;
|
||||
windowHeight *= scaleFactor;
|
||||
screenWidth *= scaleFactor;
|
||||
screenHeight *= scaleFactor;
|
||||
mWindowWidth *= scaleFactor;
|
||||
mWindowHeight *= scaleFactor;
|
||||
sScreenWidth *= scaleFactor;
|
||||
sScreenHeight *= scaleFactor;
|
||||
#else
|
||||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h);
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate)
|
||||
<< " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(windowWidth) << "x"
|
||||
<< std::to_string(windowHeight);
|
||||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h);
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(mWindowWidth) << "x"
|
||||
<< std::to_string(mWindowHeight);
|
||||
#endif
|
||||
|
||||
screenHeightModifier = static_cast<float>(screenHeight) / 1080.0f;
|
||||
screenWidthModifier = static_cast<float>(screenWidth) / 1920.0f;
|
||||
screenAspectRatio = static_cast<float>(screenWidth) / static_cast<float>(screenHeight);
|
||||
sScreenHeightModifier = static_cast<float>(sScreenHeight) / 1080.0f;
|
||||
sScreenWidthModifier = static_cast<float>(sScreenWidth) / 1920.0f;
|
||||
sScreenAspectRatio = static_cast<float>(sScreenWidth) / static_cast<float>(sScreenHeight);
|
||||
|
||||
LOG(LogInfo) << "Setting up OpenGL...";
|
||||
LOG(LogInfo) << "Setting up OpenGL...";
|
||||
|
||||
if (!createContext())
|
||||
return false;
|
||||
if (!createContext())
|
||||
return false;
|
||||
|
||||
setIcon();
|
||||
setSwapInterval();
|
||||
setIcon();
|
||||
setSwapInterval();
|
||||
|
||||
#if defined(_WIN64)
|
||||
// It seems as if Windows needs this to avoid a brief white screen flash on startup.
|
||||
// Possibly this is driver-specific rather than OS-specific. There is additional code
|
||||
// in init() to work around the white screen flash issue on all operating systems.
|
||||
swapBuffers();
|
||||
// It seems as if Windows needs this to avoid a brief white screen flash on startup.
|
||||
// Possibly this is driver-specific rather than OS-specific. There is additional code
|
||||
// in init() to work around the white screen flash issue on all operating systems.
|
||||
swapBuffers();
|
||||
#endif
|
||||
|
||||
LOG(LogInfo) << "Loading shaders...";
|
||||
return loadShaders();
|
||||
}
|
||||
|
||||
std::vector<std::string> shaderFiles;
|
||||
shaderFiles.push_back(":/shaders/glsl/core.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/blur_horizontal.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/blur_vertical.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/scanlines.glsl");
|
||||
void Renderer::destroyWindow()
|
||||
{
|
||||
destroyContext();
|
||||
SDL_DestroyWindow(mSDLWindow);
|
||||
|
||||
for (auto it = shaderFiles.cbegin(); it != shaderFiles.cend(); ++it) {
|
||||
Shader* loadShader = new Shader();
|
||||
mSDLWindow = nullptr;
|
||||
|
||||
loadShader->loadShaderFile(*it, GL_VERTEX_SHADER);
|
||||
loadShader->loadShaderFile(*it, GL_FRAGMENT_SHADER);
|
||||
SDL_ShowCursor(mInitialCursorState);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
if (!loadShader->createProgram()) {
|
||||
LOG(LogError) << "Could not create shader program.";
|
||||
return false;
|
||||
}
|
||||
bool Renderer::init()
|
||||
{
|
||||
if (!createWindow())
|
||||
return false;
|
||||
|
||||
sShaderProgramVector.push_back(loadShader);
|
||||
}
|
||||
glm::mat4 projection {getIdentity()};
|
||||
Rect viewport {0, 0, 0, 0};
|
||||
|
||||
return true;
|
||||
viewport.x = mWindowWidth - mScreenOffsetX - sScreenWidth;
|
||||
viewport.y = mWindowHeight - mScreenOffsetY - sScreenHeight;
|
||||
viewport.w = sScreenWidth;
|
||||
viewport.h = sScreenHeight;
|
||||
projection = glm::ortho(0.0f, static_cast<float>(sScreenWidth),
|
||||
static_cast<float>(sScreenHeight), 0.0f, -1.0f, 1.0f);
|
||||
projection = glm::rotate(projection, glm::radians(180.0f), {0.0f, 0.0f, 1.0f});
|
||||
mProjectionMatrixRotated =
|
||||
glm::translate(projection, {sScreenWidth * -1.0f, sScreenHeight * -1.0f, 0.0f});
|
||||
|
||||
viewport.x = mScreenOffsetX;
|
||||
viewport.y = mScreenOffsetY;
|
||||
viewport.w = sScreenWidth;
|
||||
viewport.h = sScreenHeight;
|
||||
mProjectionMatrix = glm::ortho(0.0f, static_cast<float>(sScreenWidth),
|
||||
static_cast<float>(sScreenHeight), 0.0f, -1.0f, 1.0f);
|
||||
|
||||
// This is required to avoid a brief white screen flash during startup on some systems.
|
||||
drawRect(0.0f, 0.0f, static_cast<float>(getScreenWidth()),
|
||||
static_cast<float>(getScreenHeight()), 0x000000FF, 0x000000FF);
|
||||
swapBuffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::deinit()
|
||||
{
|
||||
// Destroy the window.
|
||||
destroyWindow();
|
||||
}
|
||||
|
||||
void Renderer::pushClipRect(const glm::ivec2& pos, const glm::ivec2& size)
|
||||
{
|
||||
Rect box {pos.x, pos.y, size.x, size.y};
|
||||
|
||||
if (box.w == 0)
|
||||
box.w = sScreenWidth - box.x;
|
||||
if (box.h == 0)
|
||||
box.h = sScreenHeight - box.y;
|
||||
|
||||
if (mScreenRotated) {
|
||||
box = Rect(mWindowWidth - mScreenOffsetX - box.x - box.w,
|
||||
mWindowHeight - mScreenOffsetY - box.y - box.h, box.w, box.h);
|
||||
}
|
||||
else {
|
||||
box = Rect(mScreenOffsetX + box.x, mScreenOffsetY + box.y, box.w, box.h);
|
||||
}
|
||||
|
||||
static void destroyWindow()
|
||||
{
|
||||
for (auto it = sShaderProgramVector.cbegin(); it != sShaderProgramVector.cend(); ++it)
|
||||
delete *it;
|
||||
|
||||
destroyContext();
|
||||
SDL_DestroyWindow(sdlWindow);
|
||||
|
||||
sdlWindow = nullptr;
|
||||
|
||||
SDL_ShowCursor(initialCursorState);
|
||||
SDL_Quit();
|
||||
// Make sure the box fits within mClipStack.top(), and clip further accordingly.
|
||||
if (mClipStack.size()) {
|
||||
const Rect& top {mClipStack.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;
|
||||
}
|
||||
|
||||
bool init()
|
||||
{
|
||||
if (!createWindow())
|
||||
return false;
|
||||
if (box.w < 0)
|
||||
box.w = 0;
|
||||
if (box.h < 0)
|
||||
box.h = 0;
|
||||
|
||||
glm::mat4 projection {getIdentity()};
|
||||
Rect viewport {0, 0, 0, 0};
|
||||
mClipStack.push(box);
|
||||
|
||||
viewport.x = windowWidth - screenOffsetX - screenWidth;
|
||||
viewport.y = windowHeight - screenOffsetY - screenHeight;
|
||||
viewport.w = screenWidth;
|
||||
viewport.h = screenHeight;
|
||||
projection = glm::ortho(0.0f, static_cast<float>(screenWidth),
|
||||
static_cast<float>(screenHeight), 0.0f, -1.0f, 1.0f);
|
||||
projection = glm::rotate(projection, glm::radians(180.0f), {0.0f, 0.0f, 1.0f});
|
||||
mProjectionMatrixRotated =
|
||||
glm::translate(projection, {screenWidth * -1.0f, screenHeight * -1.0f, 0.0f});
|
||||
setScissor(box);
|
||||
}
|
||||
|
||||
viewport.x = screenOffsetX;
|
||||
viewport.y = screenOffsetY;
|
||||
viewport.w = screenWidth;
|
||||
viewport.h = screenHeight;
|
||||
mProjectionMatrix = glm::ortho(0.0f, static_cast<float>(screenWidth),
|
||||
static_cast<float>(screenHeight), 0.0f, -1.0f, 1.0f);
|
||||
|
||||
// This is required to avoid a brief white screen flash during startup on some systems.
|
||||
Renderer::drawRect(0.0f, 0.0f, static_cast<float>(Renderer::getScreenWidth()),
|
||||
static_cast<float>(Renderer::getScreenHeight()), 0x000000FF, 0x000000FF);
|
||||
swapBuffers();
|
||||
|
||||
return true;
|
||||
void Renderer::popClipRect()
|
||||
{
|
||||
if (mClipStack.empty()) {
|
||||
LOG(LogError) << "Tried to popClipRect while the stack was empty";
|
||||
return;
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
// Destroy the window.
|
||||
destroyWindow();
|
||||
}
|
||||
mClipStack.pop();
|
||||
|
||||
void pushClipRect(const glm::ivec2& pos, const glm::ivec2& size)
|
||||
{
|
||||
Rect box(pos.x, pos.y, size.x, size.y);
|
||||
if (mClipStack.empty())
|
||||
setScissor(Rect(0, 0, 0, 0));
|
||||
else
|
||||
setScissor(mClipStack.top());
|
||||
}
|
||||
|
||||
if (box.w == 0)
|
||||
box.w = screenWidth - box.x;
|
||||
if (box.h == 0)
|
||||
box.h = screenHeight - box.y;
|
||||
void Renderer::drawRect(const float x,
|
||||
const float y,
|
||||
const float w,
|
||||
const float h,
|
||||
const unsigned int color,
|
||||
const unsigned int colorEnd,
|
||||
bool horizontalGradient,
|
||||
const float opacity,
|
||||
const float dimming,
|
||||
const BlendFactor srcBlendFactorFactor,
|
||||
const BlendFactor dstBlendFactorFactor)
|
||||
{
|
||||
Vertex vertices[4];
|
||||
|
||||
if (screenRotated) {
|
||||
box = Rect(windowWidth - screenOffsetX - box.x - box.w,
|
||||
windowHeight - screenOffsetY - box.y - box.h, box.w, box.h);
|
||||
}
|
||||
else {
|
||||
box = Rect(screenOffsetX + box.x, screenOffsetY + box.y, box.w, box.h);
|
||||
}
|
||||
float wL {w};
|
||||
float hL {h};
|
||||
|
||||
// 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 the width or height was scaled down to less than 1 pixel, then set it to
|
||||
// 1 pixel so that it will still render on lower resolutions.
|
||||
if (wL > 0.0f && wL < 1.0f)
|
||||
wL = 1.0f;
|
||||
if (hL > 0.0f && hL < 1.0f)
|
||||
hL = 1.0f;
|
||||
|
||||
if (box.w < 0)
|
||||
box.w = 0;
|
||||
if (box.h < 0)
|
||||
box.h = 0;
|
||||
// clang-format off
|
||||
vertices[0] = {{x, y }, {0.0f, 0.0f}, color};
|
||||
vertices[1] = {{x, y + hL}, {0.0f, 0.0f}, horizontalGradient ? color : colorEnd};
|
||||
vertices[2] = {{x + wL, y }, {0.0f, 0.0f}, horizontalGradient ? colorEnd : color};
|
||||
vertices[3] = {{x + wL, y + hL}, {0.0f, 0.0f}, colorEnd};
|
||||
// clang-format on
|
||||
|
||||
clipStack.push(box);
|
||||
// Round vertices.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
vertices[i].position = glm::round(vertices[i].position);
|
||||
|
||||
setScissor(box);
|
||||
}
|
||||
vertices->opacity = opacity;
|
||||
vertices->dimming = dimming;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void drawRect(const float x,
|
||||
const float y,
|
||||
const float w,
|
||||
const float h,
|
||||
const unsigned int color,
|
||||
const unsigned int colorEnd,
|
||||
bool horizontalGradient,
|
||||
const float opacity,
|
||||
const float dimming,
|
||||
const Blend::Factor srcBlendFactor,
|
||||
const Blend::Factor dstBlendFactor)
|
||||
{
|
||||
Vertex vertices[4];
|
||||
|
||||
float wL {w};
|
||||
float hL {h};
|
||||
|
||||
// If the width or height was scaled down to less than 1 pixel, then set it to
|
||||
// 1 pixel so that it will still render on lower resolutions.
|
||||
if (wL > 0.0f && wL < 1.0f)
|
||||
wL = 1.0f;
|
||||
if (hL > 0.0f && hL < 1.0f)
|
||||
hL = 1.0f;
|
||||
|
||||
// clang-format off
|
||||
vertices[0] = {{x, y }, {0.0f, 0.0f}, color};
|
||||
vertices[1] = {{x, y + hL}, {0.0f, 0.0f}, horizontalGradient ? color : colorEnd};
|
||||
vertices[2] = {{x + wL, y }, {0.0f, 0.0f}, horizontalGradient ? colorEnd : color};
|
||||
vertices[3] = {{x + wL, y + hL}, {0.0f, 0.0f}, colorEnd};
|
||||
// clang-format on
|
||||
|
||||
// Round vertices.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
vertices[i].position = glm::round(vertices[i].position);
|
||||
|
||||
vertices->opacity = opacity;
|
||||
vertices->dimming = dimming;
|
||||
|
||||
bindTexture(0);
|
||||
drawTriangleStrips(vertices, 4, srcBlendFactor, dstBlendFactor);
|
||||
}
|
||||
|
||||
Shader* getShaderProgram(unsigned int shaderID)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
|
||||
// Find the index in sShaderProgramVector by counting the number
|
||||
// of shifts required to reach 0.
|
||||
while (shaderID > 0) {
|
||||
shaderID = shaderID >> 1;
|
||||
++index;
|
||||
}
|
||||
|
||||
if (sShaderProgramVector.size() > index - 1)
|
||||
return sShaderProgramVector[index - 1];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const glm::mat4& getProjectionMatrix()
|
||||
{
|
||||
if (screenRotated)
|
||||
return mProjectionMatrixRotated;
|
||||
else
|
||||
return mProjectionMatrix;
|
||||
}
|
||||
const glm::mat4& getProjectionMatrixNormal() { return mProjectionMatrix; }
|
||||
SDL_Window* getSDLWindow() { return sdlWindow; }
|
||||
const float getWindowWidth() { return static_cast<float>(windowWidth); }
|
||||
const float getWindowHeight() { return static_cast<float>(windowHeight); }
|
||||
const float getScreenWidth() { return static_cast<float>(screenWidth); }
|
||||
const float getScreenHeight() { return static_cast<float>(screenHeight); }
|
||||
const float getScreenOffsetX() { return static_cast<float>(screenOffsetX); }
|
||||
const float getScreenOffsetY() { return static_cast<float>(screenOffsetY); }
|
||||
const bool getScreenRotated() { return screenRotated; }
|
||||
const float getScreenWidthModifier() { return screenWidthModifier; }
|
||||
const float getScreenHeightModifier() { return screenHeightModifier; }
|
||||
const float getScreenAspectRatio() { return screenAspectRatio; }
|
||||
|
||||
} // namespace Renderer
|
||||
bindTexture(0);
|
||||
drawTriangleStrips(vertices, 4, srcBlendFactorFactor, dstBlendFactorFactor);
|
||||
}
|
||||
|
|
|
@ -3,123 +3,25 @@
|
|||
// EmulationStation Desktop Edition
|
||||
// Renderer.h
|
||||
//
|
||||
// General rendering functions.
|
||||
// Generic rendering functions.
|
||||
//
|
||||
|
||||
#ifndef ES_CORE_RENDERER_RENDERER_H
|
||||
#define ES_CORE_RENDERER_RENDERER_H
|
||||
|
||||
#include "Log.h"
|
||||
#include "Shader_GL21.h"
|
||||
#include "utils/MathUtil.h"
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct SDL_Window;
|
||||
class Shader;
|
||||
|
||||
namespace Renderer
|
||||
class Renderer
|
||||
{
|
||||
// clang-format off
|
||||
const unsigned int SHADER_CORE {0x00000001};
|
||||
const unsigned int SHADER_BLUR_HORIZONTAL {0x00000002};
|
||||
const unsigned int SHADER_BLUR_VERTICAL {0x00000004};
|
||||
const unsigned int SHADER_SCANLINES {0x00000008};
|
||||
// clang-format on
|
||||
|
||||
struct postProcessingParams {
|
||||
float opacity;
|
||||
float saturation;
|
||||
float dimming;
|
||||
bool convertBGRAToRGBA;
|
||||
unsigned int blurPasses;
|
||||
unsigned int shaders;
|
||||
|
||||
postProcessingParams()
|
||||
: opacity {1.0f}
|
||||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, convertBGRAToRGBA {false}
|
||||
, blurPasses {1}
|
||||
, shaders {0}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<Shader*> sShaderProgramVector;
|
||||
static GLuint shaderFBO1 {0};
|
||||
static GLuint shaderFBO2 {0};
|
||||
static GLuint vertexBuffer1 {0};
|
||||
static GLuint vertexBuffer2 {0};
|
||||
// This is simply to get rid of some GCC false positive -Wunused-variable compiler warnings.
|
||||
static GLuint shaderFBODummy1 {shaderFBO1};
|
||||
static GLuint shaderFBODummy2 {shaderFBO2};
|
||||
static GLuint vertexBufferDummy1 {vertexBuffer1};
|
||||
static GLuint vertexBufferDummy2 {vertexBuffer2};
|
||||
|
||||
static constexpr glm::mat4 getIdentity() { return glm::mat4 {1.0f}; }
|
||||
static inline glm::mat4 mTrans {getIdentity()};
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define GL_CHECK_ERROR(Function) (Function, _GLCheckError(#Function))
|
||||
|
||||
static inline void _GLCheckError(const std::string& _funcName)
|
||||
{
|
||||
const GLenum errorCode = glGetError();
|
||||
|
||||
if (errorCode != GL_NO_ERROR) {
|
||||
#if defined(USE_OPENGLES)
|
||||
LOG(LogError) << "OpenGL ES error: " << _funcName << " failed with error code: 0x"
|
||||
<< std::hex << errorCode;
|
||||
#else
|
||||
LOG(LogError) << "OpenGL error: " << _funcName << " failed with error code: 0x"
|
||||
<< std::hex << errorCode;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define GL_CHECK_ERROR(Function) (Function)
|
||||
#endif
|
||||
|
||||
namespace Blend
|
||||
{
|
||||
enum Factor {
|
||||
ZERO,
|
||||
ONE,
|
||||
SRC_COLOR,
|
||||
ONE_MINUS_SRC_COLOR,
|
||||
SRC_ALPHA,
|
||||
ONE_MINUS_SRC_ALPHA,
|
||||
DST_COLOR,
|
||||
ONE_MINUS_DST_COLOR,
|
||||
DST_ALPHA,
|
||||
ONE_MINUS_DST_ALPHA
|
||||
};
|
||||
}
|
||||
|
||||
namespace Texture
|
||||
{
|
||||
enum Type {
|
||||
RGBA, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
|
||||
BGRA,
|
||||
RED
|
||||
};
|
||||
}
|
||||
|
||||
struct Rect {
|
||||
Rect(const int xValue, const int yValue, const int wValue, const int hValue)
|
||||
: x(xValue)
|
||||
, y(yValue)
|
||||
, w(wValue)
|
||||
, h(hValue)
|
||||
{
|
||||
}
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
public:
|
||||
struct Vertex {
|
||||
glm::vec2 position;
|
||||
glm::vec2 texture;
|
||||
|
@ -142,6 +44,7 @@ namespace Renderer
|
|||
, shaders {0}
|
||||
{
|
||||
}
|
||||
|
||||
Vertex(const glm::vec2& position, const glm::vec2& textureCoord, const unsigned int color)
|
||||
: position(position)
|
||||
, texture(textureCoord)
|
||||
|
@ -157,10 +60,71 @@ namespace Renderer
|
|||
}
|
||||
};
|
||||
|
||||
enum class BlendFactor {
|
||||
ZERO,
|
||||
ONE,
|
||||
SRC_COLOR,
|
||||
ONE_MINUS_SRC_COLOR,
|
||||
SRC_ALPHA,
|
||||
ONE_MINUS_SRC_ALPHA,
|
||||
DST_COLOR,
|
||||
ONE_MINUS_DST_COLOR,
|
||||
DST_ALPHA,
|
||||
ONE_MINUS_DST_ALPHA
|
||||
};
|
||||
|
||||
enum class TextureType {
|
||||
RGBA, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
|
||||
BGRA,
|
||||
RED
|
||||
};
|
||||
|
||||
struct postProcessingParams {
|
||||
float opacity;
|
||||
float saturation;
|
||||
float dimming;
|
||||
bool convertBGRAToRGBA;
|
||||
unsigned int blurPasses;
|
||||
unsigned int shaders;
|
||||
|
||||
postProcessingParams()
|
||||
: opacity {1.0f}
|
||||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, convertBGRAToRGBA {false}
|
||||
, blurPasses {1}
|
||||
, shaders {0}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
Rect(const int xValue, const int yValue, const int wValue, const int hValue)
|
||||
: x(xValue)
|
||||
, y(yValue)
|
||||
, w(wValue)
|
||||
, h(hValue)
|
||||
{
|
||||
}
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
static Renderer* getInstance();
|
||||
|
||||
void setIcon();
|
||||
bool createWindow();
|
||||
void destroyWindow();
|
||||
bool init();
|
||||
void deinit();
|
||||
|
||||
virtual bool loadShaders() = 0;
|
||||
|
||||
void pushClipRect(const glm::ivec2& pos, const glm::ivec2& size);
|
||||
void popClipRect();
|
||||
|
||||
void drawRect(const float x,
|
||||
const float y,
|
||||
const float w,
|
||||
|
@ -170,56 +134,87 @@ namespace Renderer
|
|||
bool horizontalGradient = false,
|
||||
const float opacity = 1.0,
|
||||
const float dimming = 1.0,
|
||||
const Blend::Factor srcBlendFactor = Blend::SRC_ALPHA,
|
||||
const Blend::Factor dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA);
|
||||
SDL_Window* getSDLWindow();
|
||||
const float getWindowWidth();
|
||||
const float getWindowHeight();
|
||||
const float getScreenWidth();
|
||||
const float getScreenHeight();
|
||||
const float getScreenOffsetX();
|
||||
const float getScreenOffsetY();
|
||||
const bool getScreenRotated();
|
||||
const float getScreenWidthModifier();
|
||||
const float getScreenHeightModifier();
|
||||
const float getScreenAspectRatio();
|
||||
const BlendFactor srcBlendFactor = BlendFactor::SRC_ALPHA,
|
||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
Shader* getShaderProgram(unsigned int shaderID);
|
||||
const glm::mat4& getProjectionMatrix();
|
||||
const glm::mat4& getProjectionMatrixNormal();
|
||||
void shaderPostprocessing(
|
||||
const glm::mat4& getProjectionMatrix()
|
||||
{
|
||||
if (mScreenRotated)
|
||||
return mProjectionMatrixRotated;
|
||||
else
|
||||
return mProjectionMatrix;
|
||||
}
|
||||
const glm::mat4& getProjectionMatrixNormal() { return mProjectionMatrix; }
|
||||
SDL_Window* getSDLWindow() { return mSDLWindow; }
|
||||
const bool getScreenRotated() { return mScreenRotated; }
|
||||
const float getWindowWidth() { return static_cast<float>(mWindowWidth); }
|
||||
const float getWindowHeight() { return static_cast<float>(mWindowHeight); }
|
||||
static const float getScreenWidth() { return static_cast<float>(sScreenWidth); }
|
||||
static const float getScreenHeight() { return static_cast<float>(sScreenHeight); }
|
||||
static const float getScreenWidthModifier() { return sScreenWidthModifier; }
|
||||
static const float getScreenHeightModifier() { return sScreenHeightModifier; }
|
||||
static const float getScreenAspectRatio() { return sScreenAspectRatio; }
|
||||
|
||||
static constexpr glm::mat4 getIdentity() { return glm::mat4 {1.0f}; }
|
||||
glm::mat4 mTrans {getIdentity()};
|
||||
|
||||
virtual void shaderPostprocessing(
|
||||
const unsigned int shaders,
|
||||
const Renderer::postProcessingParams& parameters = postProcessingParams(),
|
||||
unsigned char* textureRGBA = nullptr);
|
||||
unsigned char* textureRGBA = nullptr) = 0;
|
||||
|
||||
void setupWindow();
|
||||
bool createContext();
|
||||
void destroyContext();
|
||||
unsigned int createTexture(const Texture::Type type,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
virtual void setup() = 0;
|
||||
virtual bool createContext() = 0;
|
||||
virtual void destroyContext() = 0;
|
||||
virtual unsigned int createTexture(const TextureType type,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
const unsigned int width,
|
||||
const unsigned int height,
|
||||
void* data) = 0;
|
||||
virtual void destroyTexture(const unsigned int texture) = 0;
|
||||
virtual void updateTexture(const unsigned int texture,
|
||||
const TextureType type,
|
||||
const unsigned int x,
|
||||
const unsigned int y,
|
||||
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 int y,
|
||||
const unsigned int width,
|
||||
const unsigned int height,
|
||||
void* data);
|
||||
void bindTexture(const unsigned int texture);
|
||||
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 setMatrix(const glm::mat4& matrix);
|
||||
void setScissor(const Rect& scissor);
|
||||
void setSwapInterval();
|
||||
void swapBuffers();
|
||||
void* data) = 0;
|
||||
virtual void bindTexture(const unsigned int texture) = 0;
|
||||
virtual void drawTriangleStrips(
|
||||
const Vertex* vertices,
|
||||
const unsigned int numVertices,
|
||||
const BlendFactor srcBlendFactor = BlendFactor::SRC_ALPHA,
|
||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0;
|
||||
virtual void setMatrix(const glm::mat4& matrix) = 0;
|
||||
virtual void setScissor(const Rect& scissor) = 0;
|
||||
virtual void setSwapInterval() = 0;
|
||||
virtual void swapBuffers() = 0;
|
||||
|
||||
} // namespace Renderer
|
||||
// clang-format off
|
||||
static constexpr unsigned int SHADER_CORE {0x00000001};
|
||||
static constexpr unsigned int SHADER_BLUR_HORIZONTAL {0x00000002};
|
||||
static constexpr unsigned int SHADER_BLUR_VERTICAL {0x00000004};
|
||||
static constexpr unsigned int SHADER_SCANLINES {0x00000008};
|
||||
// clang-format on
|
||||
|
||||
std::stack<Rect> mClipStack;
|
||||
SDL_Window* mSDLWindow {nullptr};
|
||||
glm::mat4 mProjectionMatrix {};
|
||||
glm::mat4 mProjectionMatrixRotated {};
|
||||
int mWindowWidth {0};
|
||||
int mWindowHeight {0};
|
||||
static inline int sScreenWidth {0};
|
||||
static inline int sScreenHeight {0};
|
||||
int mScreenOffsetX {0};
|
||||
int mScreenOffsetY {0};
|
||||
bool mScreenRotated {0};
|
||||
bool mInitialCursorState {1};
|
||||
// Screen resolution modifiers relative to the 1920x1080 reference.
|
||||
static inline float sScreenHeightModifier {0.0f};
|
||||
static inline float sScreenWidthModifier {0.0f};
|
||||
static inline float sScreenAspectRatio {0.0f};
|
||||
};
|
||||
|
||||
#endif // ES_CORE_RENDERER_RENDERER_H
|
||||
|
|
File diff suppressed because it is too large
Load diff
92
es-core/src/renderers/Renderer_GL21.h
Normal file
92
es-core/src/renderers/Renderer_GL21.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// EmulationStation Desktop Edition
|
||||
// Renderer_GL21.h
|
||||
//
|
||||
// OpenGL / OpenGL ES renderering functions.
|
||||
//
|
||||
|
||||
#ifndef ES_CORE_RENDERER_RENDERER_GL21_H
|
||||
#define ES_CORE_RENDERER_RENDERER_GL21_H
|
||||
|
||||
#include "Shader_GL21.h"
|
||||
#include "renderers/Renderer.h"
|
||||
|
||||
#if defined(USE_OPENGLES)
|
||||
#include <GLES3/gl3.h>
|
||||
#include <SDL2/SDL_opengles.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
class RendererOpenGL : public Renderer
|
||||
{
|
||||
public:
|
||||
RendererOpenGL() noexcept;
|
||||
~RendererOpenGL();
|
||||
|
||||
static RendererOpenGL* getInstance();
|
||||
|
||||
Shader* getShaderProgram(unsigned int shaderID);
|
||||
bool loadShaders() override;
|
||||
|
||||
GLenum convertBlendFactor(const BlendFactor BlendFactorFactor);
|
||||
GLenum convertTextureType(const TextureType type);
|
||||
|
||||
void setup() override;
|
||||
bool createContext() override;
|
||||
void destroyContext() override;
|
||||
|
||||
void setMatrix(const glm::mat4& matrix) override;
|
||||
void setScissor(const Rect& scissor) override;
|
||||
void setSwapInterval() override;
|
||||
void swapBuffers() override;
|
||||
|
||||
unsigned int createTexture(const TextureType type,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
const unsigned int width,
|
||||
const unsigned int height,
|
||||
void* data) override;
|
||||
void destroyTexture(const unsigned int texture) override;
|
||||
void updateTexture(const unsigned int texture,
|
||||
const TextureType type,
|
||||
const unsigned int x,
|
||||
const unsigned int y,
|
||||
const unsigned int width,
|
||||
const unsigned int height,
|
||||
void* data) override;
|
||||
void bindTexture(const unsigned int texture) override;
|
||||
|
||||
void drawTriangleStrips(
|
||||
const Vertex* vertices,
|
||||
const unsigned int numVertices,
|
||||
const BlendFactor srcBlendFactor = BlendFactor::SRC_ALPHA,
|
||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) override;
|
||||
|
||||
void shaderPostprocessing(
|
||||
const unsigned int shaders,
|
||||
const Renderer::postProcessingParams& parameters = postProcessingParams(),
|
||||
unsigned char* textureRGBA = nullptr) override;
|
||||
|
||||
private:
|
||||
std::vector<Shader*> mShaderProgramVector;
|
||||
GLuint mShaderFBO1;
|
||||
GLuint mShaderFBO2;
|
||||
GLuint mVertexBuffer1;
|
||||
GLuint mVertexBuffer2;
|
||||
|
||||
SDL_GLContext mSDLContext;
|
||||
GLuint mWhiteTexture;
|
||||
GLuint mPostProcTexture1;
|
||||
GLuint mPostProcTexture2;
|
||||
Shader* mCoreShader;
|
||||
Shader* mBlurHorizontalShader;
|
||||
Shader* mBlurVerticalShader;
|
||||
Shader* mScanlinelShader;
|
||||
Shader* mLastShader;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_RENDERER_RENDERER_GL21_H
|
|
@ -12,254 +12,246 @@
|
|||
#include "renderers/Renderer.h"
|
||||
#include "resources/ResourceManager.h"
|
||||
|
||||
namespace Renderer
|
||||
Shader::Shader()
|
||||
: mProgramID {0}
|
||||
, mShaderMVPMatrix {0}
|
||||
, mShaderPosition {0}
|
||||
, mShaderTextureCoord {0}
|
||||
, mShaderColor {0}
|
||||
, mShaderTextureSize {0}
|
||||
, mShaderOpacity {0}
|
||||
, mShaderSaturation {0}
|
||||
, mShaderDimming {0}
|
||||
, mShaderBGRAToRGBA {0}
|
||||
, mShaderFont {0}
|
||||
, mShaderPostProcessing {0}
|
||||
{
|
||||
Renderer::Shader::Shader()
|
||||
: mProgramID {0}
|
||||
, shaderMVPMatrix {0}
|
||||
, shaderPosition {0}
|
||||
, shaderTextureCoord {0}
|
||||
, shaderColor {0}
|
||||
, shaderTextureSize {0}
|
||||
, shaderOpacity {0}
|
||||
, shaderSaturation {0}
|
||||
, shaderDimming {0}
|
||||
, shaderBGRAToRGBA {0}
|
||||
, shaderFont {0}
|
||||
, shaderPostProcessing {0}
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Shader::~Shader()
|
||||
{
|
||||
// Delete the shader program when destroyed.
|
||||
deleteProgram(mProgramID);
|
||||
}
|
||||
Shader::~Shader()
|
||||
{
|
||||
// Delete the shader program when destroyed.
|
||||
deleteProgram(mProgramID);
|
||||
}
|
||||
|
||||
void Renderer::Shader::loadShaderFile(const std::string& path, GLenum shaderType)
|
||||
{
|
||||
std::string preprocessorDefines;
|
||||
std::string shaderCode;
|
||||
void Shader::loadShaderFile(const std::string& path, GLenum shaderType)
|
||||
{
|
||||
std::string preprocessorDefines;
|
||||
std::string shaderCode;
|
||||
|
||||
// This will load the entire GLSL source code into the string variable.
|
||||
const ResourceData& shaderData {ResourceManager::getInstance().getFileData(path)};
|
||||
shaderCode.assign(reinterpret_cast<const char*>(shaderData.ptr.get()), shaderData.length);
|
||||
// This will load the entire GLSL source code into the string variable.
|
||||
const ResourceData& shaderData {ResourceManager::getInstance().getFileData(path)};
|
||||
shaderCode.assign(reinterpret_cast<const char*>(shaderData.ptr.get()), shaderData.length);
|
||||
|
||||
// Define the GLSL version.
|
||||
// Define the GLSL version.
|
||||
#if defined(USE_OPENGLES)
|
||||
preprocessorDefines = "#version 300 es\n";
|
||||
preprocessorDefines = "#version 300 es\n";
|
||||
#else
|
||||
preprocessorDefines = "#version 330\n";
|
||||
preprocessorDefines = "#version 330\n";
|
||||
#endif
|
||||
// Define the preprocessor constants that will let the shader compiler know whether
|
||||
// the VERTEX or FRAGMENT portion of the code should be used.
|
||||
if (shaderType == GL_VERTEX_SHADER)
|
||||
preprocessorDefines += "#define VERTEX\n";
|
||||
else if (shaderType == GL_FRAGMENT_SHADER)
|
||||
preprocessorDefines += "#define FRAGMENT\n";
|
||||
// Define the preprocessor constants that will let the shader compiler know whether
|
||||
// the VERTEX or FRAGMENT portion of the code should be used.
|
||||
if (shaderType == GL_VERTEX_SHADER)
|
||||
preprocessorDefines += "#define VERTEX\n";
|
||||
else if (shaderType == GL_FRAGMENT_SHADER)
|
||||
preprocessorDefines += "#define FRAGMENT\n";
|
||||
|
||||
shaderVector.push_back(std::make_tuple(path, preprocessorDefines + shaderCode, shaderType));
|
||||
}
|
||||
mShaderVector.push_back(std::make_tuple(path, preprocessorDefines + shaderCode, shaderType));
|
||||
}
|
||||
|
||||
bool Renderer::Shader::createProgram()
|
||||
{
|
||||
GLint programSuccess;
|
||||
bool Shader::createProgram()
|
||||
{
|
||||
GLint programSuccess;
|
||||
|
||||
mProgramID = glCreateProgram();
|
||||
mProgramID = glCreateProgram();
|
||||
|
||||
// Compile and attach all shaders that have been loaded.
|
||||
for (auto it = shaderVector.cbegin(); it != shaderVector.cend(); ++it) {
|
||||
GLuint currentShader = glCreateShader(std::get<2>(*it));
|
||||
GLchar const* shaderCodePtr = std::get<1>(*it).c_str();
|
||||
// Compile and attach all shaders that have been loaded.
|
||||
for (auto it = mShaderVector.cbegin(); it != mShaderVector.cend(); ++it) {
|
||||
GLuint currentShader {glCreateShader(std::get<2>(*it))};
|
||||
GLchar const* shaderCodePtr {std::get<1>(*it).c_str()};
|
||||
|
||||
glShaderSource(currentShader, 1, reinterpret_cast<const GLchar**>(&shaderCodePtr),
|
||||
nullptr);
|
||||
glCompileShader(currentShader);
|
||||
glShaderSource(currentShader, 1, reinterpret_cast<const GLchar**>(&shaderCodePtr), nullptr);
|
||||
glCompileShader(currentShader);
|
||||
|
||||
GLint shaderCompiled;
|
||||
glGetShaderiv(currentShader, GL_COMPILE_STATUS, &shaderCompiled);
|
||||
GLint shaderCompiled;
|
||||
glGetShaderiv(currentShader, GL_COMPILE_STATUS, &shaderCompiled);
|
||||
|
||||
if (shaderCompiled != GL_TRUE) {
|
||||
LOG(LogError) << "OpenGL error: Unable to compile shader " << currentShader << " ("
|
||||
<< std::get<0>(*it) << ").";
|
||||
printShaderInfoLog(currentShader, std::get<2>(*it), true);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
printShaderInfoLog(currentShader, std::get<2>(*it), false);
|
||||
}
|
||||
|
||||
GL_CHECK_ERROR(glAttachShader(mProgramID, currentShader));
|
||||
}
|
||||
|
||||
glLinkProgram(mProgramID);
|
||||
|
||||
glGetProgramiv(mProgramID, GL_LINK_STATUS, &programSuccess);
|
||||
if (programSuccess != GL_TRUE) {
|
||||
LOG(LogError) << "OpenGL error: Unable to link program " << mProgramID << ".";
|
||||
printProgramInfoLog(mProgramID);
|
||||
if (shaderCompiled != GL_TRUE) {
|
||||
LOG(LogError) << "OpenGL error: Unable to compile shader " << currentShader << " ("
|
||||
<< std::get<0>(*it) << ").";
|
||||
printShaderInfoLog(currentShader, std::get<2>(*it), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
getVariableLocations(mProgramID);
|
||||
|
||||
if (shaderPosition != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderPosition));
|
||||
|
||||
if (shaderTextureCoord != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderTextureCoord));
|
||||
|
||||
if (shaderColor != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderColor));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::Shader::deleteProgram(GLuint programID)
|
||||
{
|
||||
GL_CHECK_ERROR(glDeleteProgram(programID));
|
||||
}
|
||||
|
||||
void Renderer::Shader::getVariableLocations(GLuint programID)
|
||||
{
|
||||
// Some of the variable names are chosen to be compatible with the RetroArch GLSL shaders.
|
||||
shaderMVPMatrix = glGetUniformLocation(mProgramID, "MVPMatrix");
|
||||
shaderPosition = glGetAttribLocation(mProgramID, "positionAttrib");
|
||||
shaderTextureCoord = glGetAttribLocation(mProgramID, "TexCoord");
|
||||
shaderColor = glGetAttribLocation(mProgramID, "colorAttrib");
|
||||
shaderTextureSize = glGetUniformLocation(mProgramID, "TextureSize");
|
||||
shaderOpacity = glGetUniformLocation(mProgramID, "opacity");
|
||||
shaderSaturation = glGetUniformLocation(mProgramID, "saturation");
|
||||
shaderDimming = glGetUniformLocation(mProgramID, "dimming");
|
||||
shaderBGRAToRGBA = glGetUniformLocation(mProgramID, "BGRAToRGBA");
|
||||
shaderFont = glGetUniformLocation(mProgramID, "font");
|
||||
shaderPostProcessing = glGetUniformLocation(mProgramID, "postProcessing");
|
||||
}
|
||||
|
||||
void Renderer::Shader::setModelViewProjectionMatrix(glm::mat4 mvpMatrix)
|
||||
{
|
||||
if (shaderMVPMatrix != GL_INVALID_VALUE && shaderMVPMatrix != GL_INVALID_OPERATION)
|
||||
GL_CHECK_ERROR(glUniformMatrix4fv(shaderMVPMatrix, 1, GL_FALSE,
|
||||
reinterpret_cast<GLfloat*>(&mvpMatrix)));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setAttribPointers()
|
||||
{
|
||||
if (shaderPosition != -1)
|
||||
GL_CHECK_ERROR(
|
||||
glVertexAttribPointer(shaderPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Vertex, position))));
|
||||
if (shaderTextureCoord != -1)
|
||||
GL_CHECK_ERROR(
|
||||
glVertexAttribPointer(shaderTextureCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Vertex, texture))));
|
||||
|
||||
if (shaderColor != -1)
|
||||
GL_CHECK_ERROR(
|
||||
glVertexAttribPointer(shaderColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Vertex, color))));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setTextureSize(std::array<GLfloat, 2> shaderVec2)
|
||||
{
|
||||
if (shaderTextureSize != -1)
|
||||
GL_CHECK_ERROR(glUniform2f(shaderTextureSize, shaderVec2[0], shaderVec2[1]));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setOpacity(GLfloat opacity)
|
||||
{
|
||||
if (shaderOpacity != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(shaderOpacity, opacity));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setSaturation(GLfloat saturation)
|
||||
{
|
||||
if (shaderSaturation != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(shaderSaturation, saturation));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setDimming(GLfloat dimming)
|
||||
{
|
||||
if (shaderDimming != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(shaderDimming, dimming));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setBGRAToRGBA(GLboolean BGRAToRGBA)
|
||||
{
|
||||
if (shaderBGRAToRGBA != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(shaderBGRAToRGBA, BGRAToRGBA ? 1 : 0));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setFont(GLboolean font)
|
||||
{
|
||||
if (shaderFont != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(shaderFont, font ? 1 : 0));
|
||||
}
|
||||
|
||||
void Renderer::Shader::setPostProcessing(GLboolean postProcessing)
|
||||
{
|
||||
if (shaderPostProcessing != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(shaderPostProcessing, postProcessing ? 1 : 0));
|
||||
}
|
||||
|
||||
void Renderer::Shader::activateShaders()
|
||||
{
|
||||
// Install the shader program.
|
||||
GL_CHECK_ERROR(glUseProgram(mProgramID));
|
||||
}
|
||||
|
||||
void Renderer::Shader::deactivateShaders()
|
||||
{
|
||||
// Remove the shader program.
|
||||
GL_CHECK_ERROR(glUseProgram(0));
|
||||
}
|
||||
|
||||
void Renderer::Shader::printProgramInfoLog(GLuint programID)
|
||||
{
|
||||
if (glIsProgram(programID)) {
|
||||
int logLength;
|
||||
int maxLength;
|
||||
|
||||
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
std::vector<char> infoLog(maxLength);
|
||||
|
||||
glGetProgramInfoLog(programID, maxLength, &logLength, &infoLog.front());
|
||||
|
||||
if (logLength > 0) {
|
||||
LOG(LogDebug) << "Renderer_GL21::printProgramInfoLog():\n"
|
||||
<< std::string(infoLog.begin(), infoLog.end());
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "OpenGL error: " << programID << " is not a program.";
|
||||
printShaderInfoLog(currentShader, std::get<2>(*it), false);
|
||||
}
|
||||
|
||||
GL_CHECK_ERROR(glAttachShader(mProgramID, currentShader));
|
||||
}
|
||||
|
||||
void Renderer::Shader::printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error)
|
||||
{
|
||||
if (glIsShader(shaderID)) {
|
||||
int logLength;
|
||||
int maxLength;
|
||||
glLinkProgram(mProgramID);
|
||||
|
||||
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
std::vector<char> infoLog(maxLength);
|
||||
|
||||
if (infoLog.size() == 0)
|
||||
return;
|
||||
|
||||
glGetShaderInfoLog(shaderID, maxLength, &logLength, &infoLog.front());
|
||||
|
||||
if (logLength > 0) {
|
||||
LOG(LogDebug) << "Shader_GL21::printShaderInfoLog(): "
|
||||
<< (error ? "Error" : "Warning") << " in "
|
||||
<< (shaderType == GL_VERTEX_SHADER ? "VERTEX section:\n" :
|
||||
"FRAGMENT section:\n")
|
||||
<< std::string(infoLog.begin(), infoLog.end());
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "OpenGL error: " << shaderID << " is not a shader.";
|
||||
}
|
||||
glGetProgramiv(mProgramID, GL_LINK_STATUS, &programSuccess);
|
||||
if (programSuccess != GL_TRUE) {
|
||||
LOG(LogError) << "OpenGL error: Unable to link program " << mProgramID << ".";
|
||||
printProgramInfoLog(mProgramID);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Renderer
|
||||
getVariableLocations(mProgramID);
|
||||
|
||||
if (mShaderPosition != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(mShaderPosition));
|
||||
|
||||
if (mShaderTextureCoord != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(mShaderTextureCoord));
|
||||
|
||||
if (mShaderColor != -1)
|
||||
GL_CHECK_ERROR(glEnableVertexAttribArray(mShaderColor));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Shader::deleteProgram(GLuint programID) { GL_CHECK_ERROR(glDeleteProgram(programID)); }
|
||||
|
||||
void Shader::getVariableLocations(GLuint programID)
|
||||
{
|
||||
// Some of the variable names are chosen to be compatible with the RetroArch GLSL shaders.
|
||||
mShaderMVPMatrix = glGetUniformLocation(mProgramID, "MVPMatrix");
|
||||
mShaderPosition = glGetAttribLocation(mProgramID, "positionAttrib");
|
||||
mShaderTextureCoord = glGetAttribLocation(mProgramID, "TexCoord");
|
||||
mShaderColor = glGetAttribLocation(mProgramID, "colorAttrib");
|
||||
mShaderTextureSize = glGetUniformLocation(mProgramID, "TextureSize");
|
||||
mShaderOpacity = glGetUniformLocation(mProgramID, "opacity");
|
||||
mShaderSaturation = glGetUniformLocation(mProgramID, "saturation");
|
||||
mShaderDimming = glGetUniformLocation(mProgramID, "dimming");
|
||||
mShaderBGRAToRGBA = glGetUniformLocation(mProgramID, "BGRAToRGBA");
|
||||
mShaderFont = glGetUniformLocation(mProgramID, "font");
|
||||
mShaderPostProcessing = glGetUniformLocation(mProgramID, "postProcessing");
|
||||
}
|
||||
|
||||
void Shader::setModelViewProjectionMatrix(glm::mat4 mvpMatrix)
|
||||
{
|
||||
if (mShaderMVPMatrix != GL_INVALID_VALUE && mShaderMVPMatrix != GL_INVALID_OPERATION)
|
||||
GL_CHECK_ERROR(glUniformMatrix4fv(mShaderMVPMatrix, 1, GL_FALSE,
|
||||
reinterpret_cast<GLfloat*>(&mvpMatrix)));
|
||||
}
|
||||
|
||||
void Shader::setAttribPointers()
|
||||
{
|
||||
if (mShaderPosition != -1)
|
||||
GL_CHECK_ERROR(glVertexAttribPointer(
|
||||
mShaderPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer::Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Renderer::Vertex, position))));
|
||||
if (mShaderTextureCoord != -1)
|
||||
GL_CHECK_ERROR(glVertexAttribPointer(
|
||||
mShaderTextureCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer::Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Renderer::Vertex, texture))));
|
||||
|
||||
if (mShaderColor != -1)
|
||||
GL_CHECK_ERROR(glVertexAttribPointer(
|
||||
mShaderColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Renderer::Vertex),
|
||||
reinterpret_cast<const void*>(offsetof(Renderer::Vertex, color))));
|
||||
}
|
||||
|
||||
void Shader::setTextureSize(std::array<GLfloat, 2> shaderVec2)
|
||||
{
|
||||
if (mShaderTextureSize != -1)
|
||||
GL_CHECK_ERROR(glUniform2f(mShaderTextureSize, shaderVec2[0], shaderVec2[1]));
|
||||
}
|
||||
|
||||
void Shader::setOpacity(GLfloat opacity)
|
||||
{
|
||||
if (mShaderOpacity != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(mShaderOpacity, opacity));
|
||||
}
|
||||
|
||||
void Shader::setSaturation(GLfloat saturation)
|
||||
{
|
||||
if (mShaderSaturation != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(mShaderSaturation, saturation));
|
||||
}
|
||||
|
||||
void Shader::setDimming(GLfloat dimming)
|
||||
{
|
||||
if (mShaderDimming != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(mShaderDimming, dimming));
|
||||
}
|
||||
|
||||
void Shader::setBGRAToRGBA(GLboolean BGRAToRGBA)
|
||||
{
|
||||
if (mShaderBGRAToRGBA != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(mShaderBGRAToRGBA, BGRAToRGBA ? 1 : 0));
|
||||
}
|
||||
|
||||
void Shader::setFont(GLboolean font)
|
||||
{
|
||||
if (mShaderFont != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(mShaderFont, font ? 1 : 0));
|
||||
}
|
||||
|
||||
void Shader::setPostProcessing(GLboolean postProcessing)
|
||||
{
|
||||
if (mShaderPostProcessing != -1)
|
||||
GL_CHECK_ERROR(glUniform1i(mShaderPostProcessing, postProcessing ? 1 : 0));
|
||||
}
|
||||
|
||||
void Shader::activateShaders()
|
||||
{
|
||||
// Install the shader program.
|
||||
GL_CHECK_ERROR(glUseProgram(mProgramID));
|
||||
}
|
||||
|
||||
void Shader::deactivateShaders()
|
||||
{
|
||||
// Remove the shader program.
|
||||
GL_CHECK_ERROR(glUseProgram(0));
|
||||
}
|
||||
|
||||
void Shader::printProgramInfoLog(GLuint programID)
|
||||
{
|
||||
if (glIsProgram(programID)) {
|
||||
int logLength;
|
||||
int maxLength;
|
||||
|
||||
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
std::vector<char> infoLog(maxLength);
|
||||
|
||||
glGetProgramInfoLog(programID, maxLength, &logLength, &infoLog.front());
|
||||
|
||||
if (logLength > 0) {
|
||||
LOG(LogDebug) << "Renderer_GL21::printProgramInfoLog():\n"
|
||||
<< std::string(infoLog.begin(), infoLog.end());
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "OpenGL error: " << programID << " is not a program.";
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error)
|
||||
{
|
||||
if (glIsShader(shaderID)) {
|
||||
int logLength;
|
||||
int maxLength;
|
||||
|
||||
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
std::vector<char> infoLog(maxLength);
|
||||
|
||||
if (infoLog.size() == 0)
|
||||
return;
|
||||
|
||||
glGetShaderInfoLog(shaderID, maxLength, &logLength, &infoLog.front());
|
||||
|
||||
if (logLength > 0) {
|
||||
LOG(LogDebug) << "Shader_GL21::printShaderInfoLog(): " << (error ? "Error" : "Warning")
|
||||
<< " in "
|
||||
<< (shaderType == GL_VERTEX_SHADER ? "VERTEX section:\n" :
|
||||
"FRAGMENT section:\n")
|
||||
<< std::string(infoLog.begin(), infoLog.end());
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "OpenGL error: " << shaderID << " is not a shader.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "renderers/Renderer.h"
|
||||
#include "utils/MathUtil.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
|
@ -28,61 +29,77 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Renderer
|
||||
#if !defined(NDEBUG)
|
||||
#define GL_CHECK_ERROR(Function) (Function, _GLCheckError(#Function))
|
||||
static inline void _GLCheckError(const std::string& funcName)
|
||||
{
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
const GLenum errorCode = glGetError();
|
||||
|
||||
// Loads the shader source code only, no compilation done at this point.
|
||||
void loadShaderFile(const std::string& path, GLenum shaderType);
|
||||
// Compilation, shader attachment and linking.
|
||||
bool createProgram();
|
||||
// Only used for a clean shutdown.
|
||||
void deleteProgram(GLuint programID);
|
||||
// Get references to the variables inside the compiled shaders.
|
||||
void getVariableLocations(GLuint programID);
|
||||
// One-way communication with the compiled shaders.
|
||||
void setModelViewProjectionMatrix(glm::mat4 mvpMatrix);
|
||||
if (errorCode != GL_NO_ERROR) {
|
||||
#if defined(USE_OPENGLES)
|
||||
LOG(LogError) << "OpenGL ES error: " << funcName << " failed with error code: 0x"
|
||||
<< std::hex << errorCode;
|
||||
#else
|
||||
LOG(LogError) << "OpenGL error: " << funcName << " failed with error code: 0x" << std::hex
|
||||
<< errorCode;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define GL_CHECK_ERROR(Function) (Function)
|
||||
#endif
|
||||
|
||||
void setAttribPointers();
|
||||
void setTextureSize(std::array<GLfloat, 2> shaderVec2);
|
||||
void setOpacity(GLfloat opacity);
|
||||
void setSaturation(GLfloat saturation);
|
||||
void setDimming(GLfloat dimming);
|
||||
void setBGRAToRGBA(GLboolean BGRAToRGBA);
|
||||
void setFont(GLboolean font);
|
||||
void setPostProcessing(GLboolean postProcessing);
|
||||
// Sets the shader program to use the loaded shaders.
|
||||
void activateShaders();
|
||||
// Sets the shader program to 0 which reverts to the fixed function pipeline.
|
||||
void deactivateShaders();
|
||||
// Returns the program ID that was generated by glCreateProgram().
|
||||
GLuint getProgramID() { return mProgramID; }
|
||||
// Only used for error logging if the shaders fail to compile or link.
|
||||
void printProgramInfoLog(GLuint programID);
|
||||
void printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error);
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
private:
|
||||
GLuint mProgramID;
|
||||
std::vector<std::tuple<std::string, std::string, GLenum>> shaderVector;
|
||||
// Loads the shader source code only, no compilation done at this point.
|
||||
void loadShaderFile(const std::string& path, GLenum shaderType);
|
||||
// Compilation, shader attachment and linking.
|
||||
bool createProgram();
|
||||
// Only used for a clean shutdown.
|
||||
void deleteProgram(GLuint programID);
|
||||
// Get references to the variables inside the compiled shaders.
|
||||
void getVariableLocations(GLuint programID);
|
||||
// One-way communication with the compiled shaders.
|
||||
void setModelViewProjectionMatrix(glm::mat4 mvpMatrix);
|
||||
|
||||
// Variables used for communication with the compiled shaders.
|
||||
GLint shaderMVPMatrix;
|
||||
GLint shaderPosition;
|
||||
GLint shaderTextureCoord;
|
||||
GLint shaderColor;
|
||||
GLint shaderTextureSize;
|
||||
GLint shaderOpacity;
|
||||
GLint shaderSaturation;
|
||||
GLint shaderDimming;
|
||||
GLint shaderBGRAToRGBA;
|
||||
GLint shaderFont;
|
||||
GLint shaderPostProcessing;
|
||||
};
|
||||
void setAttribPointers();
|
||||
void setTextureSize(std::array<GLfloat, 2> shaderVec2);
|
||||
void setOpacity(GLfloat opacity);
|
||||
void setSaturation(GLfloat saturation);
|
||||
void setDimming(GLfloat dimming);
|
||||
void setBGRAToRGBA(GLboolean BGRAToRGBA);
|
||||
void setFont(GLboolean font);
|
||||
void setPostProcessing(GLboolean postProcessing);
|
||||
// Sets the shader program to use the loaded shaders.
|
||||
void activateShaders();
|
||||
// Sets the shader program to 0 which reverts to the fixed function pipeline.
|
||||
void deactivateShaders();
|
||||
// Returns the program ID that was generated by glCreateProgram().
|
||||
GLuint getProgramID() { return mProgramID; }
|
||||
// Only used for error logging if the shaders fail to compile or link.
|
||||
void printProgramInfoLog(GLuint programID);
|
||||
void printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error);
|
||||
|
||||
} // namespace Renderer
|
||||
private:
|
||||
GLuint mProgramID;
|
||||
std::vector<std::tuple<std::string, std::string, GLenum>> mShaderVector;
|
||||
|
||||
// Variables used for communication with the compiled shaders.
|
||||
GLint mShaderMVPMatrix;
|
||||
GLint mShaderPosition;
|
||||
GLint mShaderTextureCoord;
|
||||
GLint mShaderColor;
|
||||
GLint mShaderTextureSize;
|
||||
GLint mShaderOpacity;
|
||||
GLint mShaderSaturation;
|
||||
GLint mShaderDimming;
|
||||
GLint mShaderBGRAToRGBA;
|
||||
GLint mShaderFont;
|
||||
GLint mShaderPostProcessing;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_RENDERER_SHADER_GL21_H
|
||||
|
|
|
@ -76,7 +76,8 @@ size_t Font::getTotalMemUsage()
|
|||
}
|
||||
|
||||
Font::Font(int size, const std::string& path)
|
||||
: mSize(size)
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mSize(size)
|
||||
, mPath(path)
|
||||
{
|
||||
if (mSize < 9) {
|
||||
|
@ -199,14 +200,14 @@ bool Font::FontTexture::findEmpty(const glm::ivec2& size, glm::ivec2& cursor_out
|
|||
void Font::FontTexture::initTexture()
|
||||
{
|
||||
assert(textureId == 0);
|
||||
textureId = Renderer::createTexture(Renderer::Texture::RED, false, false, false, textureSize.x,
|
||||
textureSize.y, nullptr);
|
||||
textureId = Renderer::getInstance()->createTexture(
|
||||
Renderer::TextureType::RED, false, false, false, textureSize.x, textureSize.y, nullptr);
|
||||
}
|
||||
|
||||
void Font::FontTexture::deinitTexture()
|
||||
{
|
||||
if (textureId != 0) {
|
||||
Renderer::destroyTexture(textureId);
|
||||
Renderer::getInstance()->destroyTexture(textureId);
|
||||
textureId = 0;
|
||||
}
|
||||
}
|
||||
|
@ -346,8 +347,8 @@ Font::Glyph* Font::getGlyph(unsigned int id)
|
|||
static_cast<float>(g->metrics.horiBearingY) / 64.0f};
|
||||
|
||||
// Upload glyph bitmap to texture.
|
||||
Renderer::updateTexture(tex->textureId, Renderer::Texture::RED, cursor.x, cursor.y, glyphSize.x,
|
||||
glyphSize.y, g->bitmap.buffer);
|
||||
mRenderer->updateTexture(tex->textureId, Renderer::TextureType::RED, cursor.x, cursor.y,
|
||||
glyphSize.x, glyphSize.y, g->bitmap.buffer);
|
||||
|
||||
// Update max glyph height.
|
||||
if (glyphSize.y > mMaxGlyphHeight)
|
||||
|
@ -380,8 +381,8 @@ void Font::rebuildTextures()
|
|||
static_cast<int>(it->second.texSize.y * tex->textureSize.y)};
|
||||
|
||||
// Upload to texture.
|
||||
Renderer::updateTexture(tex->textureId, Renderer::Texture::RED, cursor.x, cursor.y,
|
||||
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
|
||||
mRenderer->updateTexture(tex->textureId, Renderer::TextureType::RED, cursor.x, cursor.y,
|
||||
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,9 +399,9 @@ void Font::renderTextCache(TextCache* cache)
|
|||
auto vertexList = *it;
|
||||
it->verts[0].font = true;
|
||||
|
||||
Renderer::bindTexture(*it->textureIdPtr);
|
||||
Renderer::drawTriangleStrips(&it->verts[0],
|
||||
static_cast<const unsigned int>(it->verts.size()));
|
||||
mRenderer->bindTexture(*it->textureIdPtr);
|
||||
mRenderer->drawTriangleStrips(&it->verts[0],
|
||||
static_cast<const unsigned int>(it->verts.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ public:
|
|||
static size_t getTotalMemUsage();
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
static FT_Library sLibrary;
|
||||
static std::map<std::pair<std::string, int>, std::weak_ptr<Font>> sFontMap;
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
#define DPI 96
|
||||
|
||||
TextureData::TextureData(bool tile)
|
||||
: mTile {tile}
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mTile {tile}
|
||||
, mTextureID {0}
|
||||
, mDataRGBA {}
|
||||
, mWidth {0}
|
||||
|
@ -209,7 +210,7 @@ bool TextureData::uploadAndBind()
|
|||
// Check if it has already been uploaded.
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
if (mTextureID != 0) {
|
||||
Renderer::bindTexture(mTextureID);
|
||||
mRenderer->bindTexture(mTextureID);
|
||||
}
|
||||
else {
|
||||
// Make sure we're ready to upload.
|
||||
|
@ -218,9 +219,9 @@ bool TextureData::uploadAndBind()
|
|||
|
||||
// Upload texture.
|
||||
mTextureID =
|
||||
Renderer::createTexture(Renderer::Texture::RGBA, true, mLinearMagnify, mTile,
|
||||
static_cast<const unsigned int>(mWidth),
|
||||
static_cast<const unsigned int>(mHeight), mDataRGBA.data());
|
||||
mRenderer->createTexture(Renderer::TextureType::RGBA, true, mLinearMagnify, mTile,
|
||||
static_cast<const unsigned int>(mWidth),
|
||||
static_cast<const unsigned int>(mHeight), mDataRGBA.data());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -229,7 +230,7 @@ void TextureData::releaseVRAM()
|
|||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
if (mTextureID != 0) {
|
||||
Renderer::destroyTexture(mTextureID);
|
||||
mRenderer->destroyTexture(mTextureID);
|
||||
mTextureID = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
bool tiled() { return mTile; }
|
||||
|
||||
private:
|
||||
Renderer* mRenderer;
|
||||
std::mutex mMutex;
|
||||
|
||||
bool mTile;
|
||||
|
|
Loading…
Reference in a new issue