A small OpenGL 3+ renderer and game engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

214 lines
4.5 KiB

#pragma once
#include <SDL2/SDL.h>
#include <GL/glew.h>
#define GLM_FORCE_XYZW_ONLY
#include <glm/glm.hpp>
#include "asset.h"
#include "types.h"
#include "util.h"
enum UniformType
{
UNIFORM_SAMPLER,
UNIFORM_NODE_XFORM,
UNIFORM_VIEW_XFORM,
UNIFORM_PROJECTION_XFORM,
UNIFORM_NORMAL_XFORM,
UNIFORM_BLOCK_XFORMS,
UNIFORM_BLOCK_LIGHTS,
UNIFORM_UNKNOWN,
UNIFORM_TYPE_COUNT
};
struct GLUniform
{
// NOTE: would be nice to use idx as the location parameter because it seems
// to match when the uniform isn't part of a uniform block, at least with
// intel mesa driver, but apparently that's not guarantied
GLuint idx;
GLint location;
GLint block_idx;
UniformType uniform_type;
GLenum gl_type; // NOTE: GL_UNSIGNED_INT, GL_FLOAT_VEC4
GLint num_elements; // NOTE: 1 unless uniform is an array of base types
GLint array_stride; // NOTE: bytes between array elements
GLint uniform_offset; // NOTE: byte offset from beginning of uniform
char* name;
};
struct GLUniformBlock
{
GLuint block_id;
GLint binding_idx;
UniformType uniform_type;
GLuint num_uniforms;
GLUniform* uniforms;
char* name;
};
enum MeshBufferType
{
VERTEX,
NORMAL,
UV,
COLOR,
MESH_BUFFER_TYPE_COUNT
};
// NOTE: we need another struct for vertex attributes that mirrors GLBuffer
// because an attribute is associated with a ShaderProgram while a buffer is
// associated with the vertex data passed to glBufferData()
struct GLVertexAttrib
{
MeshBufferType buf_type;
GLenum data_type;
GLenum component_type;
u32 num_components;
GLuint location;
char* name;
};
// TODO: add a note explaining usage when we implement complex entities
struct GLBufferToAttribMapping
{
GLVertexAttrib* attrib;
MeshBufferType buf_type;
};
struct ShaderProgram
{
GLuint prog_id;
u32 num_blocks;
GLUniformBlock* uniform_blocks;
u32 num_uniforms;
GLUniform* uniforms;
u32 num_vertex_attribs;
GLVertexAttrib* vertex_attribs;
GLBufferToAttribMapping* attrib_mappings;
char* name;
u64 hash; // NOTE: hash of vs filpath + fs filepath concat
};
struct GLBuffer
{
GLuint id;
GLenum target;
GLenum data_type;
GLuint data_size; // NOTE: size of buffer in bytes
GLint location; // NOTE: if used as backing for vertex attribute
GLint binding_idx; // NOTE: if used as backing from uniform buffer object
char* name;
};
struct GLTexture
{
GLuint id;
GLenum pixel_format; // NOTE: GL_RGB or GL_RGBA
u32 width;
u32 height;
u64 filepath_hash;
};
struct GLContext
{
GLuint binding_count;
GLint max_binding_points;
GLint max_vertex_blocks;
GLint max_fragment_blocks;
GLint max_ublock_size;
GLint max_vertex_attribs;
u32 max_ubos;
u32 num_ubos;
GLBuffer* uniform_buffers;
u32 max_shaders;
u32 num_shaders;
ShaderProgram* shaders;
u32 max_textures;
u32 num_textures;
GLTexture* textures;
};
struct GLMesh
{
u32 num_indices;
GLuint vao_id;
bool has_texture;
GLuint tex_id;
mat4* node_xform;
u32 num_vertex_attrib_buffers;
GLBuffer* vertex_attrib_buffers;
GLBuffer* element_buf;
};
struct Animation;
GLContext* initGLContext(MemoryArena* arena,
u32 max_shaders,
u32 max_textures,
u32 max_ubos);
// TODO: add more notes here describing the internals? This is the entry point
// to a complex process of programatically assigning properties to our notion
// of what a shader needs ie) uniforms, buffer block bindings, etc
// NOTE: every shader program is assumed to have one uniform block named
// "matrices" that contains the projection and view matrices, and one uniform
// named "node_xform" for the node matrix
bool addShaderProgram(MemoryArena* arena,
GLContext* gl_ctx,
const char* vs,
const char* fs,
const char* name);
ShaderProgram* getShaderByName(const char* name, GLContext* gl_ctx);
ShaderProgram* getShaderByID(GLContext* gl_ctx, GLuint prog_id);
ShaderProgram* getShaderByHash(GLContext* gl_ctx, u64 hash);
ShaderProgram* getFreeShader(GLContext* gl_ctx);
GLBuffer* getFreeUBO(GLContext* gl_ctx);
GLBuffer* getUBOByName(GLContext* gl_ctx, const char* name);
GLTexture* getGLTexture(GLContext* gl_ctx, Texture* diffuse_img);
GLBuffer* initGLBackingBuffer(GLContext* gl_ctx,
MemoryArena* arena,
const char* name,
GLenum data_type,
u32 buf_size,
void* data);
void updateGLBuffer(GLBuffer* gl_buf, void* data);
void renderVAO(GLMesh* glmesh,
mat4* node_xform,
ShaderProgram* shader,
GLTexture* gl_tex,
GLenum draw_mode);
GLVertexAttrib* getVertexAttribByName(ShaderProgram* shader, const char* name);
GLMesh loadGLMesh(MemoryArena* arena,
const Mesh& m,
GLenum draw_mode,
GLenum usage,
GLTexture* diffuse_texture,
u32 num_mappings,
GLBufferToAttribMapping mappings[]);