cleaned up the opengl implementation

This commit is contained in:
Noel Berry 2020-08-28 19:35:10 -07:00
parent a9087d10bf
commit e70d7a11a0
2 changed files with 488 additions and 558 deletions

View File

@ -29,6 +29,7 @@ namespace Blah
bool valid = false; bool valid = false;
GraphicsInfo info; GraphicsInfo info;
virtual ~GraphicsDevice() = default;
virtual void startup() = 0; virtual void startup() = 0;
virtual void update() = 0; virtual void update() = 0;
virtual void shutdown() = 0; virtual void shutdown() = 0;

View File

@ -1,14 +1,14 @@
#include <blah/graphics/graphics.h> #include <blah/graphics/graphics.h>
#include <blah/internal/graphics.h> #include <blah/internal/graphics.h>
#ifdef BLAH_USE_OPENGL
#include <blah/internal/platform.h> #include <blah/internal/platform.h>
#include <blah/graphics/texture.h> #include <blah/graphics/texture.h>
#include <blah/graphics/framebuffer.h> #include <blah/graphics/framebuffer.h>
#include <blah/graphics/mesh.h> #include <blah/graphics/mesh.h>
#include <blah/graphics/shader.h> #include <blah/graphics/shader.h>
#include <blah/graphics/material.h> #include <blah/graphics/material.h>
#ifdef BLAH_USE_OPENGL
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
@ -19,6 +19,7 @@
#define APIENTRY #define APIENTRY
#endif #endif
// OpenGL Value Types
typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLintptr;
typedef ptrdiff_t GLsizeiptr; typedef ptrdiff_t GLsizeiptr;
typedef unsigned int GLenum; typedef unsigned int GLenum;
@ -38,6 +39,7 @@ typedef double GLdouble; /* double precision float */
typedef double GLclampd; /* double precision float in [0,1] */ typedef double GLclampd; /* double precision float in [0,1] */
typedef char GLchar; typedef char GLchar;
// OpenGL Constants
#define GL_DONT_CARE 0x1100 #define GL_DONT_CARE 0x1100
#define GL_ZERO 0x0000 #define GL_ZERO 0x0000
#define GL_ONE 0x0001 #define GL_ONE 0x0001
@ -226,6 +228,113 @@ typedef char GLchar;
#define GL_DEBUG_OUTPUT 0x92E0 #define GL_DEBUG_OUTPUT 0x92E0
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
// OpenGL Functions
#define GL_FUNCTIONS \
GL_FUNC(DebugMessageCallback, void, DEBUGPROC callback, const void* userParam) \
GL_FUNC(GetString, const GLubyte*, GLenum name) \
GL_FUNC(Flush, void, void) \
GL_FUNC(Enable, void, GLenum mode) \
GL_FUNC(Disable, void, GLenum mode) \
GL_FUNC(Clear, void, GLenum mask) \
GL_FUNC(ClearColor, void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
GL_FUNC(ClearDepth, void, GLdouble depth) \
GL_FUNC(ClearStencil, void, GLint stencil) \
GL_FUNC(DepthMask, void, GLboolean enabled) \
GL_FUNC(DepthFunc, void, GLenum func) \
GL_FUNC(Viewport, void, GLint x, GLint y, GLint width, GLint height) \
GL_FUNC(Scissor, void, GLint x, GLint y, GLint width, GLint height) \
GL_FUNC(CullFace, void, GLenum mode) \
GL_FUNC(BlendEquation, void, GLenum eq) \
GL_FUNC(BlendEquationSeparate, void, GLenum modeRGB, GLenum modeAlpha) \
GL_FUNC(BlendFunc, void, GLenum sfactor, GLenum dfactor) \
GL_FUNC(BlendFuncSeparate, void, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) \
GL_FUNC(BlendColor, void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
GL_FUNC(ColorMask, void, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) \
GL_FUNC(GetIntegerv, void, GLenum name, GLint* data) \
GL_FUNC(GenTextures, void, GLint n, void* textures) \
GL_FUNC(GenRenderbuffers, void, GLint n, void* textures) \
GL_FUNC(GenFramebuffers, void, GLint n, void* textures) \
GL_FUNC(ActiveTexture, void, GLuint id) \
GL_FUNC(BindTexture, void, GLenum target, GLuint id) \
GL_FUNC(BindRenderbuffer, void, GLenum target, GLuint id) \
GL_FUNC(BindFramebuffer, void, GLenum target, GLuint id) \
GL_FUNC(TexImage2D, void, GLenum target, GLint level, GLenum internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, void* data) \
GL_FUNC(FramebufferRenderbuffer, void, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
GL_FUNC(FramebufferTexture2D, void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
GL_FUNC(TexParameteri, void, GLenum target, GLenum name, GLint param) \
GL_FUNC(RenderbufferStorage, void, GLenum target, GLenum internalformat, GLint width, GLint height) \
GL_FUNC(GetTexImage, void, GLenum target, GLint level, GLenum format, GLenum type, void* data) \
GL_FUNC(DrawElements, void, GLenum mode, GLint count, GLenum type, void* indices) \
GL_FUNC(DrawElementsInstanced, void, GLenum mode, GLint count, GLenum type, void* indices, GLint amount) \
GL_FUNC(DeleteTextures, void, GLint n, GLuint* textures) \
GL_FUNC(DeleteRenderbuffers, void, GLint n, GLuint* renderbuffers) \
GL_FUNC(DeleteFramebuffers, void, GLint n, GLuint* textures) \
GL_FUNC(GenVertexArrays, void, GLint n, GLuint* arrays) \
GL_FUNC(BindVertexArray, void, GLuint id) \
GL_FUNC(GenBuffers, void, GLint n, GLuint* arrays) \
GL_FUNC(BindBuffer, void, GLenum target, GLuint buffer) \
GL_FUNC(BufferData, void, GLenum target, GLsizeiptr size, const void* data, GLenum usage) \
GL_FUNC(BufferSubData, void, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) \
GL_FUNC(DeleteBuffers, void, GLint n, GLuint* buffers) \
GL_FUNC(DeleteVertexArrays, void, GLint n, GLuint* arrays) \
GL_FUNC(EnableVertexAttribArray, void, GLuint location) \
GL_FUNC(DisableVertexAttribArray, void, GLuint location) \
GL_FUNC(VertexAttribPointer, void, GLuint index, GLint size, GLenum type, GLboolean normalized, GLint stride, const void* pointer) \
GL_FUNC(VertexAttribDivisor, void, GLuint index, GLuint divisor) \
GL_FUNC(CreateShader, GLuint, GLenum type) \
GL_FUNC(AttachShader, void, GLuint program, GLuint shader) \
GL_FUNC(DetachShader, void, GLuint program, GLuint shader) \
GL_FUNC(DeleteShader, void, GLuint shader) \
GL_FUNC(ShaderSource, void, GLuint shader, GLsizei count, const GLchar** string, const GLint* length) \
GL_FUNC(CompileShader, void, GLuint shader) \
GL_FUNC(GetShaderiv, void, GLuint shader, GLenum pname, GLint* result) \
GL_FUNC(GetShaderInfoLog, void, GLuint shader, GLint maxLength, GLsizei* length, GLchar* infoLog) \
GL_FUNC(CreateProgram, GLuint, ) \
GL_FUNC(DeleteProgram, void, GLuint program) \
GL_FUNC(LinkProgram, void, GLuint program) \
GL_FUNC(GetProgramiv, void, GLuint program, GLenum pname, GLint* result) \
GL_FUNC(GetProgramInfoLog, void, GLuint program, GLint maxLength, GLsizei* length, GLchar* infoLog) \
GL_FUNC(GetActiveUniform, void, GLuint program, GLuint index, GLint bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) \
GL_FUNC(GetActiveAttrib, void, GLuint program, GLuint index, GLint bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) \
GL_FUNC(UseProgram, void, GLuint program) \
GL_FUNC(GetUniformLocation, GLint, GLuint program, const GLchar* name) \
GL_FUNC(GetAttribLocation, GLint, GLuint program, const GLchar* name) \
GL_FUNC(Uniform1f, void, GLint location, GLfloat v0) \
GL_FUNC(Uniform2f, void, GLint location, GLfloat v0, GLfloat v1) \
GL_FUNC(Uniform3f, void, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
GL_FUNC(Uniform4f, void, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
GL_FUNC(Uniform1fv, void, GLint location, GLint count, const GLfloat* value) \
GL_FUNC(Uniform2fv, void, GLint location, GLint count, const GLfloat* value) \
GL_FUNC(Uniform3fv, void, GLint location, GLint count, const GLfloat* value) \
GL_FUNC(Uniform4fv, void, GLint location, GLint count, const GLfloat* value) \
GL_FUNC(Uniform1i, void, GLint location, GLint v0) \
GL_FUNC(Uniform2i, void, GLint location, GLint v0, GLint v1) \
GL_FUNC(Uniform3i, void, GLint location, GLint v0, GLint v1, GLint v2) \
GL_FUNC(Uniform4i, void, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) \
GL_FUNC(Uniform1iv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform2iv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform3iv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform4iv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform1ui, void, GLint location, GLuint v0) \
GL_FUNC(Uniform2ui, void, GLint location, GLuint v0, GLuint v1) \
GL_FUNC(Uniform3ui, void, GLint location, GLuint v0, GLuint v1, GLuint v2) \
GL_FUNC(Uniform4ui, void, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) \
GL_FUNC(Uniform1uiv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform2uiv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform3uiv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(Uniform4uiv, void, GLint location, GLint count, const GLint* value) \
GL_FUNC(UniformMatrix2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix2x3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix3x2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix2x4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix4x2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix3x4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(UniformMatrix4x3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value) \
GL_FUNC(PixelStorei, void, GLenum pname, GLint param)
// Debug Function Delegate
typedef void (APIENTRY* DEBUGPROC)(GLenum source, typedef void (APIENTRY* DEBUGPROC)(GLenum source,
GLenum type, GLenum type,
GLuint id, GLuint id,
@ -234,136 +343,54 @@ typedef void (APIENTRY *DEBUGPROC)(GLenum source,
const GLchar* message, const GLchar* message,
const void* userParam); const void* userParam);
#define GL_FUNC(name, ret, ...) \
typedef ret (*name ## Func) (__VA_ARGS__); \
name ## Func name
#define GL_BIND(name) gl.name = (GL::name ## Func)(Internal::Platform::gl_get_func("gl" #name));
namespace Blah namespace Blah
{ {
namespace OpenGL namespace OpenGL
{ {
// GL function pointers
struct GL struct GL
{ {
GL_FUNC(DebugMessageCallback, void, DEBUGPROC callback, const void* userParam); #define GL_FUNC(name, ret, ...) typedef ret (*name ## Func) (__VA_ARGS__); name ## Func name;
GL_FUNC(GetString, const GLubyte*, GLenum name); GL_FUNCTIONS
GL_FUNC(Flush, void, void); #undef GL_FUNC
GL_FUNC(Enable, void, GLenum mode);
GL_FUNC(Disable, void, GLenum mode);
GL_FUNC(Clear, void, GLenum mask);
GL_FUNC(ClearColor, void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_FUNC(ClearDepth, void, GLdouble depth);
GL_FUNC(ClearStencil, void, GLint stencil);
GL_FUNC(DepthMask, void, GLboolean enabled);
GL_FUNC(DepthFunc, void, GLenum func);
GL_FUNC(Viewport, void, GLint x, GLint y, GLint width, GLint height);
GL_FUNC(Scissor, void, GLint x, GLint y, GLint width, GLint height);
GL_FUNC(CullFace, void, GLenum mode);
GL_FUNC(BlendEquation, void, GLenum eq);
GL_FUNC(BlendEquationSeparate, void, GLenum modeRGB, GLenum modeAlpha);
GL_FUNC(BlendFunc, void, GLenum sfactor, GLenum dfactor);
GL_FUNC(BlendFuncSeparate, void, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
GL_FUNC(BlendColor, void, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_FUNC(ColorMask, void, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
GL_FUNC(GetIntegerv, void, GLenum name, GLint* data);
GL_FUNC(GenTextures, void, GLint n, void* textures);
GL_FUNC(GenRenderbuffers, void, GLint n, void* textures);
GL_FUNC(GenFramebuffers, void, GLint n, void* textures);
GL_FUNC(ActiveTexture, void, GLuint id);
GL_FUNC(BindTexture, void, GLenum target, GLuint id);
GL_FUNC(BindRenderbuffer, void, GLenum target, GLuint id);
GL_FUNC(BindFramebuffer, void, GLenum target, GLuint id);
GL_FUNC(TexImage2D, void, GLenum target, GLint level, GLenum internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, void* data);
GL_FUNC(FramebufferRenderbuffer, void, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
GL_FUNC(FramebufferTexture2D, void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GL_FUNC(TexParameteri, void, GLenum target, GLenum name, GLint param);
GL_FUNC(RenderbufferStorage, void, GLenum target, GLenum internalformat, GLint width, GLint height);
GL_FUNC(GetTexImage, void, GLenum target, GLint level, GLenum format, GLenum type, void* data);
GL_FUNC(DrawElements, void, GLenum mode, GLint count, GLenum type, void* indices);
GL_FUNC(DrawElementsInstanced, void, GLenum mode, GLint count, GLenum type, void* indices, GLint amount);
GL_FUNC(DeleteTextures, void, GLint n, GLuint* textures);
GL_FUNC(DeleteRenderbuffers, void, GLint n, GLuint* renderbuffers);
GL_FUNC(DeleteFramebuffers, void, GLint n, GLuint* textures);
GL_FUNC(GenVertexArrays, void, GLint n, GLuint* arrays);
GL_FUNC(BindVertexArray, void, GLuint id);
GL_FUNC(GenBuffers, void, GLint n, GLuint* arrays);
GL_FUNC(BindBuffer, void, GLenum target, GLuint buffer);
GL_FUNC(BufferData, void, GLenum target, GLsizeiptr size, const void* data, GLenum usage);
GL_FUNC(BufferSubData, void, GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
GL_FUNC(DeleteBuffers, void, GLint n, GLuint* buffers);
GL_FUNC(DeleteVertexArrays, void, GLint n, GLuint* arrays);
GL_FUNC(EnableVertexAttribArray, void, GLuint location);
GL_FUNC(DisableVertexAttribArray, void, GLuint location);
GL_FUNC(VertexAttribPointer, void, GLuint index, GLint size, GLenum type, GLboolean normalized, GLint stride, const void* pointer);
GL_FUNC(VertexAttribDivisor, void, GLuint index, GLuint divisor);
GL_FUNC(CreateShader, GLuint, GLenum type);
GL_FUNC(AttachShader, void, GLuint program, GLuint shader);
GL_FUNC(DetachShader, void, GLuint program, GLuint shader);
GL_FUNC(DeleteShader, void, GLuint shader);
GL_FUNC(ShaderSource, void, GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
GL_FUNC(CompileShader, void, GLuint shader);
GL_FUNC(GetShaderiv, void, GLuint shader, GLenum pname, GLint* result);
GL_FUNC(GetShaderInfoLog, void, GLuint shader, GLint maxLength, GLsizei* length, GLchar* infoLog);
GL_FUNC(CreateProgram, GLuint, );
GL_FUNC(DeleteProgram, void, GLuint program);
GL_FUNC(LinkProgram, void, GLuint program);
GL_FUNC(GetProgramiv, void, GLuint program, GLenum pname, GLint* result);
GL_FUNC(GetProgramInfoLog, void, GLuint program, GLint maxLength, GLsizei* length, GLchar* infoLog);
GL_FUNC(GetActiveUniform, void, GLuint program, GLuint index, GLint bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GL_FUNC(GetActiveAttrib, void, GLuint program, GLuint index, GLint bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GL_FUNC(UseProgram, void, GLuint program);
GL_FUNC(GetUniformLocation, GLint, GLuint program, const GLchar* name);
GL_FUNC(GetAttribLocation, GLint, GLuint program, const GLchar* name);
GL_FUNC(Uniform1f, void, GLint location, GLfloat v0);
GL_FUNC(Uniform2f, void, GLint location, GLfloat v0, GLfloat v1);
GL_FUNC(Uniform3f, void, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
GL_FUNC(Uniform4f, void, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
GL_FUNC(Uniform1fv, void, GLint location, GLint count, const GLfloat* value);
GL_FUNC(Uniform2fv, void, GLint location, GLint count, const GLfloat* value);
GL_FUNC(Uniform3fv, void, GLint location, GLint count, const GLfloat* value);
GL_FUNC(Uniform4fv, void, GLint location, GLint count, const GLfloat* value);
GL_FUNC(Uniform1i, void, GLint location, GLint v0);
GL_FUNC(Uniform2i, void, GLint location, GLint v0, GLint v1);
GL_FUNC(Uniform3i, void, GLint location, GLint v0, GLint v1, GLint v2);
GL_FUNC(Uniform4i, void, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
GL_FUNC(Uniform1iv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform2iv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform3iv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform4iv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform1ui, void, GLint location, GLuint v0);
GL_FUNC(Uniform2ui, void, GLint location, GLuint v0, GLuint v1);
GL_FUNC(Uniform3ui, void, GLint location, GLuint v0, GLuint v1, GLuint v2);
GL_FUNC(Uniform4ui, void, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
GL_FUNC(Uniform1uiv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform2uiv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform3uiv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(Uniform4uiv, void, GLint location, GLint count, const GLint* value);
GL_FUNC(UniformMatrix2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix2x3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix3x2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix2x4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix4x2fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix3x4fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(UniformMatrix4x3fv, void, GLint location, GLint count, GLboolean transpose, const GLfloat* value);
GL_FUNC(PixelStorei, void, GLenum pname, GLint param);
}; };
// static state // static function pointers
// TODO: // TODO:
// this should probably be part of the Device implementation ... // this should move into the Device, as on windows it's not guaranteed that these function
void* context; // pointers are the same between contexts. this doesn't matter right now since we only create
// a single context, but will potentially need to change.
// reference: https://wiki.libsdl.org/SDL_GL_GetProcAddress
GL gl; GL gl;
GLint maxColorAttachments;
GLint maxElementIndices;
GLint maxElementVertices;
GLint maxRenderBufferSize;
GLint maxSamples;
GLint maxTextureImageUnits;
GLint maxTextureSize;
class Device : public Internal::GraphicsDevice
{
public:
void* context = nullptr;
GLint max_color_attachments = 0;
GLint max_element_indices = 0;
GLint max_element_vertices = 0;
GLint max_renderbuffer_size = 0;
GLint max_samples = 0;
GLint max_texture_image_units = 0;
GLint max_texture_size = 0;
inline virtual void startup() override;
inline virtual void shutdown() override;
inline virtual void update() override {}
inline virtual void before_render() override {}
inline virtual void after_render() override {}
inline virtual TextureRef create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format) override;
inline virtual FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount) override;
inline virtual ShaderRef create_shader(const ShaderData* data) override;
inline virtual MeshRef create_mesh() override;
inline virtual void render(RenderCall* call) override;
inline virtual void clear(const FrameBufferRef& target, uint32_t rgba) override;
};
// debug callback
void APIENTRY gl_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) void APIENTRY gl_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
{ {
// these are basically never useful // these are basically never useful
@ -403,6 +430,7 @@ namespace Blah
Log::print("GL (%s) %s", typeName, message); Log::print("GL (%s) %s", typeName, message);
} }
// assign attributes
GLuint gl_mesh_assign_attributes(GLuint buffer, GLenum buffer_type, const VertexAttribute* vertex_attributes, int vertex_attribute_count, int stride, GLint divisor) GLuint gl_mesh_assign_attributes(GLuint buffer, GLenum buffer_type, const VertexAttribute* vertex_attributes, int vertex_attribute_count, int stride, GLint divisor)
{ {
// bind // bind
@ -459,6 +487,7 @@ namespace Blah
return stride; return stride;
} }
// convert blend op enum
GLenum gl_get_blend_func(BlendOp operation) GLenum gl_get_blend_func(BlendOp operation)
{ {
switch (operation) switch (operation)
@ -472,6 +501,7 @@ namespace Blah
return GL_FUNC_ADD; return GL_FUNC_ADD;
} }
// convert blend factor enum
GLenum gl_get_blend_factor(BlendFactor factor) GLenum gl_get_blend_factor(BlendFactor factor)
{ {
switch (factor) switch (factor)
@ -517,7 +547,7 @@ namespace Blah
public: public:
bool framebuffer_parent; bool framebuffer_parent;
OpenGL_Texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format) OpenGL_Texture(Device* device, int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
{ {
m_id = 0; m_id = 0;
m_width = width; m_width = width;
@ -531,9 +561,9 @@ namespace Blah
m_gl_format = GL_RED; m_gl_format = GL_RED;
m_gl_type = GL_UNSIGNED_BYTE; m_gl_type = GL_UNSIGNED_BYTE;
if (width > maxTextureSize || height > maxTextureSize) if (width > device->max_texture_size || height > device->max_texture_size)
{ {
Log::error("Exceeded Max Texture Size of %i", maxTextureSize); Log::error("Exceeded Max Texture Size of %i", device->max_texture_size);
return; return;
} }
@ -689,7 +719,7 @@ namespace Blah
public: public:
OpenGL_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachmentCount) OpenGL_FrameBuffer(Device* device, int width, int height, const TextureFormat* attachments, int attachmentCount)
{ {
gl.GenFramebuffers(1, &m_id); gl.GenFramebuffers(1, &m_id);
m_width = width; m_width = width;
@ -776,7 +806,7 @@ namespace Blah
public: public:
GLint uniforms_loc[BLAH_UNIFORMS] = { 0 }; GLint uniforms_loc[BLAH_UNIFORMS] = { 0 };
OpenGL_Shader(const ShaderData* data) OpenGL_Shader(Device* device, const ShaderData* data)
{ {
m_id = 0; m_id = 0;
@ -936,6 +966,7 @@ namespace Blah
~OpenGL_Shader() ~OpenGL_Shader()
{ {
if (m_id > 0)
gl.DeleteProgram(m_id); gl.DeleteProgram(m_id);
m_id = 0; m_id = 0;
} }
@ -972,6 +1003,7 @@ namespace Blah
virtual void dispose() override virtual void dispose() override
{ {
if (m_id > 0)
gl.DeleteProgram(m_id); gl.DeleteProgram(m_id);
m_id = 0; m_id = 0;
} }
@ -996,7 +1028,7 @@ namespace Blah
public: public:
OpenGL_Mesh() OpenGL_Mesh(Device* device)
{ {
m_id = 0; m_id = 0;
m_index_buffer = 0; m_index_buffer = 0;
@ -1142,9 +1174,7 @@ namespace Blah
} }
}; };
class Device : public Internal::GraphicsDevice void Device::startup()
{
virtual void startup() override
{ {
valid = true; valid = true;
@ -1159,109 +1189,9 @@ namespace Blah
Internal::Platform::gl_context_make_current(context); Internal::Platform::gl_context_make_current(context);
// bind opengl functions // bind opengl functions
GL_BIND(DebugMessageCallback); #define GL_FUNC(name, ...) gl.name = (GL::name ## Func)(Internal::Platform::gl_get_func("gl" #name));
GL_BIND(GetString); GL_FUNCTIONS
GL_BIND(Flush); #undef GL_FUNC
GL_BIND(Enable);
GL_BIND(Disable);
GL_BIND(Clear);
GL_BIND(ClearColor);
GL_BIND(ClearDepth);
GL_BIND(ClearStencil);
GL_BIND(DepthMask);
GL_BIND(DepthFunc);
GL_BIND(Viewport);
GL_BIND(Scissor);
GL_BIND(CullFace);
GL_BIND(BlendEquation);
GL_BIND(BlendEquationSeparate);
GL_BIND(BlendFunc);
GL_BIND(BlendFuncSeparate);
GL_BIND(BlendColor);
GL_BIND(ColorMask);
GL_BIND(GetIntegerv);
GL_BIND(GenTextures);
GL_BIND(GenRenderbuffers);
GL_BIND(GenFramebuffers);
GL_BIND(ActiveTexture);
GL_BIND(BindTexture);
GL_BIND(BindRenderbuffer);
GL_BIND(BindFramebuffer);
GL_BIND(TexImage2D);
GL_BIND(FramebufferRenderbuffer);
GL_BIND(FramebufferTexture2D);
GL_BIND(TexParameteri);
GL_BIND(RenderbufferStorage);
GL_BIND(GetTexImage);
GL_BIND(DrawElements);
GL_BIND(DrawElementsInstanced);
GL_BIND(DeleteTextures);
GL_BIND(DeleteRenderbuffers);
GL_BIND(DeleteFramebuffers);
GL_BIND(GenVertexArrays);
GL_BIND(BindVertexArray);
GL_BIND(GenBuffers);
GL_BIND(BindBuffer);
GL_BIND(BufferData);
GL_BIND(BufferSubData);
GL_BIND(DeleteBuffers);
GL_BIND(DeleteVertexArrays);
GL_BIND(EnableVertexAttribArray);
GL_BIND(DisableVertexAttribArray);
GL_BIND(VertexAttribPointer);
GL_BIND(VertexAttribDivisor);
GL_BIND(CreateShader);
GL_BIND(AttachShader);
GL_BIND(DetachShader);
GL_BIND(DeleteShader);
GL_BIND(ShaderSource);
GL_BIND(CompileShader);
GL_BIND(GetShaderiv);
GL_BIND(GetShaderInfoLog);
GL_BIND(CreateProgram);
GL_BIND(DeleteProgram);
GL_BIND(LinkProgram);
GL_BIND(GetProgramiv);
GL_BIND(GetProgramInfoLog);
GL_BIND(GetActiveUniform);
GL_BIND(GetActiveAttrib);
GL_BIND(UseProgram);
GL_BIND(GetUniformLocation);
GL_BIND(GetAttribLocation);
GL_BIND(Uniform1f);
GL_BIND(Uniform2f);
GL_BIND(Uniform3f);
GL_BIND(Uniform4f);
GL_BIND(Uniform1fv);
GL_BIND(Uniform2fv);
GL_BIND(Uniform3fv);
GL_BIND(Uniform4fv);
GL_BIND(Uniform1i);
GL_BIND(Uniform2i);
GL_BIND(Uniform3i);
GL_BIND(Uniform4i);
GL_BIND(Uniform1iv);
GL_BIND(Uniform2iv);
GL_BIND(Uniform3iv);
GL_BIND(Uniform4iv);
GL_BIND(Uniform1ui);
GL_BIND(Uniform2ui);
GL_BIND(Uniform3ui);
GL_BIND(Uniform4ui);
GL_BIND(Uniform1uiv);
GL_BIND(Uniform2uiv);
GL_BIND(Uniform3uiv);
GL_BIND(Uniform4uiv);
GL_BIND(UniformMatrix2fv);
GL_BIND(UniformMatrix3fv);
GL_BIND(UniformMatrix4fv);
GL_BIND(UniformMatrix2x3fv);
GL_BIND(UniformMatrix3x2fv);
GL_BIND(UniformMatrix2x4fv);
GL_BIND(UniformMatrix4x2fv);
GL_BIND(UniformMatrix3x4fv);
GL_BIND(UniformMatrix4x3fv);
GL_BIND(PixelStorei);
// bind debug message callback // bind debug message callback
if (gl.DebugMessageCallback != nullptr) if (gl.DebugMessageCallback != nullptr)
@ -1272,13 +1202,13 @@ namespace Blah
} }
// get opengl info // get opengl info
gl.GetIntegerv(0x8CDF, &maxColorAttachments); gl.GetIntegerv(0x8CDF, &max_color_attachments);
gl.GetIntegerv(0x80E9, &maxElementIndices); gl.GetIntegerv(0x80E9, &max_element_indices);
gl.GetIntegerv(0x80E8, &maxElementVertices); gl.GetIntegerv(0x80E8, &max_element_vertices);
gl.GetIntegerv(0x84E8, &maxRenderBufferSize); gl.GetIntegerv(0x84E8, &max_renderbuffer_size);
gl.GetIntegerv(0x8D57, &maxSamples); gl.GetIntegerv(0x8D57, &max_samples);
gl.GetIntegerv(0x8872, &maxTextureImageUnits); gl.GetIntegerv(0x8872, &max_texture_image_units);
gl.GetIntegerv(0x0D33, &maxTextureSize); gl.GetIntegerv(0x0D33, &max_texture_size);
// log // log
Log::print("OpenGL %s, %s", Log::print("OpenGL %s, %s",
@ -1293,40 +1223,36 @@ namespace Blah
info.api = GfxAPI::OpenGL; info.api = GfxAPI::OpenGL;
info.instancing = true; info.instancing = true;
info.origin_bottom_left = true; info.origin_bottom_left = true;
info.max_texture_size = maxTextureSize; info.max_texture_size = max_texture_size;
} }
virtual void shutdown() override void Device::shutdown()
{ {
Internal::Platform::gl_context_destroy(context); Internal::Platform::gl_context_destroy(context);
context = nullptr; context = nullptr;
} }
virtual void update() override {} TextureRef Device::create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
virtual void before_render() override {}
virtual void after_render() override {}
virtual TextureRef create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format) override
{ {
return TextureRef(new OpenGL_Texture(width, height, filter, wrap_x, wrap_y, format)); return TextureRef(new OpenGL_Texture(this, width, height, filter, wrap_x, wrap_y, format));
} }
virtual FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount) override FrameBufferRef Device::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
{ {
return FrameBufferRef(new OpenGL_FrameBuffer(width, height, attachments, attachmentCount)); return FrameBufferRef(new OpenGL_FrameBuffer(this, width, height, attachments, attachmentCount));
} }
virtual ShaderRef create_shader(const ShaderData* data) override ShaderRef Device::create_shader(const ShaderData* data)
{ {
return ShaderRef(new OpenGL_Shader(data)); return ShaderRef(new OpenGL_Shader(this, data));
} }
virtual MeshRef create_mesh() override MeshRef Device::create_mesh()
{ {
return MeshRef(new OpenGL_Mesh()); return MeshRef(new OpenGL_Mesh(this));
} }
virtual void render(RenderCall* call) override void Device::render(RenderCall* call)
{ {
// Bind the Target // Bind the Target
Point size; Point size;
@ -1338,15 +1264,19 @@ namespace Blah
} }
else else
{ {
gl.BindFramebuffer(GL_FRAMEBUFFER, ((OpenGL_FrameBuffer*)call->target.get())->gl_id()); auto framebuffer = (OpenGL_FrameBuffer*)call->target.get();
gl.BindFramebuffer(GL_FRAMEBUFFER, framebuffer->gl_id());
size.x = call->target->width(); size.x = call->target->width();
size.y = call->target->height(); size.y = call->target->height();
} }
auto shader_ref = call->material->shader();
auto shader = (OpenGL_Shader*)shader_ref.get();
auto mesh = (OpenGL_Mesh*)call->mesh.get();
// Use the Shader // Use the Shader
// TODO: I don't love how material values are assigned or set here // TODO: I don't love how material values are assigned or set here
{ {
OpenGL_Shader* shader = (OpenGL_Shader*)(call->material->shader().get());
gl.UseProgram(shader->gl_id()); gl.UseProgram(shader->gl_id());
// upload uniform values // upload uniform values
@ -1539,7 +1469,7 @@ namespace Blah
// Draw the Mesh // Draw the Mesh
{ {
gl.BindVertexArray(((OpenGL_Mesh*)call->mesh.get())->gl_id()); gl.BindVertexArray(mesh->gl_id());
if (call->instance_count > 0) if (call->instance_count > 0)
{ {
@ -1563,7 +1493,7 @@ namespace Blah
} }
} }
virtual void clear(const FrameBufferRef& target, uint32_t rgba) override void Device::clear(const FrameBufferRef& target, uint32_t rgba)
{ {
if (!target || !target->is_valid()) if (!target || !target->is_valid())
{ {
@ -1585,7 +1515,6 @@ namespace Blah
gl.ClearColor(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); gl.ClearColor(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
gl.Clear(GL_COLOR_BUFFER_BIT); gl.Clear(GL_COLOR_BUFFER_BIT);
} }
};
bool supported() bool supported()
{ {