Added Diffuse Light to LitScene

YES! FINALLY LIGHTING! Next up is specular light!
This commit is contained in:
elipzer 2018-09-14 21:29:05 -04:00
parent af20d28442
commit 9920dfc25b
17 changed files with 203 additions and 43 deletions

View File

@ -0,0 +1,29 @@
#include "BasicBatch.h"
namespace charcoal
{
namespace builtin
{
void BasicBatch::setup_vao()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BasicVertex), NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_element_buffers[0]);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(0 * sizeof(vec4)));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(1 * sizeof(vec4)));
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(2 * sizeof(vec4)));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(3 * sizeof(vec4)));
glVertexAttribDivisor(0, 0); // Send the mesh data once
glVertexAttribDivisor(1, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(2, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(3, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(4, 1); // Send the offset data for each instance drawn
}
}
}

30
OpenGLEngine/BasicBatch.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include "PoseableBatch.h"
#include "BuiltinTypes.h"
namespace charcoal
{
namespace builtin
{
class BasicBatch : public PoseableBatch<BasicVertex, BasicIndex, BasicRenderable>
{
public:
BasicBatch(
BasicRenderable* renderable,
int element_count
) : PoseableBatch<BasicVertex, BasicIndex, BasicRenderable>(renderable, element_count)
{}
BasicBatch(
BasicRenderable* renderable,
int element_count,
int element_render_count
) : PoseableBatch<BasicVertex, BasicIndex, BasicRenderable>(renderable, element_count, element_render_count)
{}
protected:
void setup_vao() override;
};
}
}

View File

@ -8,6 +8,7 @@
#include "BuiltinTypes.h"
#include "Camera2D.h"
#include "Batched.h"
#include "BasicBatch.h"
#include "constants.h"

View File

@ -41,9 +41,12 @@ namespace charcoal
struct Light
{
Light(const ColorRGB& ambient) : ambient(ambient) {}
Light(const Position& position, const ColorRGB& ambient, const ColorRGB& diffuse)
: position(position), ambient(ambient), diffuse(diffuse) {}
Position position;
ColorRGB ambient;
ColorRGB diffuse;
};
// typedefs for builtin types
@ -51,11 +54,9 @@ namespace charcoal
typedef PVertex BasicVertex;
typedef Index BasicIndex;
typedef Renderable<BasicVertex, BasicIndex> BasicRenderable;
typedef PoseableBatch<BasicVertex, BasicIndex> BasicBatch;
typedef PNVertex LitVertex;
typedef Index LitIndex;
typedef Renderable<LitVertex, LitIndex> LitRenderable;
typedef PoseableBatch<LitVertex, LitIndex> LitBatch;
}
}

View File

@ -30,12 +30,18 @@ namespace charcoal
void uniform_lights(int uniform_index, const std::vector<Light>& lights)
{
const int position_size = 1;
const int ambient_size = 1;
const int diffuse_size = 1;
int current_location = uniform_index;
for (std::vector<Light>::size_type i = 0; i < lights.size(); ++i)
{
glUniform3fv(current_location, 1, &lights[i].position[0]);
current_location += position_size;
glUniform3fv(current_location, 1, &lights[i].ambient[0]);
current_location += ambient_size;
glUniform3fv(current_location, 1, &lights[i].diffuse[0]);
current_location += diffuse_size;
}
}
}

32
OpenGLEngine/LitBatch.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "LitBatch.h"
namespace charcoal
{
namespace builtin
{
void LitBatch::setup_vao()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(LitVertex), (void*)(offsetof(LitVertex, position)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(LitVertex), (void*)(offsetof(LitVertex, normal)));
glBindBuffer(GL_ARRAY_BUFFER, m_element_buffers[0]);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(0 * sizeof(vec4)));
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(1 * sizeof(vec4)));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(2 * sizeof(vec4)));
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(3 * sizeof(vec4)));
glVertexAttribDivisor(0, 0); // Send the mesh data once
glVertexAttribDivisor(1, 0); // Send the mesh data once
glVertexAttribDivisor(2, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(3, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(4, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(5, 1); // Send the offset data for each instance drawn
}
}
}

30
OpenGLEngine/LitBatch.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include "PoseableBatch.h"
#include "BuiltinTypes.h"
namespace charcoal
{
namespace builtin
{
class LitBatch : public PoseableBatch<LitVertex, LitIndex, LitRenderable>
{
public:
LitBatch(
LitRenderable* renderable,
int element_count
) : PoseableBatch<LitVertex, LitIndex, LitRenderable>(renderable, element_count)
{}
LitBatch(
LitRenderable* renderable,
int element_count,
int element_render_count
) : PoseableBatch<LitVertex, LitIndex, LitRenderable>(renderable, element_count, element_render_count)
{}
protected:
void setup_vao() override;
};
}
}

