Browse Source

load a dummy shader to init GLContext limits

This solves a chicken and egg problem when loading shaders that need to
know about GLContext limits.

Also moved initGLContext() from tangerine.cpp to shader.cpp
main
cinnaboot 5 years ago
parent
commit
79b20bb6b0
  1. 30
      src/dummy_shader.h
  2. 41
      src/shader.cpp
  3. 5
      src/shader.h
  4. 33
      src/tangerine.cpp
  5. 14
      src/tangerine.h

30
src/dummy_shader.h

@ -0,0 +1,30 @@
#pragma once
const char* DUMMY_VERTEX_SHADER = R"VS(
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 world_transform;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * world_transform * vec4(position, 1);
}
)VS";
const char* DUMMY_FRAGMENT_SHADER = R"FS(
#version 330 core
out vec4 color;
void main()
{
color = vec4(1, 0, 0, 1);
}
)FS";

41
src/shader.cpp

@ -12,6 +12,7 @@
#include "asset.h"
#include "dumbLog.h"
#include "dummy_shader.h"
#define GL_DEBUG_IMPLEMENTATION
#include "GLDebug.h"
#include "shader.h"
@ -22,6 +23,7 @@
const std::string dumpTextFile(const char* filepath);
bool parseShader(MemoryArena* arena, GLContext* gl_ctx, ShaderProgram* s);
void loadDummyShader();
void initCTXSizes(GLContext* gl_ctx);
bool compileAndLinkShader(ShaderProgram* shader,
const char* vert_src,
@ -36,6 +38,28 @@ void* getMeshData(const Mesh& m, const GLBufferToAttribMapping& mapping);
// NOTE: interface
GLContext*
initGLContext(MemoryArena* arena,
u32 max_shaders,
u32 max_textures,
u32 max_ubos)
{
GLContext* gl_ctx = ARENA_ALLOC(arena, GLContext, 1);
gl_ctx->max_shaders = max_shaders;
gl_ctx->shaders = ARENA_ALLOC(arena, ShaderProgram, max_shaders);
gl_ctx->max_ubos = max_ubos;
gl_ctx->uniform_buffers = ARENA_ALLOC(arena, GLBuffer, max_ubos);
gl_ctx->max_textures = max_textures;
gl_ctx->textures = ARENA_ALLOC(arena, GLTexture, max_textures);
// NOTE: load a dummy shader to avoid chicken and egg problem where we need
// GLContext info before we can parse a shader, which needs GLContext info
loadDummyShader();
initCTXSizes(gl_ctx);
return gl_ctx;
}
bool
addShaderProgram(MemoryArena* arena,
GLContext* gl_ctx,
@ -66,9 +90,6 @@ addShaderProgram(MemoryArena* arena,
GLuint vs_id, fs_id;
if (compileAndLinkShader(s, vert.c_str(), frag.c_str(), vs_id, fs_id)) {
// NOTE: we call this here because we can only make the GL_MAX*
// queries after at least one shader has been linked
initCTXSizes(gl_ctx);
s->node_xform_id = glGetUniformLocation(s->prog_id, "node_xform");
// TODO: add sampler uniform detection in dynamic shader parsing
s->sampler_id = glGetUniformLocation(s->prog_id, "sampler");
@ -418,6 +439,20 @@ dumpTextFile(const char* filepath)
return s;
}
void
loadDummyShader()
{
GLuint vs_id = 0, fs_id = 0;
ShaderProgram temp_shader = {0};
bool ret = compileAndLinkShader(&temp_shader,
DUMMY_VERTEX_SHADER,
DUMMY_FRAGMENT_SHADER,
vs_id,
fs_id);
assert(ret);
glDeleteProgram(temp_shader.prog_id);
}
u32
getGLTypeSize(GLenum e)
{

5
src/shader.h

@ -164,6 +164,11 @@ const glm::vec3 DEFAULT_CAM_POS = { 0, 0, 50.f };
const glm::vec3 DEFAULT_LOOK_POS = { 0, 0, 0 };
GLContext* initGLContext(MemoryArena* arena,
u32 max_shaders,
u32 max_textures,
u32 max_ubos);
// 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

33
src/tangerine.cpp

@ -41,9 +41,10 @@ initRenderState(u32 max_models,
rs->render_groups = ARENA_ALLOC(rs->rg_arena, RenderGroup,
DEFAULT_RENDER_GROUP_COUNT);
// FIXME: revisit for 'Scene' abstraction
rs->max_lights = 32;
rs->lights = ARENA_ALLOC(rs->rg_arena, PointLight, rs->max_lights);
if (!initGraphics(&rs->handles)) {
LOGF(Error, "error initializing renderer\n");
return nullptr;
}
rs->gl_ctx = initGLContext(rs->assets.arena,
max_shaders,
@ -51,8 +52,6 @@ initRenderState(u32 max_models,
max_ubos);
rs->xforms = ARENA_ALLOC(rs->assets.arena, Transforms, 1);
rs->handles = UTIL_ALLOC(1, SDLHandles);
initGraphics(rs->handles);
// FIXME: need to test this with another shader that has another UBO
GLBuffer& ubo = rs->gl_ctx->uniform_buffers[rs->gl_ctx->num_ubos++];
@ -69,11 +68,10 @@ void
freeRenderState(RenderState*& rs)
{
if (rs) {
SDL_GL_DeleteContext(rs->handles->sdl_gl_ctx);
SDL_DestroyWindow(rs->handles->window);
SDL_GL_DeleteContext(rs->handles.sdl_gl_ctx);
SDL_DestroyWindow(rs->handles.window);
arenaFree(rs->assets.arena);
arenaFree(rs->rg_arena);
utilSafeFree(rs->handles);
utilSafeFree(rs);
rs = nullptr;
}
@ -153,7 +151,7 @@ doRenderLoop(RenderState* rs,
if (cb_func_post != nullptr)
cb_func_post(rs);
SDL_GL_SwapWindow(rs->handles->window);
SDL_GL_SwapWindow(rs->handles.window);
frameTime = SDL_GetTicks() - frameStart;
if (delay > frameTime)
@ -291,20 +289,3 @@ initGraphics(SDLHandles* handles)
return handles->window != nullptr;
}
GLContext*
initGLContext(MemoryArena* arena,
u32 max_shaders,
u32 max_textures,
u32 max_ubos)
{
GLContext* gl_ctx = ARENA_ALLOC(arena, GLContext, 1);
gl_ctx->max_shaders = max_shaders;
gl_ctx->shaders = ARENA_ALLOC(arena, ShaderProgram, max_shaders);
gl_ctx->max_ubos = max_ubos;
gl_ctx->uniform_buffers = ARENA_ALLOC(arena, GLBuffer, max_ubos);
gl_ctx->max_textures = max_textures;
gl_ctx->textures = ARENA_ALLOC(arena, GLTexture, max_textures);
return gl_ctx;
}

14
src/tangerine.h

@ -106,12 +106,24 @@ struct GLClearColor
GLfloat A;
};
// NOTE: structure to match the layout of the 'lights' uniform in a shader
struct LightsBuffer
{
u32 active_p_lights;
u32 max_p_lights;
u32 active_d_lights;
u32 max_d_lights;
// FIXME: do we need any padding here for layout(std 140)?
PointLight* p_lights;
PointLight* d_lights; // TODO: directional lights
};
struct RenderState
{
bool running;
GLClearColor clear_col;
Transforms* xforms; // NOTE: would be part of camera in libTangerine
SDLHandles* handles;
SDLHandles handles;
GLContext* gl_ctx;
Assets assets;

Loading…
Cancel
Save