mirror of https://github.com/auygun/kaliber.git
165 lines
4.8 KiB
C++
165 lines
4.8 KiB
C++
#ifndef ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H
|
|
#define ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "engine/renderer/opengl/opengl.h"
|
|
#include "engine/renderer/renderer.h"
|
|
|
|
#if defined(__ANDROID__)
|
|
struct ANativeWindow;
|
|
#endif
|
|
|
|
namespace eng {
|
|
|
|
class RendererOpenGL final : public Renderer {
|
|
public:
|
|
RendererOpenGL(base::Closure context_lost_cb);
|
|
~RendererOpenGL() final;
|
|
|
|
bool Initialize(Platform* platform) final;
|
|
void Shutdown() final;
|
|
|
|
bool IsInitialzed() const final { return is_initialized_; }
|
|
|
|
void OnWindowResized(int width, int height) final;
|
|
|
|
int GetScreenWidth() const final;
|
|
int GetScreenHeight() const final;
|
|
|
|
void SetViewport(int x, int y, int width, int height) final;
|
|
void ResetViewport() final;
|
|
|
|
void SetScissor(int x, int y, int width, int height) final;
|
|
void ResetScissor() final;
|
|
|
|
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
|
void DestroyGeometry(uint64_t resource_id) final;
|
|
void Draw(uint64_t resource_id,
|
|
uint64_t num_indices = 0,
|
|
uint64_t start_offset = 0) final;
|
|
|
|
uint64_t CreateTexture() final;
|
|
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
|
void DestroyTexture(uint64_t resource_id) final;
|
|
void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
|
|
|
|
uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
|
|
const VertexDescription& vertex_description,
|
|
Primitive primitive,
|
|
bool enable_depth_test) final;
|
|
void DestroyShader(uint64_t resource_id) final;
|
|
void ActivateShader(uint64_t resource_id) final;
|
|
|
|
void SetUniform(uint64_t resource_id,
|
|
const std::string& name,
|
|
const base::Vector2f& val) final;
|
|
void SetUniform(uint64_t resource_id,
|
|
const std::string& name,
|
|
const base::Vector3f& val) final;
|
|
void SetUniform(uint64_t resource_id,
|
|
const std::string& name,
|
|
const base::Vector4f& val) final;
|
|
void SetUniform(uint64_t resource_id,
|
|
const std::string& name,
|
|
const base::Matrix4f& val) final;
|
|
void SetUniform(uint64_t resource_id,
|
|
const std::string& name,
|
|
float val) final;
|
|
void SetUniform(uint64_t resource_id, const std::string& name, int val) final;
|
|
void UploadUniforms(uint64_t resource_id) final {}
|
|
|
|
void PrepareForDrawing() final;
|
|
void Present() final;
|
|
|
|
size_t GetAndResetFPS() final;
|
|
|
|
const char* GetDebugName() final { return "OpenGL"; }
|
|
|
|
RendererType GetRendererType() final { return RendererType::kOpenGL; }
|
|
|
|
private:
|
|
struct GeometryOpenGL {
|
|
struct Element {
|
|
GLsizei num_elements;
|
|
GLenum type;
|
|
size_t vertex_offset;
|
|
};
|
|
|
|
GLsizei num_vertices = 0;
|
|
GLsizei num_indices = 0;
|
|
GLenum primitive = 0;
|
|
GLenum index_type = 0;
|
|
std::vector<Element> vertex_layout;
|
|
GLuint vertex_size = 0;
|
|
GLuint vertex_array_id = 0;
|
|
GLuint vertex_buffer_id = 0;
|
|
GLuint index_buffer_id = 0;
|
|
};
|
|
|
|
struct ShaderOpenGL {
|
|
GLuint id = 0;
|
|
std::vector<std::pair<size_t, // Uniform name hash
|
|
GLuint // Uniform index
|
|
>>
|
|
uniforms;
|
|
bool enable_depth_test = false;
|
|
};
|
|
|
|
std::unordered_map<uint64_t, GeometryOpenGL> geometries_;
|
|
std::unordered_map<uint64_t, ShaderOpenGL> shaders_;
|
|
std::unordered_map<uint64_t, GLuint> textures_;
|
|
uint64_t last_resource_id_ = 0;
|
|
|
|
GLuint active_shader_id_ = 0;
|
|
std::array<GLuint, kMaxTextureUnits> active_texture_id_ = {};
|
|
|
|
bool vertex_array_objects_ = false;
|
|
bool npot_ = false;
|
|
|
|
bool is_initialized_ = false;
|
|
|
|
// Stats.
|
|
size_t fps_ = 0;
|
|
|
|
int screen_width_ = 0;
|
|
int screen_height_ = 0;
|
|
|
|
#if defined(__ANDROID__)
|
|
ANativeWindow* window_ = nullptr;
|
|
#elif defined(__linux__)
|
|
Display* display_ = NULL;
|
|
Window window_ = 0;
|
|
GLXContext glx_context_ = NULL;
|
|
#elif defined(_WIN32)
|
|
HWND wnd_ = nullptr;
|
|
HDC dc_ = nullptr;
|
|
HGLRC glrc_ = nullptr;
|
|
#endif
|
|
|
|
bool InitCommon();
|
|
void ShutdownInternal();
|
|
void OnDestroy();
|
|
void ContextLost();
|
|
void DestroyAllResources();
|
|
|
|
bool SetupVertexLayout(const VertexDescription& vd,
|
|
GLuint vertex_size,
|
|
bool use_vao,
|
|
std::vector<GeometryOpenGL::Element>& vertex_layout);
|
|
GLuint CreateShader(const char* source, GLenum type);
|
|
bool BindAttributeLocation(GLuint id, const VertexDescription& vd);
|
|
GLint GetUniformLocation(GLuint id,
|
|
const std::string& name,
|
|
std::vector<std::pair<size_t, GLuint>>& uniforms);
|
|
};
|
|
|
|
} // namespace eng
|
|
|
|
#endif // ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H
|