Skip to content

Commit

Permalink
ok
Browse files Browse the repository at this point in the history
  • Loading branch information
CCIGAMES committed Mar 2, 2024
1 parent 71cbe68 commit c990ede
Show file tree
Hide file tree
Showing 5 changed files with 473 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#include "oxygen/pch.h"

#ifdef RMX_WITH_OPENGL_SUPPORT

#include "oxygen/rendering/opengl/shaders/RenderPaletteSpriteShader.h"
#include "oxygen/rendering/opengl/OpenGLRenderResources.h"
#include "oxygen/rendering/Geometry.h"
#include "oxygen/rendering/parts/RenderParts.h"
#include "oxygen/application/Configuration.h"
#include "oxygen/drawing/opengl/OpenGLSpriteTextureManager.h"
#include "oxygen/helper/FileHelper.h"


void RenderPaletteSpriteShader::initialize(bool alphaTest)
{
const std::string additionalDefines = BufferTexture::supportsBufferTextures() ? "USE_BUFFER_TEXTURES" : "";
FileHelper::loadShader(mShader, L"data/shader/render_sprite_palette.shader", alphaTest ? "Standard_AlphaTest" : "Standard", additionalDefines);
}

void RenderPaletteSpriteShader::refresh(const Vec2i& gameResolution, int waterSurfaceHeight, const OpenGLRenderResources& resources)
{
mShader.bind();

if (!mInitialized)
{
mLocGameResolution = mShader.getUniformLocation("GameResolution");
mLocWaterLevel = mShader.getUniformLocation("WaterLevel");
mLocPaletteTex = mShader.getUniformLocation("PaletteTexture");
mLocSpriteTex = mShader.getUniformLocation("SpriteTexture");
mLocPosition = mShader.getUniformLocation("Position");
mLocPivotOffset = mShader.getUniformLocation("PivotOffset");
mLocSize = mShader.getUniformLocation("Size");
mLocTransformation = mShader.getUniformLocation("Transformation");
mLocAtex = mShader.getUniformLocation("Atex");
mLocTintColor = mShader.getUniformLocation("TintColor");
mLocAddedColor = mShader.getUniformLocation("AddedColor");

glUniform1i(mLocSpriteTex, 0);
glUniform1i(mLocPaletteTex, 1);
}

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, resources.mPaletteTexture.getHandle());

if (mLastGameResolution != gameResolution || !mInitialized)
{
glUniform2iv(mLocGameResolution, 1, *gameResolution);
mLastGameResolution = gameResolution;
}

if (mLastWaterSurfaceHeight != waterSurfaceHeight || !mInitialized)
{
glUniform1i(mLocWaterLevel, waterSurfaceHeight);
mLastWaterSurfaceHeight = waterSurfaceHeight;
}

mInitialized = true;
}

