Browse Source

rename data structure in shader.h to consistent style

main
cinnaboot 5 years ago
parent
commit
99db662ac5
  1. 2
      src/main.cpp
  2. 60
      src/shader.cpp
  3. 41
      src/shader.h
  4. 14
      src/tangerine.cpp
  5. 8
      src/tangerine.h

2
src/main.cpp

@ -15,7 +15,7 @@ loadScene(RenderState* rs)
// NOTE: the default shaders already have their attribute mappings created // NOTE: the default shaders already have their attribute mappings created
// in initRenderState, but if you use a custom shader, you will need to // in initRenderState, but if you use a custom shader, you will need to
// create a GLBufferToAttribMapping manually // create a GLBufferToAttribMapping manually
shader_program* s_default = getShaderByName("default", rs->gl_ctx); ShaderProgram* s_default = getShaderByName("default", rs->gl_ctx);
if (!s_default) return false; if (!s_default) return false;
// NOTE: init new render group // NOTE: init new render group

60
src/shader.cpp

@ -20,9 +20,9 @@
// NOTE: forward declarations // NOTE: forward declarations
const std::string dumpTextFile(const char* filepath); const std::string dumpTextFile(const char* filepath);
bool parseShader(MemoryArena* arena, GLContext* gl_ctx, shader_program* s); bool parseShader(MemoryArena* arena, GLContext* gl_ctx, ShaderProgram* s);
void initCTXSizes(GLContext* gl_ctx); void initCTXSizes(GLContext* gl_ctx);
bool compileAndLinkShader(shader_program* shader, bool compileAndLinkShader(ShaderProgram* shader,
const char* vert_src, const char* vert_src,
const char* frag_src, const char* frag_src,
GLuint& vs_id, GLuint& vs_id,
@ -53,7 +53,7 @@ addShaderProgram(MemoryArena* arena,
return false; return false;
} }
shader_program* s = getFreeShader(gl_ctx); ShaderProgram* s = getFreeShader(gl_ctx);
if (s) { if (s) {
s->name = arenaCopyCStr(arena, name); s->name = arenaCopyCStr(arena, name);
@ -87,7 +87,7 @@ addShaderProgram(MemoryArena* arena,
return false; return false;
} }
shader_program* ShaderProgram*
getFreeShader(GLContext* gl_ctx) getFreeShader(GLContext* gl_ctx)
{ {
if (gl_ctx->num_shaders >= gl_ctx->max_shaders) { if (gl_ctx->num_shaders >= gl_ctx->max_shaders) {
@ -95,11 +95,11 @@ getFreeShader(GLContext* gl_ctx)
return nullptr; return nullptr;
} }
shader_program* s = &gl_ctx->shaders[gl_ctx->num_shaders++]; ShaderProgram* s = &gl_ctx->shaders[gl_ctx->num_shaders++];
return s; return s;
} }
shader_program* ShaderProgram*
getShaderByHash(GLContext* gl_ctx, u64 hash) getShaderByHash(GLContext* gl_ctx, u64 hash)
{ {
for (u32 i; i < gl_ctx->num_shaders; i++) { for (u32 i; i < gl_ctx->num_shaders; i++) {
@ -110,7 +110,7 @@ getShaderByHash(GLContext* gl_ctx, u64 hash)
return nullptr; return nullptr;
} }
shader_program* ShaderProgram*
getShaderByName(const char* name, GLContext* gl_ctx) getShaderByName(const char* name, GLContext* gl_ctx)
{ {
// FIXME: no reason to use hashes here. should use std::strncmp instead // FIXME: no reason to use hashes here. should use std::strncmp instead
@ -125,7 +125,7 @@ getShaderByName(const char* name, GLContext* gl_ctx)
return nullptr; return nullptr;
} }
shader_program* ShaderProgram*
getShaderByID(GLContext* gl_ctx, GLuint prog_id) getShaderByID(GLContext* gl_ctx, GLuint prog_id)
{ {
for (u32 i = 0; i < gl_ctx->num_shaders; i++) { for (u32 i = 0; i < gl_ctx->num_shaders; i++) {
@ -167,7 +167,7 @@ getGLTexture(GLContext* gl_ctx, util_image* diffuse_img)
void void
renderVAO(GLmesh* glmesh, renderVAO(GLmesh* glmesh,
glm::mat4* model_xform, glm::mat4* model_xform,
shader_program* shader, ShaderProgram* shader,
GLuint tex_id) GLuint tex_id)
{ {
glUseProgram(shader->prog_id); glUseProgram(shader->prog_id);
@ -188,8 +188,8 @@ renderVAO(GLmesh* glmesh,
void void
initTransforms(MemoryArena* arena, initTransforms(MemoryArena* arena,
transforms* xforms, Transforms* xforms,
gl_buffer* xform_ubo, GLBuffer* xform_ubo,
GLContext* gl_ctx, GLContext* gl_ctx,
float fov, float fov,
float near_clip_plane, float near_clip_plane,
@ -216,7 +216,7 @@ initTransforms(MemoryArena* arena,
} }
GLVertexAttrib* GLVertexAttrib*
getVertexAttribByName(shader_program* shader, const char* name) getVertexAttribByName(ShaderProgram* shader, const char* name)
{ {
for (u32 i = 0; i < shader->num_vertex_attribs; i++) { for (u32 i = 0; i < shader->num_vertex_attribs; i++) {
if (strncmp(shader->vertex_attribs[i].name, name, 256) == 0) if (strncmp(shader->vertex_attribs[i].name, name, 256) == 0)
@ -235,8 +235,8 @@ initGLmesh(const mesh& m, u32 num_mappings, GLenum draw_mode)
glm.draw_mode = draw_mode; glm.draw_mode = draw_mode;
glm.usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes glm.usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes
glm.num_vertex_attrib_buffers = num_mappings; glm.num_vertex_attrib_buffers = num_mappings;
glm.vertex_attrib_buffers = UTIL_ALLOC(num_mappings, gl_buffer); glm.vertex_attrib_buffers = UTIL_ALLOC(num_mappings, GLBuffer);
glm.element_buf = UTIL_ALLOC(1, gl_buffer); glm.element_buf = UTIL_ALLOC(1, GLBuffer);
glm.model_xform = UTIL_ALLOC(1, glm::mat4); glm.model_xform = UTIL_ALLOC(1, glm::mat4);
*glm.model_xform = glm::mat4(1); *glm.model_xform = glm::mat4(1);
@ -244,7 +244,7 @@ initGLmesh(const mesh& m, u32 num_mappings, GLenum draw_mode)
} }
void void
initGLAttribBuffer(gl_buffer* buf, GLenum target, GLVertexAttrib* attrib) initGLAttribBuffer(GLBuffer* buf, GLenum target, GLVertexAttrib* attrib)
{ {
glGenBuffers(1, &buf->id); glGenBuffers(1, &buf->id);
buf->target = target; buf->target = target;
@ -263,14 +263,14 @@ loadGLMesh(const mesh& m,
GLBufferToAttribMapping mappings[]) GLBufferToAttribMapping mappings[])
{ {
// NOTE: need to use freeGLMesh() when freeing because we're not storing // NOTE: need to use freeGLMesh() when freeing because we're not storing
// the gl_buffers on a memory arean (yet) // the GLBuffers on a memory arean (yet)
GLmesh glm = initGLmesh(m, num_mappings, draw_mode); GLmesh glm = initGLmesh(m, num_mappings, draw_mode);
glm.tex_id = diffuse_texture_id; glm.tex_id = diffuse_texture_id;
glGenVertexArrays(1, &glm.vao_id); glGenVertexArrays(1, &glm.vao_id);
glBindVertexArray(glm.vao_id); glBindVertexArray(glm.vao_id);
for (u32 i = 0; i < num_mappings; i++) { for (u32 i = 0; i < num_mappings; i++) {
gl_buffer& buf = glm.vertex_attrib_buffers[i]; GLBuffer& buf = glm.vertex_attrib_buffers[i];
GLVertexAttrib* attrib = mappings[i].attrib; GLVertexAttrib* attrib = mappings[i].attrib;
u32 type_size = getGLTypeSize(attrib->data_type); u32 type_size = getGLTypeSize(attrib->data_type);
assert(type_size > 0); assert(type_size > 0);
@ -359,7 +359,7 @@ loadGLTexture(util_image* image, GLuint& tex_id)
} }
bool bool
compileAndLinkShader(shader_program* shader, compileAndLinkShader(ShaderProgram* shader,
const char* vert_src, const char* vert_src,
const char* frag_src, const char* frag_src,
GLuint& vs_id, GLuint& vs_id,
@ -435,10 +435,10 @@ getGLTypeSizeStd140(GLenum e)
} }
} }
const gl_uniform const GLUniform
parseUniform(MemoryArena* arena, shader_program* s, u32 uniform_idx) parseUniform(MemoryArena* arena, ShaderProgram* s, u32 uniform_idx)
{ {
gl_uniform unif = {0}; GLUniform unif = {0};
GLchar unif_name[256] = {0}; GLchar unif_name[256] = {0};
GLsizei name_len = 0; GLsizei name_len = 0;
@ -460,7 +460,7 @@ parseUniform(MemoryArena* arena, shader_program* s, u32 uniform_idx)
} }
bool bool
parseShaderUniforms(MemoryArena* arena, shader_program* s, GLContext* gl_ctx) parseShaderUniforms(MemoryArena* arena, ShaderProgram* s, GLContext* gl_ctx)
{ {
// NOTE: only add uniforms in the default block to the base uniform array // NOTE: only add uniforms in the default block to the base uniform array
GLint num_uniforms_total = 0; GLint num_uniforms_total = 0;
@ -478,10 +478,10 @@ parseShaderUniforms(MemoryArena* arena, shader_program* s, GLContext* gl_ctx)
} }
} }
s->uniforms = ARENA_ALLOC(arena, gl_uniform, s->num_uniforms); s->uniforms = ARENA_ALLOC(arena, GLUniform, s->num_uniforms);
for (u32 i = 0; i < s->num_uniforms; i++) { for (u32 i = 0; i < s->num_uniforms; i++) {
const gl_uniform unif = parseUniform(arena, s, indices[i]); const GLUniform unif = parseUniform(arena, s, indices[i]);
std::memcpy(&s->uniforms[i], &unif, sizeof(unif)); std::memcpy(&s->uniforms[i], &unif, sizeof(unif));
} }
@ -520,7 +520,7 @@ i32
ctxGetUniformBlockBinding(GLContext* gl_ctx, const char* name) ctxGetUniformBlockBinding(GLContext* gl_ctx, const char* name)
{ {
for (u32 i = 0; i < gl_ctx->num_ubos; i++) { for (u32 i = 0; i < gl_ctx->num_ubos; i++) {
gl_buffer& ubo = gl_ctx->uniform_buffers[i]; GLBuffer& ubo = gl_ctx->uniform_buffers[i];
if (std::strstr(ubo.name, name)) if (std::strstr(ubo.name, name))
return ubo.binding_idx; return ubo.binding_idx;
@ -531,7 +531,7 @@ ctxGetUniformBlockBinding(GLContext* gl_ctx, const char* name)
} }
bool bool
parseUniformBlocks(MemoryArena* arena, shader_program* s, GLContext* gl_ctx) parseUniformBlocks(MemoryArena* arena, ShaderProgram* s, GLContext* gl_ctx)
{ {
glGetProgramiv(s->prog_id, GL_ACTIVE_UNIFORM_BLOCKS, glGetProgramiv(s->prog_id, GL_ACTIVE_UNIFORM_BLOCKS,
(GLint*) &s->num_blocks); (GLint*) &s->num_blocks);
@ -549,13 +549,13 @@ parseUniformBlocks(MemoryArena* arena, shader_program* s, GLContext* gl_ctx)
glGetActiveUniformBlockiv(s->prog_id, i, glGetActiveUniformBlockiv(s->prog_id, i,
GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, (GLint*) &ub.num_uniforms); GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, (GLint*) &ub.num_uniforms);
ub.uniforms = ARENA_ALLOC(arena, gl_uniform, ub.num_uniforms); ub.uniforms = ARENA_ALLOC(arena, GLUniform, ub.num_uniforms);
GLint indices[ub.num_uniforms] = {0}; GLint indices[ub.num_uniforms] = {0};
glGetActiveUniformBlockiv(s->prog_id, i, glGetActiveUniformBlockiv(s->prog_id, i,
GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*) &indices); GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*) &indices);
for (u32 j = 0; j < ub.num_uniforms; j++) { for (u32 j = 0; j < ub.num_uniforms; j++) {
const gl_uniform unif = parseUniform(arena, s, indices[j]); const GLUniform unif = parseUniform(arena, s, indices[j]);
std::memcpy(&ub.uniforms[j], &unif, sizeof(unif)); std::memcpy(&ub.uniforms[j], &unif, sizeof(unif));
} }
@ -598,7 +598,7 @@ getAttribComponentType(GLenum type)
} }
bool bool
parseAttributes(MemoryArena* arena, shader_program* s, GLContext* gl_ctx) parseAttributes(MemoryArena* arena, ShaderProgram* s, GLContext* gl_ctx)
{ {
GLint num_attribs; GLint num_attribs;
glGetProgramiv(s->prog_id, GL_ACTIVE_ATTRIBUTES, &num_attribs); glGetProgramiv(s->prog_id, GL_ACTIVE_ATTRIBUTES, &num_attribs);
@ -630,7 +630,7 @@ parseAttributes(MemoryArena* arena, shader_program* s, GLContext* gl_ctx)
} }
bool bool
parseShader(MemoryArena* arena, GLContext* gl_ctx, shader_program* s) parseShader(MemoryArena* arena, GLContext* gl_ctx, ShaderProgram* s)
{ {
if (parseShaderUniforms(arena, s, gl_ctx) if (parseShaderUniforms(arena, s, gl_ctx)
&& parseUniformBlocks(arena, s, gl_ctx) && parseUniformBlocks(arena, s, gl_ctx)

41
src/shader.h

@ -9,8 +9,7 @@
#include "util.h" #include "util.h"
// TODO: rename structures to consistent style struct GLUniform
struct gl_uniform
{ {
// NOTE: would be nice to use idx as the location parameter because it seems // 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 // to match when the uniform isn't part of a uniform block, at least with
@ -29,7 +28,7 @@ struct GLUniformBlock
GLuint block_id; GLuint block_id;
GLint binding_idx; GLint binding_idx;
GLuint num_uniforms; GLuint num_uniforms;
gl_uniform* uniforms; GLUniform* uniforms;
char* name; char* name;
}; };
@ -42,8 +41,8 @@ enum MeshBufferType
MESH_BUFFER_TYPE_COUNT MESH_BUFFER_TYPE_COUNT
}; };
// NOTE: we need another struct for vertex attributes that mirrors gl_buffer // NOTE: we need another struct for vertex attributes that mirrors GLBuffer
// because an attribute is associated with a shader_program while a buffer is // because an attribute is associated with a ShaderProgram while a buffer is
// associated with the vertex data passed to glBufferData() // associated with the vertex data passed to glBufferData()
struct GLVertexAttrib struct GLVertexAttrib
{ {
@ -61,7 +60,7 @@ struct GLBufferToAttribMapping
MeshBufferType buf_type; MeshBufferType buf_type;
}; };
struct shader_program struct ShaderProgram
{ {
GLuint prog_id; GLuint prog_id;
GLuint xforms_ubo_id; GLuint xforms_ubo_id;
@ -72,7 +71,7 @@ struct shader_program
GLUniformBlock* uniform_blocks; GLUniformBlock* uniform_blocks;
u32 num_uniforms; u32 num_uniforms;
gl_uniform* uniforms; GLUniform* uniforms;
u32 num_vertex_attribs; u32 num_vertex_attribs;
GLVertexAttrib* vertex_attribs; GLVertexAttrib* vertex_attribs;
@ -82,7 +81,7 @@ struct shader_program
u64 hash; // NOTE: hash of vs filpath + fs filepath concat u64 hash; // NOTE: hash of vs filpath + fs filepath concat
}; };
struct gl_buffer struct GLBuffer
{ {
GLuint id; GLuint id;
GLenum target; GLenum target;
@ -112,11 +111,11 @@ struct GLContext
u32 max_ubos; u32 max_ubos;
u32 num_ubos; u32 num_ubos;
gl_buffer* uniform_buffers; GLBuffer* uniform_buffers;
u32 max_shaders; u32 max_shaders;
u32 num_shaders; u32 num_shaders;
shader_program* shaders; ShaderProgram* shaders;
u32 max_textures; u32 max_textures;
u32 num_textures; u32 num_textures;
@ -135,8 +134,8 @@ struct GLmesh
glm::mat4* model_xform; glm::mat4* model_xform;
u32 num_vertex_attrib_buffers; u32 num_vertex_attrib_buffers;
gl_buffer* vertex_attrib_buffers; GLBuffer* vertex_attrib_buffers;
gl_buffer* element_buf; GLBuffer* element_buf;
}; };
struct Animation; struct Animation;
@ -148,7 +147,7 @@ struct PointLight
u32 intensity; u32 intensity;
}; };
struct transforms struct Transforms
{ {
glm::mat4 view_xform; glm::mat4 view_xform;
glm::mat4 proj_xform; glm::mat4 proj_xform;
@ -172,22 +171,22 @@ bool addShaderProgram(MemoryArena* arena,
const char* fs, const char* fs,
const char* name); const char* name);
shader_program* getShaderByName(const char* name, GLContext* gl_ctx); ShaderProgram* getShaderByName(const char* name, GLContext* gl_ctx);
shader_program* getShaderByID(GLContext* gl_ctx, GLuint prog_id); ShaderProgram* getShaderByID(GLContext* gl_ctx, GLuint prog_id);
shader_program* getShaderByHash(GLContext* gl_ctx, u64 hash); ShaderProgram* getShaderByHash(GLContext* gl_ctx, u64 hash);
shader_program* getFreeShader(GLContext* gl_ctx); ShaderProgram* getFreeShader(GLContext* gl_ctx);
GLTexture* getGLTexture(GLContext* gl_ctx, util_image* diffuse_img); GLTexture* getGLTexture(GLContext* gl_ctx, util_image* diffuse_img);
void renderVAO(GLmesh* glmesh, void renderVAO(GLmesh* glmesh,
glm::mat4* model_xform, glm::mat4* model_xform,
shader_program* shader, ShaderProgram* shader,
GLuint tex_id = 0); GLuint tex_id = 0);
GLVertexAttrib* getVertexAttribByName(shader_program* shader, const char* name); GLVertexAttrib* getVertexAttribByName(ShaderProgram* shader, const char* name);
GLmesh loadGLMesh(const mesh& m, GLmesh loadGLMesh(const mesh& m,
GLenum draw_mode, GLenum draw_mode,
@ -196,8 +195,8 @@ GLmesh loadGLMesh(const mesh& m,
GLBufferToAttribMapping mappings[]); GLBufferToAttribMapping mappings[]);
void initTransforms(MemoryArena* arena, void initTransforms(MemoryArena* arena,
transforms* xforms, Transforms* xforms,
gl_buffer* xform_ubo, GLBuffer* xform_ubo,
GLContext* gl_ctx, GLContext* gl_ctx,
float fov = DEFAULT_FOV, float fov = DEFAULT_FOV,
float near_clip_plane = NEAR_CLIP_PLANE, float near_clip_plane = NEAR_CLIP_PLANE,

14
src/tangerine.cpp

@ -46,12 +46,12 @@ initRenderState(u32 max_models,
max_textures, max_textures,
max_ubos); max_ubos);
rs->xforms = ARENA_ALLOC(rs->assets.arena, transforms, 1); rs->xforms = ARENA_ALLOC(rs->assets.arena, Transforms, 1);
rs->handles = UTIL_ALLOC(1, SDLHandles); rs->handles = UTIL_ALLOC(1, SDLHandles);
initGraphics(rs->handles); initGraphics(rs->handles);
// FIXME: need to test this with another shader that has another UBO // FIXME: need to test this with another shader that has another UBO
gl_buffer& ubo = rs->gl_ctx->uniform_buffers[rs->gl_ctx->num_ubos++]; GLBuffer& ubo = rs->gl_ctx->uniform_buffers[rs->gl_ctx->num_ubos++];
initTransforms(rs->assets.arena, rs->xforms, &ubo, rs->gl_ctx); initTransforms(rs->assets.arena, rs->xforms, &ubo, rs->gl_ctx);
bool ret = loadDefaultShaders(rs); bool ret = loadDefaultShaders(rs);
@ -80,7 +80,7 @@ freeRenderState(RenderState*& rs)
void void
initRenderGroup(RenderGroup* rg, initRenderGroup(RenderGroup* rg,
MemoryArena* arena, MemoryArena* arena,
shader_program* shader, ShaderProgram* shader,
u32 num_entities, u32 num_entities,
const char* name) const char* name)
{ {
@ -199,7 +199,7 @@ loadDefaultShaders(RenderState* rs,
} }
// TODO: need to set the mappings here // TODO: need to set the mappings here
shader_program* shader = getShaderByName(si.name, rs->gl_ctx); ShaderProgram* shader = getShaderByName(si.name, rs->gl_ctx);
assert(shader); assert(shader);
// NOTE: not every buffer will be available for every shader, so we // NOTE: not every buffer will be available for every shader, so we
@ -219,7 +219,7 @@ loadDefaultShaders(RenderState* rs,
} }
GLVertexAttrib* GLVertexAttrib*
getVertexAttribByType(shader_program* shader, MeshBufferType buf_type) getVertexAttribByType(ShaderProgram* shader, MeshBufferType buf_type)
{ {
switch (buf_type) { switch (buf_type) {
case VERTEX: return getVertexAttribByName(shader, "position"); case VERTEX: return getVertexAttribByName(shader, "position");
@ -295,9 +295,9 @@ initGLContext(MemoryArena* arena,
{ {
GLContext* gl_ctx = ARENA_ALLOC(arena, GLContext, 1); GLContext* gl_ctx = ARENA_ALLOC(arena, GLContext, 1);
gl_ctx->max_shaders = max_shaders; gl_ctx->max_shaders = max_shaders;
gl_ctx->shaders = ARENA_ALLOC(arena, shader_program, max_shaders); gl_ctx->shaders = ARENA_ALLOC(arena, ShaderProgram, max_shaders);
gl_ctx->max_ubos = max_ubos; gl_ctx->max_ubos = max_ubos;
gl_ctx->uniform_buffers = ARENA_ALLOC(arena, gl_buffer, max_ubos); gl_ctx->uniform_buffers = ARENA_ALLOC(arena, GLBuffer, max_ubos);
gl_ctx->max_textures = max_textures; gl_ctx->max_textures = max_textures;
gl_ctx->textures = ARENA_ALLOC(arena, GLTexture, max_textures); gl_ctx->textures = ARENA_ALLOC(arena, GLTexture, max_textures);

8
src/tangerine.h

@ -60,7 +60,7 @@ struct Node;
struct RenderGroup struct RenderGroup
{ {
shader_program* shader; ShaderProgram* shader;
u32 num_entities; u32 num_entities;
u32 max_entities; u32 max_entities;
Entity* entities; Entity* entities;
@ -78,7 +78,7 @@ struct GLClearColor
struct RenderState struct RenderState
{ {
bool running; bool running;
transforms* xforms; // NOTE: would be part of camera in libTangerine Transforms* xforms; // NOTE: would be part of camera in libTangerine
SDLHandles* handles; SDLHandles* handles;
GLContext* gl_ctx; GLContext* gl_ctx;
Assets assets; Assets assets;
@ -114,7 +114,7 @@ void freeRenderState(RenderState*& rs);
#define DEFAULT_ENTITY_COUNT 256 #define DEFAULT_ENTITY_COUNT 256
void initRenderGroup(RenderGroup* rg, void initRenderGroup(RenderGroup* rg,
MemoryArena* arena, MemoryArena* arena,
shader_program* shader, ShaderProgram* shader,
u32 num_entities = DEFAULT_ENTITY_COUNT, u32 num_entities = DEFAULT_ENTITY_COUNT,
const char* name = ""); const char* name = "");
@ -172,5 +172,5 @@ bool loadDefaultShaders(RenderState* rs,
// NOTE: only useful if the shader attribute names match the names in the // NOTE: only useful if the shader attribute names match the names in the
// default shaders. If loading a custom shader, this may not work as expected, // default shaders. If loading a custom shader, this may not work as expected,
// and you should use getVertexAttribByName instead // and you should use getVertexAttribByName instead
GLVertexAttrib* getVertexAttribByType(shader_program* shader, GLVertexAttrib* getVertexAttribByType(ShaderProgram* shader,
MeshBufferType buf_type); MeshBufferType buf_type);

Loading…
Cancel
Save