View File

@ -2,19 +2,30 @@
struct Light
{
vec3 position;
vec3 ambient;
vec3 diffuse;
};
in vec3 fragment_position;
in vec3 fragment_normal;
#define MAX_LIGHTS 16
layout(location = 4) uniform Light lights[MAX_LIGHTS];
layout(location = 20) uniform uint num_lights;
layout(location = 52) uniform uint num_lights;
out vec4 frag_color;
void main()
{
vec3 norm_normal = normalize(fragment_normal);
vec3 accum = vec3(0.0);
float diffuse_multiplier;
vec3 light_vector;
for (uint i = 0; i < MAX_LIGHTS && i < num_lights; ++i) {
accum = accum + lights[i].ambient;
light_vector = normalize(lights[i].position - fragment_position);
diffuse_multiplier = clamp(dot(light_vector, norm_normal), 0.0, 1.0);
accum += lights[i].ambient;
accum += diffuse_multiplier * lights[i].diffuse;
}
frag_color = vec4(accum, 1.0);
}

View File

@ -35,13 +35,14 @@ namespace charcoal
void LitScene::render()
{
glutil::clear_screen();
CHECK_GL_ERR();
m_shader_program.use();
CHECK_GL_ERR();
glutil::uniform_matrix(0, m_p_camera->get_world_to_view_matrix());
CHECK_GL_ERR();
glutil::uniform_lights(4, m_lights);
CHECK_GL_ERR();
glutil::uniform_uint(20, m_lights.size());
glutil::uniform_uint(52, (unsigned int)m_lights.size());
CHECK_GL_ERR();
for (auto iter = m_batches.begin(); iter != m_batches.end(); ++iter)
{

View File

@ -6,6 +6,7 @@
#include "BuiltinTypes.h"
#include "Camera.h"
#include "Batched.h"
#include "LitBatch.h"
#include "LitShaderProgram.h"
namespace charcoal
@ -29,7 +30,10 @@ namespace charcoal
protected:
void set_camera(const Camera* p_camera) { m_p_camera = p_camera; }
void add_light(const ColorRGB& ambient) { m_lights.emplace_back(ambient); }
void add_light(const Position& position, const ColorRGB& ambient, const ColorRGB& diffuse)
{
m_lights.emplace_back(position, ambient, diffuse);
}
private:
LitShaderProgram m_shader_program;

View File

@ -1,10 +1,18 @@
#version 430
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in mat4 model_to_world;
layout(location = 1) in vec3 vertex_normal;
layout(location = 2) in mat4 model_to_world;
layout(location = 0) uniform mat4 world_to_projection;
out vec3 fragment_position;
out vec3 fragment_normal;
void main()
{
gl_Position = world_to_projection * model_to_world * vec4(vertex_position, 1.0);
vec4 model_position = model_to_world * vec4(vertex_position, 1.0);
vec4 model_normal = model_to_world * vec4(vertex_normal, 0.0);
gl_Position = world_to_projection * model_position;
fragment_position = model_position.xyz;
fragment_normal = model_normal.xyz;
}

View File

@ -6,15 +6,15 @@
MyBuiltinLitScene::MyBuiltinLitScene(Application& application)
: LitScene(application),
m_shape(meshgenerator::gen_cube_p<LitVertex, LitIndex>(DRAW_TRIANGLES, 2.0f, 2.0f, 2.0f), DrawMode::DRAW_TRIANGLES),
m_shape(meshgenerator::gen_cube_pn<LitVertex, LitIndex>(DRAW_TRIANGLES, 2.0f, 2.0f, 2.0f), DrawMode::DRAW_TRIANGLES),
m_camera((float)TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)),
m_batch(add_batch(&m_shape, 1))
{
add_prerenderable(&m_camera);
set_camera(&m_camera);
add_light(ColorRGB(0.0f, 0.0f, 1.0f));
add_light(ColorRGB(0.0f, 1.0f, 0.0f));
// Something is off here... The light seems to be rotating...
add_light(Position(0.0f, 2.0f, -2.0f), ColorRGB(0.2f, 0.2f, 0.2f), ColorRGB(1.0f, 1.0f, 1.0f));
}
void MyBuiltinLitScene::update(float delta_time, clock_t clock)

View File

@ -153,10 +153,12 @@
<ItemGroup>
<ClCompile Include="Application.cpp" />
<ClCompile Include="AutoPrerenderingScene.cpp" />
<ClCompile Include="BasicBatch.cpp" />
<ClCompile Include="BasicScene.cpp" />
<ClCompile Include="Camera2D.cpp" />
<ClCompile Include="Camera3D.cpp" />
<ClCompile Include="FPS.cpp" />
<ClCompile Include="LitBatch.cpp" />
<ClCompile Include="LitScene.cpp" />
<ClCompile Include="MyBuiltinCubeScene.cpp" />
<ClCompile Include="GLFWInputManager.cpp" />
@ -183,6 +185,7 @@
<ItemGroup>
<ClInclude Include="Application.h" />
<ClInclude Include="AutoPrerenderingScene.h" />
<ClInclude Include="BasicBatch.h" />
<ClInclude Include="BasicScene.h" />
<ClInclude Include="BasicShaderProgram.h" />
<ClInclude Include="Batch.h" />
@ -197,6 +200,7 @@
<ClInclude Include="DrawMode.h" />
<ClInclude Include="Exception.h" />
<ClInclude Include="FPS.h" />
<ClInclude Include="LitBatch.h" />
<ClInclude Include="LitScene.h" />
<ClInclude Include="LitShaderProgram.h" />
<ClInclude Include="MyBuiltinCubeScene.h" />

View File

@ -138,6 +138,12 @@
<ClCompile Include="VertexFragmentShaderProgram.cpp">
<Filter>Source Files\Engine\Rendering</Filter>
</ClCompile>
<ClCompile Include="BasicBatch.cpp">
<Filter>Source Files\Engine\builtin</Filter>
</ClCompile>
<ClCompile Include="LitBatch.cpp">
<Filter>Source Files\Engine\builtin</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Exception.h">
@ -275,6 +281,12 @@
<ClInclude Include="MyBuiltinLitScene.h">
<Filter>Header Files\Example\Application</Filter>
</ClInclude>
<ClInclude Include="BasicBatch.h">
<Filter>Header Files\Engine\builtin</Filter>
</ClInclude>
<ClInclude Include="LitBatch.h">
<Filter>Header Files\Engine\builtin</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="MySimpleVS.glsl">

View File

@ -33,35 +33,13 @@ namespace charcoal
const Poseable& get_pose(int index) const { return m_pose_elements[index]; }
protected:
void setup_element_buffers() override
void setup_element_buffers()
{
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, Renderable>::m_element_buffers[0]);
glBufferData(GL_ARRAY_BUFFER, m_pose_elements.size() * sizeof(Poseable), NULL, GL_STREAM_DRAW);
}
void setup_vao() override
{
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, Renderable>::m_vertex_vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexType), NULL);
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, Renderable>::m_element_buffers[0]);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(0 * sizeof(vec4)));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(1 * sizeof(vec4)));
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(2 * sizeof(vec4)));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(3 * sizeof(vec4)));
glVertexAttribDivisor(0, 0); // Send the mesh data once
glVertexAttribDivisor(1, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(2, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(3, 1); // Send the offset data for each instance drawn
glVertexAttribDivisor(4, 1); // Send the offset data for each instance drawn
}
void update_element_buffers() override
void update_element_buffers()
{
// TODO: There are probably better ways to do this. Should check with the old engine to see what I did there.
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, Renderable>::m_element_buffers[0]);
@ -69,7 +47,6 @@ namespace charcoal
glBufferSubData(GL_ARRAY_BUFFER, 0, m_pose_elements.size() * sizeof(Poseable), m_pose_elements.data());
}
private:
std::vector<Poseable> m_pose_elements;
};
}