void RenderPaletteSpriteShader::draw(const renderitems::PaletteSpriteInfo& spriteInfo, OpenGLRenderResources& resources)
{
if (nullptr == spriteInfo.mCacheItem)
return;

glActiveTexture(GL_TEXTURE0);
const BufferTexture* texture = OpenGLSpriteTextureManager::instance().getPaletteSpriteTexture(*spriteInfo.mCacheItem, spriteInfo.mUseUpscaledSprite);
if (nullptr == texture)
return;

texture->bindTexture();

glUniform3iv(mLocPosition, 1, *Vec3i(spriteInfo.mInterpolatedPosition.x, spriteInfo.mInterpolatedPosition.y, spriteInfo.mPriorityFlag ? 1 : 0));
glUniform2iv(mLocPivotOffset, 1, *spriteInfo.mPivotOffset);
glUniform2iv(mLocSize, 1, *spriteInfo.mSize);
glUniform4fv(mLocTransformation, 1, *spriteInfo.mTransformation.mMatrix);
glUniform1i (mLocAtex, spriteInfo.mAtex);
glUniform4fv(mLocTintColor, 1, spriteInfo.mTintColor.data);
glUniform4fv(mLocAddedColor, 1, spriteInfo.mAddedColor.data);

glDrawArrays(GL_TRIANGLES, 0, 6);
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#pragma once

#ifdef RMX_WITH_OPENGL_SUPPORT

#include "oxygen/rendering/opengl/shaders/OpenGLShader.h"
#include "oxygen/rendering/parts/RenderItem.h"

class OpenGLDrawer;
class OpenGLRenderResources;


class RenderPaletteSpriteShader : public OpenGLShader
{
public:
void initialize(bool alphaTest);
void refresh(const Vec2i& gameResolution, int waterSurfaceHeight, const OpenGLRenderResources& resources);
void draw(const renderitems::PaletteSpriteInfo& spriteInfo, OpenGLRenderResources& resources);

private:
bool mInitialized = false;
Vec2i mLastGameResolution;
int mLastWaterSurfaceHeight = 0;

Shader mShader;
GLuint mLocGameResolution = 0;
GLuint mLocWaterLevel = 0;
GLuint mLocPaletteTex = 0;
GLuint mLocSpriteTex = 0;
GLuint mLocPosition = 0;
GLuint mLocPivotOffset = 0;
GLuint mLocSize = 0;
GLuint mLocTransformation = 0;
GLuint mLocAtex = 0;
GLuint mLocTintColor = 0;
GLuint mLocAddedColor = 0;
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#include "oxygen/pch.h"

#ifdef RMX_WITH_OPENGL_SUPPORT

#include "oxygen/rendering/opengl/shaders/RenderPlaneShader.h"
#include "oxygen/rendering/opengl/OpenGLRenderResources.h"
#include "oxygen/rendering/Geometry.h"
#include "oxygen/rendering/parts/RenderParts.h"
#include "oxygen/application/Configuration.h"
#include "oxygen/helper/FileHelper.h"


void RenderPlaneShader::initialize(Variation variation, bool alphaTest)
{
switch (variation)
{
case PS_SIMPLE: initialize(false, false, false, alphaTest); break; // No scroll offsets used, primarily for window plane
case PS_HORIZONTAL_SCROLLING: initialize(true, false, false, alphaTest); break; // Only horizontal scroll offsets used
case PS_VERTICAL_SCROLLING: initialize(true, true, false, alphaTest); break; // Horizontal + vertical scroll offsets used
case PS_NO_REPEAT: initialize(true, false, true, alphaTest); break; // No repeat for horizontal scroll offsets
default:
RMX_ASSERT(false, "Unrecognized render plane shader variation " << variation);
}
}

void RenderPlaneShader::initialize(bool horizontalScrolling, bool verticalScrolling, bool noRepeat, bool alphaTest)
{
mHorizontalScrolling = horizontalScrolling;
mVerticalScrolling = verticalScrolling;

std::string techname = noRepeat ? "HorizontalScrollingNoRepeat" : horizontalScrolling ? (verticalScrolling ? "HorizontalVerticalScrolling" : "HorizontalScrolling") : (verticalScrolling ? "VerticalScrolling" : "Standard");
std::string additionalDefines = BufferTexture::supportsBufferTextures() ? "USE_BUFFER_TEXTURES" : "";
if (alphaTest)
additionalDefines = (additionalDefines.empty() ? std::string() : (additionalDefines + ",")) + "ALPHA_TEST";
FileHelper::loadShader(mShader, L"data/shader/render_plane.shader", techname, additionalDefines);
}

void RenderPlaneShader::refresh(const Vec2i& gameResolution, const OpenGLRenderResources& resources)
{
// No alpha blending needed for planes
glBlendFunc(GL_ONE, GL_ZERO);

mShader.bind();

if (!mInitialized)
{
mLocActiveRect = mShader.getUniformLocation("ActiveRect");
mLocGameResolution = mShader.getUniformLocation("GameResolution");
mLocPriorityFlag = mShader.getUniformLocation("PriorityFlag");
mLocPaletteOffset = mShader.getUniformLocation("PaletteOffset");
mLocPlayfieldSize = mShader.getUniformLocation("PlayfieldSize");
mLocPatternCacheTex = mShader.getUniformLocation("PatternCacheTexture");
mLocIndexTex = mShader.getUniformLocation("IndexTexture");
mLocPaletteTex = mShader.getUniformLocation("PaletteTexture");

glUniform1i(mLocPatternCacheTex, 0);
glUniform1i(mLocPaletteTex, 1);
glUniform1i(mLocIndexTex, 2);

if (mHorizontalScrolling)
{
mLocHScrollOffsetsTex = mShader.getUniformLocation("HScrollOffsetsTexture");
glUniform1i(mLocHScrollOffsetsTex, 3);
}
else
{
mLocScrollOffsetX = mShader.getUniformLocation("ScrollOffsetX");
}

if (mVerticalScrolling)
{
mLocVScrollOffsetsTex = mShader.getUniformLocation("VScrollOffsetsTexture");
mLocVScrollOffsetBias = mShader.getUniformLocation("VScrollOffsetBias");
glUniform1i(mLocVScrollOffsetsTex, 4);
}
else
{
mLocScrollOffsetY = mShader.getUniformLocation("ScrollOffsetY");
}
}

glActiveTexture(GL_TEXTURE0);
resources.mPatternCacheTexture.bindTexture();

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, resources.mPaletteTexture.getHandle());

if (mLastGameResolution != gameResolution || !mInitialized)
{
glUniform2iv(mLocGameResolution, 1, *gameResolution);
mLastGameResolution = gameResolution;
}

mInitialized = true;
}

void RenderPlaneShader::draw(const PlaneGeometry& geometry, int waterSurfaceHeight, RenderParts& renderParts, const OpenGLRenderResources& resources)
{
const Vec4i playfieldSize = (geometry.mPlaneIndex <= PlaneManager::PLANE_A) ? renderParts.getPlaneManager().getPlayfieldSizeForShaders() : Vec4i(512, 256, 64, 32);
if (mLastPlayfieldSize != playfieldSize)
{
glUniform4iv(mLocPlayfieldSize, 1, playfieldSize.data);
mLastPlayfieldSize = playfieldSize;
}

if (mLastRenderedPlanePriority != geometry.mPriorityFlag)
{
glUniform1i(mLocPriorityFlag, geometry.mPriorityFlag ? 1 : 0);
mLastRenderedPlanePriority = geometry.mPriorityFlag;
}

glActiveTexture(GL_TEXTURE2);
resources.mPlanePatternsTexture[geometry.mPlaneIndex].bindTexture();

if (mHorizontalScrolling)
{
glActiveTexture(GL_TEXTURE3);
resources.getHScrollOffsetsTexture(geometry.mScrollOffsets).bindTexture();
}
else
{
if (geometry.mPlaneIndex == PlaneManager::PLANE_W) // Special handling required here
{
glUniform1i(mLocScrollOffsetX, renderParts.getScrollOffsetsManager().getPlaneWScrollOffset().x);
}
else
{
glUniform1i(mLocScrollOffsetX, renderParts.getScrollOffsetsManager().getScrollOffsetsH(geometry.mScrollOffsets)[0]);
}
}

if (mVerticalScrolling)
{
glActiveTexture(GL_TEXTURE4);
resources.getVScrollOffsetsTexture(geometry.mScrollOffsets).bindTexture();

glUniform1i(mLocVScrollOffsetBias, renderParts.getScrollOffsetsManager().getVerticalScrollOffsetBias());
}
else
{
if (geometry.mPlaneIndex == PlaneManager::PLANE_W) // Special handling required here
{
glUniform1i(mLocScrollOffsetY, renderParts.getScrollOffsetsManager().getPlaneWScrollOffset().y);
}
else
{
glUniform1i(mLocScrollOffsetY, renderParts.getScrollOffsetsManager().getScrollOffsetsV(geometry.mScrollOffsets)[0]);
}
}

// Handle palette split inside the active rect
Recti rects[2];
const int numRects = splitRectY(geometry.mActiveRect, waterSurfaceHeight, rects);
for (int i = 0; i < numRects; ++i)
{
if (mLastActiveRect != rects[i])
{
glUniform4iv(mLocActiveRect, 1, rects[i].mData);
mLastActiveRect = rects[i];
}

const int paletteVariant = i;
if (mLastPaletteVariant != paletteVariant || !mInitialized)
{
const float paletteOffset = (float)paletteVariant / 2.0f;
glUniform1f(mLocPaletteOffset, paletteOffset);
mLastPaletteVariant = paletteVariant;
}

glDrawArrays(GL_TRIANGLES, 0, 6);
}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#pragma once

#ifdef RMX_WITH_OPENGL_SUPPORT

#include "oxygen/rendering/opengl/shaders/OpenGLShader.h"

class RenderParts;
class PlaneGeometry;
class OpenGLRenderResources;


class RenderPlaneShader : public OpenGLShader
{
public:
enum Variation
{
PS_SIMPLE = 0, // No scroll offsets used, primarily for window plane
PS_HORIZONTAL_SCROLLING, // Only horizontal scroll offsets used
PS_VERTICAL_SCROLLING, // Horizontal + vertical scroll offsets used
PS_NO_REPEAT, // No repeat for horizontal scroll offsets
_NUM_VARIATIONS
};

public:
void initialize(Variation variation, bool alphaTest);
void initialize(bool horizontalScrolling, bool verticalScrolling, bool noRepeat, bool alphaTest);
void refresh(const Vec2i& gameResolution, const OpenGLRenderResources& resources);
void draw(const PlaneGeometry& geometry, int waterSurfaceHeight, RenderParts& renderParts, const OpenGLRenderResources& resources);

private:
bool mInitialized = false;
bool mHorizontalScrolling = false;
bool mVerticalScrolling = false;
bool mLastRenderedPlanePriority = false;
Recti mLastActiveRect;
Vec2i mLastGameResolution;
int mLastPaletteVariant = 0;
Vec4i mLastPlayfieldSize;

Shader mShader;
GLuint mLocActiveRect = 0;
GLuint mLocGameResolution = 0;
GLuint mLocPriorityFlag = 0;
GLuint mLocPaletteOffset = 0;
GLuint mLocPlayfieldSize = 0;
GLuint mLocPatternCacheTex = 0;
GLuint mLocIndexTex = 0;
GLuint mLocHScrollOffsetsTex = 0;
GLuint mLocVScrollOffsetsTex = 0;
GLuint mLocVScrollOffsetBias = 0;
GLuint mLocScrollOffsetX = 0;
GLuint mLocScrollOffsetY = 0;
GLuint mLocPaletteTex = 0;
};

#endif
Loading

0 comments on commit c990ede

Please sign in to comment.