Browse Source

add full lighting shader with debug values

main
cinnaboot 5 years ago
parent
commit
3c9b7c9376
  1. 60
      data/full_lighting.frag
  2. 27
      data/full_lighting.vert
  3. 1
      data/texture_only.frag
  4. 0
      data/texture_only.vert
  5. 40
      src/main.cpp
  6. 2
      src/shader.h
  7. 17
      src/tangerine.cpp
  8. 27
      src/tangerine.h

60
data/full_lighting.frag

@ -0,0 +1,60 @@
#version 330 core
in vec3 frag_pos;
in vec3 frag_normal;
in vec2 frag_uv;
out vec4 color;
layout (std140) uniform matrices
{
mat4 view_xform;
mat4 proj_xform;
mat4 normal_xform;
};
uniform mat4 node_xform;
uniform sampler2D sampler;
struct PointLight
{
vec3 pos;
vec3 color;
float intensity;
};
struct DirectionalLight
{
vec3 direction;
vec3 color;
float intensity;
};
// FIXME: probably want a buffer-backed UBO for lights in case we have more
// than one shader that does lighting calculations
//uniform PointLight lights[32];
// FIXME: hard-coded values for testing
const DirectionalLight dl1 =
DirectionalLight(vec3(-2, 1, 3), vec3(1,1,1), 1);
const vec4 ambient_color = vec4(0.1, 0.1, 0.1, 1);
const PointLight pl1 = PointLight(vec3(-20, 10, 30), vec3(1, 1, 1), 800);
void main()
{
#if 1 // directional light
vec3 light_direction = normalize(dl1.direction);
float diffuse_factor = clamp(dot(frag_normal, light_direction), 0, 1);
vec4 diffuse_color = dl1.intensity * vec4(dl1.color * diffuse_factor, 1);
#else // point light
vec3 light_direction = pl1.pos - frag_pos;
float len = length(light_direction);
light_direction = normalize(light_direction);
float diffuse_factor = dot(frag_normal, light_direction) / pow(len, 2);
diffuse_factor = clamp(diffuse_factor, 0, 1);
vec4 diffuse_color = pl1.intensity * vec4(pl1.color * diffuse_factor, 1);
#endif
color = (ambient_color + diffuse_color) * texture(sampler, frag_uv.st);
}

27
data/full_lighting.vert

@ -0,0 +1,27 @@
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uv;
out vec3 frag_pos;
out vec3 frag_normal;
out vec2 frag_uv;
layout (std140) uniform matrices
{
mat4 view_xform;
mat4 proj_xform;
mat4 normal_xform;
};
uniform mat4 node_xform;
void main()
{
frag_pos = (node_xform * vec4(position, 1)).xyz;
frag_uv = uv;
frag_normal = normalize(mat3(node_xform) * normal);
gl_Position = proj_xform * view_xform * node_xform * vec4(position, 1);
}

1
data/shader.frag → data/texture_only.frag

@ -14,6 +14,7 @@ layout (std140) uniform matrices
uniform mat4 node_xform;
uniform sampler2D sampler;
void main()
{
color = texture(sampler, frag_uv.st);

0
data/shader.vert → data/texture_only.vert

40
src/main.cpp

@ -15,13 +15,13 @@ loadScene(RenderState* rs)
// NOTE: the default shaders already have their attribute mappings created
// in initRenderState, but if you use a custom shader, you will need to
// create a GLBufferToAttribMapping manually
ShaderProgram* s_default = getShaderByName("default", rs->gl_ctx);
if (!s_default) return false;
ShaderProgram* shader_lit = getShaderByName("full_lighting", rs->gl_ctx);
if (!shader_lit) return false;
// NOTE: init new render group
RenderGroup* textured_cubes = getFreeRenderGroup(rs);
assert(textured_cubes);
initRenderGroup(textured_cubes, rs->rg_arena, s_default, 256,
initRenderGroup(textured_cubes, rs->rg_arena, shader_lit, 256,
"textured_cubes");
// NOTE: init entities
@ -45,8 +45,8 @@ loadScene(RenderState* rs)
rs->gl_ctx,
rs->rg_arena,
tex_cube,
s_default->num_vertex_attribs,
s_default->attrib_mappings,
shader_lit->num_vertex_attribs,
shader_lit->attrib_mappings,
cube_name))
{
return false;
@ -56,6 +56,36 @@ loadScene(RenderState* rs)
scaleEntity(e, 3);
}
// NOTE: add a point light
PointLight* l1 = &rs->lights[rs->num_lights++];
l1->position = glm::vec3(-20, 10, 30);
l1->color = glm::vec3(1, 1, 1);
l1->intensity = 256;
// NOTE: add a debug mesh to view the light source
RenderGroup* debug_group = getFreeRenderGroup(rs);
assert(debug_group);
ShaderProgram* s_debug = getShaderByName("debug", rs->gl_ctx);
assert(s_debug);
initRenderGroup(debug_group, rs->rg_arena, s_debug, 256, "debug_lights");
for (u32 i = 0; i < rs->num_lights; i++) {
PointLight* l = &rs->lights[i];
Entity* e = getFreeEntity(debug_group);
assert(e);
if (!initEntity(e,
rs->gl_ctx,
rs->rg_arena,
tex_cube,
s_debug->num_vertex_attribs,
s_debug->attrib_mappings))
{
return false;
}
setEntityPosition(e, l->position);
}
return true;
}

