239 lines
6.8 KiB
C++
239 lines
6.8 KiB
C++
#pragma once
|
|
|
|
#include "StarTextureAtlas.hpp"
|
|
#include "StarRenderer.hpp"
|
|
|
|
#include "GL/glew.h"
|
|
|
|
namespace Star {
|
|
|
|
STAR_CLASS(OpenGl20Renderer);
|
|
|
|
constexpr size_t FrameBufferCount = 1;
|
|
|
|
// OpenGL 2.0 implementation of Renderer. OpenGL context must be created and
|
|
// active during construction, destruction, and all method calls.
|
|
class OpenGl20Renderer : public Renderer {
|
|
public:
|
|
OpenGl20Renderer();
|
|
~OpenGl20Renderer();
|
|
|
|
String rendererId() const override;
|
|
Vec2U screenSize() const override;
|
|
|
|
void loadConfig(Json const& config) override;
|
|
void loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) override;
|
|
|
|
void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) override;
|
|
void setEffectTexture(String const& textureName, Image const& image) override;
|
|
|
|
void setScissorRect(Maybe<RectI> const& scissorRect) override;
|
|
|
|
bool switchEffectConfig(String const& name) override;
|
|
|
|
TexturePtr createTexture(Image const& texture, TextureAddressing addressing, TextureFiltering filtering) override;
|
|
void setSizeLimitEnabled(bool enabled) override;
|
|
void setMultiTexturingEnabled(bool enabled) override;
|
|
TextureGroupPtr createTextureGroup(TextureGroupSize size, TextureFiltering filtering) override;
|
|
RenderBufferPtr createRenderBuffer() override;
|
|
|
|
List<RenderPrimitive>& immediatePrimitives() override;
|
|
void render(RenderPrimitive primitive) override;
|
|
void renderBuffer(RenderBufferPtr const& renderBuffer, Mat3F const& transformation) override;
|
|
|
|
void flush() override;
|
|
|
|
void setScreenSize(Vec2U screenSize);
|
|
|
|
void startFrame();
|
|
void finishFrame();
|
|
|
|
private:
|
|
struct GlTextureAtlasSet : public TextureAtlasSet<GLuint> {
|
|
public:
|
|
GlTextureAtlasSet(unsigned atlasNumCells);
|
|
|
|
GLuint createAtlasTexture(Vec2U const& size, PixelFormat pixelFormat) override;
|
|
void destroyAtlasTexture(GLuint const& glTexture) override;
|
|
void copyAtlasPixels(GLuint const& glTexture, Vec2U const& bottomLeft, Image const& image) override;
|
|
|
|
TextureFiltering textureFiltering;
|
|
};
|
|
|
|
struct GlTextureGroup : enable_shared_from_this<GlTextureGroup>, public TextureGroup {
|
|
GlTextureGroup(unsigned atlasNumCells);
|
|
~GlTextureGroup();
|
|
|
|
TextureFiltering filtering() const override;
|
|
TexturePtr create(Image const& texture) override;
|
|
|
|
GlTextureAtlasSet textureAtlasSet;
|
|
};
|
|
|
|
struct GlTexture : public Texture {
|
|
virtual GLuint glTextureId() const = 0;
|
|
virtual Vec2U glTextureSize() const = 0;
|
|
virtual Vec2U glTextureCoordinateOffset() const = 0;
|
|
};
|
|
|
|
struct GlGroupedTexture : public GlTexture {
|
|
~GlGroupedTexture();
|
|
|
|
Vec2U size() const override;
|
|
TextureFiltering filtering() const override;
|
|
TextureAddressing addressing() const override;
|
|
|
|
GLuint glTextureId() const override;
|
|
Vec2U glTextureSize() const override;
|
|
Vec2U glTextureCoordinateOffset() const override;
|
|
|
|
void incrementBufferUseCount();
|
|
void decrementBufferUseCount();
|
|
|
|
unsigned bufferUseCount = 0;
|
|
shared_ptr<GlTextureGroup> parentGroup;
|
|
GlTextureAtlasSet::TextureHandle parentAtlasTexture = nullptr;
|
|
};
|
|
|
|
struct GlLoneTexture : public GlTexture {
|
|
~GlLoneTexture();
|
|
|
|
Vec2U size() const override;
|
|
TextureFiltering filtering() const override;
|
|
TextureAddressing addressing() const override;
|
|
|
|
GLuint glTextureId() const override;
|
|
Vec2U glTextureSize() const override;
|
|
Vec2U glTextureCoordinateOffset() const override;
|
|
|
|
GLuint textureId = 0;
|
|
Vec2U textureSize;
|
|
TextureAddressing textureAddressing = TextureAddressing::Clamp;
|
|
TextureFiltering textureFiltering = TextureFiltering::Nearest;
|
|
};
|
|
|
|
struct GlRenderVertex {
|
|
Vec2F screenCoordinate;
|
|
Vec2F textureCoordinate;
|
|
float textureIndex;
|
|
Vec4B color;
|
|
float param1;
|
|
};
|
|
|
|
struct GlRenderBuffer : public RenderBuffer {
|
|
struct GlVertexBufferTexture {
|
|
GLuint texture;
|
|
Vec2U size;
|
|
};
|
|
|
|
struct GlVertexBuffer {
|
|
List<GlVertexBufferTexture> textures;
|
|
GLuint vertexBuffer = 0;
|
|
size_t vertexCount = 0;
|
|
};
|
|
|
|
~GlRenderBuffer();
|
|
|
|
void set(List<RenderPrimitive>& primitives) override;
|
|
|
|
RefPtr<GlTexture> whiteTexture;
|
|
ByteArray accumulationBuffer;
|
|
|
|
HashSet<TexturePtr> usedTextures;
|
|
List<GlVertexBuffer> vertexBuffers;
|
|
|
|
bool useMultiTexturing{true};
|
|
};
|
|
|
|
struct EffectParameter {
|
|
GLint parameterUniform = -1;
|
|
VariantTypeIndex parameterType = 0;
|
|
Maybe<RenderEffectParameter> parameterValue;
|
|
};
|
|
|
|
struct EffectTexture {
|
|
GLint textureUniform = -1;
|
|
unsigned textureUnit = 0;
|
|
TextureAddressing textureAddressing = TextureAddressing::Clamp;
|
|
TextureFiltering textureFiltering = TextureFiltering::Linear;
|
|
GLint textureSizeUniform = -1;
|
|
RefPtr<GlLoneTexture> textureValue;
|
|
};
|
|
|
|
struct GlFrameBuffer : RefCounter {
|
|
GLuint id = 0;
|
|
RefPtr<GlLoneTexture> texture;
|
|
|
|
Json config;
|
|
bool blitted = false;
|
|
|
|
GlFrameBuffer(Json const& config);
|
|
~GlFrameBuffer();
|
|
};
|
|
|
|
class Effect {
|
|
public:
|
|
GLuint program = 0;
|
|
Json config;
|
|
StringMap<EffectParameter> parameters;
|
|
StringMap<EffectTexture> textures;
|
|
|
|
StringMap<GLuint> attributes;
|
|
StringMap<GLuint> uniforms;
|
|
|
|
GLuint getAttribute(String const& name);
|
|
GLuint getUniform(String const& name);
|
|
};
|
|
|
|
static bool logGlErrorSummary(String prefix);
|
|
static void uploadTextureImage(PixelFormat pixelFormat, Vec2U size, uint8_t const* data);
|
|
|
|
static RefPtr<GlLoneTexture> createGlTexture(Image const& texture, TextureAddressing addressing, TextureFiltering filtering);
|
|
|
|
shared_ptr<GlRenderBuffer> createGlRenderBuffer();
|
|
|
|
void flushImmediatePrimitives();
|
|
|
|
void renderGlBuffer(GlRenderBuffer const& renderBuffer, Mat3F const& transformation);
|
|
|
|
void setupGlUniforms(Effect& effect);
|
|
|
|
RefPtr<OpenGl20Renderer::GlFrameBuffer> getGlFrameBuffer(String const& id);
|
|
void blitGlFrameBuffer(RefPtr<OpenGl20Renderer::GlFrameBuffer> const& frameBuffer);
|
|
void switchGlFrameBuffer(RefPtr<OpenGl20Renderer::GlFrameBuffer> const& frameBuffer);
|
|
|
|
Vec2U m_screenSize;
|
|
|
|
GLuint m_program = 0;
|
|
|
|
GLint m_positionAttribute = -1;
|
|
GLint m_texCoordAttribute = -1;
|
|
GLint m_texIndexAttribute = -1;
|
|
GLint m_colorAttribute = -1;
|
|
GLint m_param1Attribute = -1;
|
|
|
|
List<GLint> m_textureUniforms = {};
|
|
List<GLint> m_textureSizeUniforms = {};
|
|
GLint m_screenSizeUniform = -1;
|
|
GLint m_vertexTransformUniform = -1;
|
|
|
|
StringMap<Effect> m_effects;
|
|
Effect* m_currentEffect;
|
|
|
|
StringMap<RefPtr<GlFrameBuffer>> m_frameBuffers;
|
|
RefPtr<GlFrameBuffer> m_currentFrameBuffer;
|
|
|
|
RefPtr<GlTexture> m_whiteTexture;
|
|
|
|
Maybe<RectI> m_scissorRect;
|
|
|
|
bool m_limitTextureGroupSize;
|
|
bool m_useMultiTexturing;
|
|
List<shared_ptr<GlTextureGroup>> m_liveTextureGroups;
|
|
|
|
List<RenderPrimitive> m_immediatePrimitives;
|
|
shared_ptr<GlRenderBuffer> m_immediateRenderBuffer;
|
|
};
|
|
|
|
}
|