View File

@ -31,12 +31,12 @@ namespace charcoal
glGetShaderiv(m_shader, GL_COMPILE_STATUS, &compiled);
if (compiled != GL_TRUE)
{
char buffer[1024];
GLsizei log_length;
glGetShaderInfoLog(m_shader, 1023, &log_length, buffer);
buffer[log_length] = '\0'; // Add null terminator
GLsizei log_length = 0;
GLchar message[1024];
glGetShaderInfoLog(m_shader, 1023, &log_length, message);
message[log_length] = '\0'; // Add null terminator
OutputDebugString("Error Compiling Shader:\n");
OutputDebugString(buffer);
OutputDebugString(message);
OutputDebugString("\nSource:\n");
OutputDebugString(source.c_str());
OutputDebugString("\n");

View File

@ -19,7 +19,21 @@ namespace charcoal
void ShaderProgram::link()
{
glLinkProgram(m_program);
// TODO: Error handling
GLint program_linked;
glGetProgramiv(m_program, GL_LINK_STATUS, &program_linked);
if (program_linked != GL_TRUE)
{
GLsizei log_length = 0;
GLchar message[1024];
glGetProgramInfoLog(m_program, 1023, &log_length, message);
message[log_length] = '\0'; // Add null terminator
OutputDebugString("Error Linking Shader Program:\n");
OutputDebugString(message);
OutputDebugString("\n");
throw EXCEPTION("Error linking Shader Program.");
}
}
void ShaderProgram::use() const