2
src/shader.h

@ -158,7 +158,7 @@ struct Transforms
const float DEFAULT_FOV = 60.f;
const float NEAR_CLIP_PLANE = 5.f;
const float DEFAULT_ASPECT_RATIO = 16.f / 9.f;
const glm::vec3 DEFAULT_CAM_POS = { 0, 0, 30.f };
const glm::vec3 DEFAULT_CAM_POS = { 0, 0, 50.f };
const glm::vec3 DEFAULT_LOOK_POS = { 0, 0, 0 };

17
src/tangerine.cpp

@ -41,6 +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);
rs->gl_ctx = initGLContext(rs->assets.arena,
max_shaders,
max_textures,
@ -188,18 +192,17 @@ loadDefaultShaders(RenderState* rs,
{
for (u32 i = 0; i < num_shaders; i++) {
const ShaderInit& si = shaders[i];
bool ret = addShaderProgram(rs->assets.arena,
rs->gl_ctx,
si.vert_path,
si.frag_path,
si.name);
if (!ret) {
if (!addShaderProgram(rs->assets.arena,
rs->gl_ctx,
si.vert_path,
si.frag_path,
si.name))
{
LOG(Error) << "failed to load shader " << si.name << "\n";
return false;
}
// TODO: need to set the mappings here
ShaderProgram* shader = getShaderByName(si.name, rs->gl_ctx);
assert(shader);

27
src/tangerine.h

@ -15,8 +15,12 @@
/*
* === TODO: ===
* - full lighting model
* - add buffer backed storage for light arrays in GLSL
* - remove hard-coded values in full_lighting.frag
* - test complex entities
* - need a separate GLBufferToAttribMapping for each mesh on an entity
* - maybe fixed now with MeshBufferType enum and getMeshData()
* - add an example of dynamically switching shaders for an entity
* - fix debug load times (either by using cgltf, or hiding tinygltf.h)
* - RenderGroups and Entities need to come into and out of existence during
* gameplay. So, we need to extend MemoryArena to be a pool allocator
@ -79,6 +83,7 @@ struct GLClearColor
struct RenderState
{
bool running;
GLClearColor clear_col;
Transforms* xforms; // NOTE: would be part of camera in libTangerine
SDLHandles* handles;
GLContext* gl_ctx;
@ -89,13 +94,13 @@ struct RenderState
u32 max_render_groups;
RenderGroup* render_groups;
GLClearColor clear_col;
// TODO: full lighting
#if 0
// TODO: should we have a 'scene' abstraction here?
// could have render groups, lights, camera
// could match up with gltf scene graph where everyting is part of a node
// TODO: will also need other types of lights: directional, spotlight
u32 num_lights;
u32 max_lights;
PointLight* lights;
#endif
};
@ -149,19 +154,23 @@ struct ShaderInit
const char* frag_path;
};
#define DEFAULT_SHADER_INIT { "default", \
"../data/shader.vert", \
"../data/shader.frag" }
#define SHADER_INIT_COUNT 4
#define TEXTURE_ONLY_SHADER_INIT { "texture_only", \
"../data/texture_only.vert", \
"../data/texture_only.frag" }
#define FULL_LIGHTING_SHADER_INIT { "full_lighting", \
"../data/full_lighting.vert", \
"../data/full_lighting.frag" }
#define DEBUG_SHADER_INIT { "debug", \
"../data/debug.vert", \
"../data/debug.frag", }
#define COLORED_VERT_SHADER_INIT { "colored_vertices", \
"../data/colored_vertices.vert", \
"../data/colored_vertices.frag", }
#define SHADER_INIT_COUNT 3
const ShaderInit SHADER_INIT_LIST[SHADER_INIT_COUNT]
{
DEFAULT_SHADER_INIT,
TEXTURE_ONLY_SHADER_INIT,
FULL_LIGHTING_SHADER_INIT,
DEBUG_SHADER_INIT,
COLORED_VERT_SHADER_INIT
};

Loading…
Cancel
Save