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 "BuiltinTypes.h"
#include "Camera2D.h" #include "Camera2D.h"
#include "Batched.h" #include "Batched.h"
#include "BasicBatch.h"
#include "constants.h" #include "constants.h"

View File

@ -41,9 +41,12 @@ namespace charcoal
struct Light 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 ambient;
ColorRGB diffuse;
}; };
// typedefs for builtin types // typedefs for builtin types
@ -51,11 +54,9 @@ namespace charcoal
typedef PVertex BasicVertex; typedef PVertex BasicVertex;
typedef Index BasicIndex; typedef Index BasicIndex;
typedef Renderable<BasicVertex, BasicIndex> BasicRenderable; typedef Renderable<BasicVertex, BasicIndex> BasicRenderable;
typedef PoseableBatch<BasicVertex, BasicIndex> BasicBatch;
typedef PNVertex LitVertex; typedef PNVertex LitVertex;
typedef Index LitIndex; typedef Index LitIndex;
typedef Renderable<LitVertex, LitIndex> LitRenderable; 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) void uniform_lights(int uniform_index, const std::vector<Light>& lights)
{ {
const int position_size = 1;
const int ambient_size = 1; const int ambient_size = 1;
const int diffuse_size = 1;
int current_location = uniform_index; int current_location = uniform_index;
for (std::vector<Light>::size_type i = 0; i < lights.size(); ++i) 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]); glUniform3fv(current_location, 1, &lights[i].ambient[0]);
current_location += ambient_size; 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 struct Light
{ {
vec3 position;
vec3 ambient; vec3 ambient;
vec3 diffuse;
}; };
in vec3 fragment_position;
in vec3 fragment_normal;
#define MAX_LIGHTS 16 #define MAX_LIGHTS 16
layout(location = 4) uniform Light lights[MAX_LIGHTS]; 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; out vec4 frag_color;
void main() void main()
{ {
vec3 norm_normal = normalize(fragment_normal);
vec3 accum = vec3(0.0); vec3 accum = vec3(0.0);
float diffuse_multiplier;
vec3 light_vector;
for (uint i = 0; i < MAX_LIGHTS && i < num_lights; ++i) { 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); frag_color = vec4(accum, 1.0);
} }

View File

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

View File

@ -6,6 +6,7 @@
#include "BuiltinTypes.h" #include "BuiltinTypes.h"
#include "Camera.h" #include "Camera.h"
#include "Batched.h" #include "Batched.h"
#include "LitBatch.h"
#include "LitShaderProgram.h" #include "LitShaderProgram.h"
namespace charcoal namespace charcoal
@ -29,7 +30,10 @@ namespace charcoal
protected: protected:
void set_camera(const Camera* p_camera) { m_p_camera = p_camera; } 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: private:
LitShaderProgram m_shader_program; LitShaderProgram m_shader_program;

View File

@ -1,10 +1,18 @@
#version 430 #version 430
layout(location = 0) in vec3 vertex_position; 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; layout(location = 0) uniform mat4 world_to_projection;
out vec3 fragment_position;
out vec3 fragment_normal;
void main() 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) MyBuiltinLitScene::MyBuiltinLitScene(Application& application)
: LitScene(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_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)) m_batch(add_batch(&m_shape, 1))
{ {
add_prerenderable(&m_camera); add_prerenderable(&m_camera);
set_camera(&m_camera); set_camera(&m_camera);
add_light(ColorRGB(0.0f, 0.0f, 1.0f)); // Something is off here... The light seems to be rotating...
add_light(ColorRGB(0.0f, 1.0f, 0.0f)); 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) void MyBuiltinLitScene::update(float delta_time, clock_t clock)

View File

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

View File

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

View File

@ -33,35 +33,13 @@ namespace charcoal
const Poseable& get_pose(int index) const { return m_pose_elements[index]; } const Poseable& get_pose(int index) const { return m_pose_elements[index]; }
protected: protected:
void setup_element_buffers() override void setup_element_buffers()
{ {
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, Renderable>::m_element_buffers[0]); 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); glBufferData(GL_ARRAY_BUFFER, m_pose_elements.size() * sizeof(Poseable), NULL, GL_STREAM_DRAW);
} }
void setup_vao() override void update_element_buffers()
{
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
{ {
// TODO: There are probably better ways to do this. Should check with the old engine to see what I did there. // 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]); 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()); glBufferSubData(GL_ARRAY_BUFFER, 0, m_pose_elements.size() * sizeof(Poseable), m_pose_elements.data());
} }
private:
std::vector<Poseable> m_pose_elements; std::vector<Poseable> m_pose_elements;
}; };
} }

View File

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

View File

@ -19,7 +19,21 @@ namespace charcoal
void ShaderProgram::link() void ShaderProgram::link()
{ {
glLinkProgram(m_program); 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 void ShaderProgram::use() const