#pragma once #include "gles_system.h" #include "gles_shader.h" #include "hwrenderer/postprocessing/hw_postprocess.h" namespace OpenGLESRenderer { class FShaderProgram : public PPShaderBackend { public: FShaderProgram(); ~FShaderProgram(); enum ShaderType { Vertex, Fragment, NumShaderTypes }; void Compile(ShaderType type, const char *lumpName, const char *defines, int maxGlslVersion); void Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion); void Link(const char *name); void SetUniformBufferLocation(int index, const char *name); void Bind(); GLuint Handle() { return mProgram; } //explicit operator bool() const { return mProgram != 0; } std::unique_ptr Uniforms; GLuint mProgram = 0; private: FShaderProgram(const FShaderProgram &) = delete; FShaderProgram &operator=(const FShaderProgram &) = delete; void CompileShader(ShaderType type); FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion); void CreateShader(ShaderType type); FString GetShaderInfoLog(GLuint handle); FString GetProgramInfoLog(GLuint handle); GLuint mShaders[NumShaderTypes]; FString mShaderSources[NumShaderTypes]; FString mShaderNames[NumShaderTypes]; TArray> samplerstobind; }; template class ShaderUniformsGles { public: ShaderUniformsGles() { memset(&Values, 0, sizeof(Values)); } ~ShaderUniformsGles() { if (mBuffer != nullptr) delete mBuffer; } FString CreateDeclaration(const char* name, const std::vector& fields) { mFields = fields; FString decl; decl += "\n"; for (size_t i = 0; i < fields.size(); i++) { decl.AppendFormat("\tuniform %s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name); } decl += "\n"; return decl; } void Init() { if (mBuffer == nullptr) mBuffer = screen->CreateDataBuffer(-1, false, false); } void SetData() { if (mBuffer != nullptr) mBuffer->SetData(sizeof(T), &Values, BufferUsageType::Static); } IDataBuffer* GetBuffer() const { // OpenGL needs to mess around with this in ways that should not be part of the interface. return mBuffer; } T* operator->() { return &Values; } const T* operator->() const { return &Values; } T Values; std::vector mFields; std::vector UniformLocation; private: ShaderUniformsGles(const ShaderUniformsGles&) = delete; ShaderUniformsGles& operator=(const ShaderUniformsGles&) = delete; IDataBuffer* mBuffer = nullptr; private: static const char* GetTypeStr(UniformType type) { switch (type) { default: case UniformType::Int: return "int"; case UniformType::UInt: return "uint"; case UniformType::Float: return "float"; case UniformType::Vec2: return "vec2"; case UniformType::Vec3: return "vec3"; case UniformType::Vec4: return "vec4"; case UniformType::IVec2: return "ivec2"; case UniformType::IVec3: return "ivec3"; case UniformType::IVec4: return "ivec4"; case UniformType::UVec2: return "uvec2"; case UniformType::UVec3: return "uvec3"; case UniformType::UVec4: return "uvec4"; case UniformType::Mat4: return "mat4"; } } }; class FPresentShaderBase { public: virtual ~FPresentShaderBase() {} virtual void Bind() = 0; ShaderUniformsGles Uniforms; protected: virtual void Init(const char * vtx_shader_name, const char * program_name); std::unique_ptr mShader; }; class FPresentShader : public FPresentShaderBase { public: void Bind() override; }; }