#ifndef __GL_RENDERBUFFERS_H #define __GL_RENDERBUFFERS_H #include "gl/shaders/gl_shader.h" #include "hwrenderer/postprocessing/hw_postprocess.h" class PPTexture { public: void Bind(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE) { glActiveTexture(GL_TEXTURE0 + index); glBindTexture(GL_TEXTURE_2D, handle); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); } int Width = -1; int Height = -1; explicit operator bool() const { return handle != 0; } private: GLuint handle = 0; friend class FGLRenderBuffers; }; class PPFrameBuffer { public: void Bind() { glBindFramebuffer(GL_FRAMEBUFFER, handle); } explicit operator bool() const { return handle != 0; } private: GLuint handle = 0; friend class FGLRenderBuffers; }; class PPRenderBuffer { private: GLuint handle = 0; explicit operator bool() const { return handle != 0; } friend class FGLRenderBuffers; }; class FShaderProgram; class FGLRenderBuffers { public: FGLRenderBuffers(); ~FGLRenderBuffers(); bool Setup(int width, int height, int sceneWidth, int sceneHeight); void UpdateEffectTextures(); void CompileEffectShaders(); void RenderEffect(const FString &name); TMap GLTextures; TMap GLTextureFBs; TMap> GLShaders; void BindSceneFB(bool sceneData); void BindSceneColorTexture(int index); void BindSceneFogTexture(int index); void BindSceneNormalTexture(int index); void BindSceneDepthTexture(int index); void BlitSceneToTexture(); void BindCurrentTexture(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE); void BindCurrentFB(); void BindNextFB(); void NextTexture(); PPFrameBuffer GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; } void BindOutputFB(); void BlitToEyeTexture(int eye); void BindEyeTexture(int eye, int texunit); void BindEyeFB(int eye, bool readBuffer = false); void BindShadowMapFB(); void BindShadowMapTexture(int index); // Ambient occlusion buffers PPTexture LinearDepthTexture; PPFrameBuffer LinearDepthFB; PPTexture AmbientTexture0; PPTexture AmbientTexture1; PPFrameBuffer AmbientFB0; PPFrameBuffer AmbientFB1; int AmbientWidth = 0; int AmbientHeight = 0; enum { NumAmbientRandomTextures = 3 }; PPTexture AmbientRandomTexture[NumAmbientRandomTextures]; int GetWidth() const { return mWidth; } int GetHeight() const { return mHeight; } int GetSceneWidth() const { return mSceneWidth; } int GetSceneHeight() const { return mSceneHeight; } private: void ClearScene(); void ClearPipeline(); void ClearEyeBuffers(); void ClearAmbientOcclusion(); void ClearShadowMap(); void CreateScene(int width, int height, int samples, bool needsSceneTextures); void CreatePipeline(int width, int height); void CreateEyeBuffers(int eye); void CreateShadowMap(); void CreateAmbientOcclusion(int width, int height); PPTexture Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr); PPTexture Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations); PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height); PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples); PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer); PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer, PPRenderBuffer depthstencil); PPFrameBuffer CreateFrameBuffer(const char *name, PPRenderBuffer colorbuffer, PPRenderBuffer depthstencil); PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer0, PPTexture colorbuffer1, PPTexture colorbuffer2, PPTexture depthstencil, bool multisample); bool CheckFrameBufferCompleteness(); void ClearFrameBuffer(bool stencil, bool depth); void DeleteTexture(PPTexture &handle); void DeleteRenderBuffer(PPRenderBuffer &handle); void DeleteFrameBuffer(PPFrameBuffer &handle); int mWidth = 0; int mHeight = 0; int mSamples = 0; int mMaxSamples = 0; int mSceneWidth = 0; int mSceneHeight = 0; static const int NumPipelineTextures = 2; int mCurrentPipelineTexture = 0; // Buffers for the scene PPTexture mSceneMultisampleTex; PPTexture mSceneDepthStencilTex; PPTexture mSceneFogTex; PPTexture mSceneNormalTex; PPRenderBuffer mSceneMultisampleBuf; PPRenderBuffer mSceneDepthStencilBuf; PPRenderBuffer mSceneFogBuf; PPRenderBuffer mSceneNormalBuf; PPFrameBuffer mSceneFB; PPFrameBuffer mSceneDataFB; bool mSceneUsesTextures = false; // Effect/HUD buffers PPTexture mPipelineTexture[NumPipelineTextures]; PPFrameBuffer mPipelineFB[NumPipelineTextures]; // Eye buffers TArray mEyeTextures; TArray mEyeFBs; // Shadow map texture PPTexture mShadowMapTexture; PPFrameBuffer mShadowMapFB; int mCurrentShadowMapSize = 0; static bool FailedCreate; }; #endif