16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-21 18:19:19 +02:00

ubo for light settings

This commit is contained in:
milek7
2017-08-02 23:26:40 +02:00
parent f7459f3434
commit 726a834232
6 changed files with 163 additions and 120 deletions

View File

@@ -1325,8 +1325,7 @@ TWorld::Render_Cab() {
if( dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = dynamic->InteriorLight * dynamic->InteriorLightLevel;
glm::vec3 cablight_glm = glm::make_vec3(&cablight.x);
GfxRenderer.shader.set_ambient(cablight_glm);
GfxRenderer.ubo.data.ambient = glm::make_vec3(&cablight.x);
}
// render
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
@@ -1338,8 +1337,7 @@ TWorld::Render_Cab() {
}
if( dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
glm::vec3 ambient(0.0f, 0.0f, 0.0f);
GfxRenderer.shader.set_ambient(ambient);
GfxRenderer.ubo.data.ambient = glm::vec3(0.0f);
}
}
glPopMatrix();

View File

@@ -105,7 +105,9 @@ opengl_renderer::Init( GLFWwindow *Window ) {
Global::daylight.color.z = 231.0f / 255.0f;
Global::daylight.intensity = 1.0f; //m7todo: przenieść
ubo.init();
shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
shader.bind_ubodata(ubo.get_binding_point());
depth_shader = gl_program_mvp({ gl_shader("shadowmap.vert"), gl_shader("empty.frag") });
active_shader = &shader;
@@ -267,12 +269,14 @@ opengl_renderer::Render( world_environment *Environment ) {
::glDisable( GL_DEPTH_TEST );
::glDepthMask( GL_FALSE );
::glPushMatrix();
ubo.data.fog_color = glm::make_vec3(Global::FogColor);
// setup fog
if( Global::fFogEnd > 0 ) {
// fog setup
shader.set_fog(1.0f / Global::fFogEnd, glm::make_vec3(Global::FogColor));
}
else { shader.set_fog(0.0f, glm::make_vec3(Global::FogColor)); }
if( Global::fFogEnd > 0 )
ubo.data.fog_density = 1.0f / Global::fFogEnd;
else
ubo.data.fog_density = 0.0f;
ubo.update();
Environment->m_skydome.Render();
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
@@ -444,6 +448,7 @@ opengl_renderer::Render( TGround *Ground ) {
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
Update_Lights( Ground->m_lights );
ubo.update();
m_drawqueue.clear();
@@ -705,14 +710,14 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
shader.set_ambient(glm::make_vec3(&cablight.x));
ubo.data.ambient = glm::make_vec3(&cablight.x);
}
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
shader.set_ambient(glm::vec3(m_baseambient));
ubo.data.ambient = glm::vec3(m_baseambient);
}
}
}
@@ -1182,14 +1187,14 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
shader.set_ambient(glm::make_vec3(&cablight.x));
ubo.data.ambient = glm::make_vec3(&cablight.x);
}
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
shader.set_ambient(glm::vec3(m_baseambient));
ubo.data.ambient = glm::vec3(m_baseambient);
}
}
}
@@ -1457,6 +1462,8 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
size_t renderlight = 0;
glm::mat4 mv = OpenGLMatrices.data(GL_MODELVIEW);
for( auto const &scenelight : Lights.data ) {
if( renderlight == Global::DynamicLightCount ) {
@@ -1483,21 +1490,30 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
scenelight.color.y,
scenelight.color.z);
shader.set_light((GLuint)renderlight + 1, gl_program_light::SPOT, position, direction, 0.906f, 0.866f, color, 0.007f, 0.0002f);
gl_ubodata_light *light = &ubo.data.lights[renderlight + 1];
light->type = gl_ubodata_light::SPOT;
light->pos = mv * glm::vec4(position, 1.0f);
light->dir = mv * glm::vec4(direction, 0.0f);
light->in_cutoff = 0.906f;
light->out_cutoff = 0.866f;
light->color = color;
light->linear = 0.007f;
light->quadratic = 0.0002f;
++renderlight;
}
shader.set_ambient(Global::daylight.ambient);
shader.set_light(0, gl_program_light::DIR, glm::vec3(0.0f), Global::daylight.direction,
0.0f, 0.0f, Global::daylight.color, 0.0f, 0.0f);
shader.set_light_count((GLuint)renderlight + 1);
ubo.data.ambient = Global::daylight.ambient;
ubo.data.lights[0].type = gl_ubodata_light::DIR;
ubo.data.lights[0].dir = mv * glm::vec4(Global::daylight.direction, 0.0f);
ubo.data.lights[0].color = Global::daylight.color;
ubo.data.lights_count = renderlight + 1;
}
void
opengl_renderer::Disable_Lights() {
shader.set_light_count(0);
ubo.data.lights_count = 0;
}
bool

View File

@@ -67,6 +67,7 @@ private:
class opengl_renderer {
public:
gl_ubo<gl_ubodata_light_params> ubo;
gl_program_light shader;
gl_program_mvp depth_shader;
gl_program_mvp *active_shader = nullptr;

View File

@@ -66,6 +66,11 @@ gl_shader::operator GLuint()
return id;
}
gl_shader::~gl_shader()
{
//glDeleteShader(*this); //m7todo: something is broken
}
gl_program::gl_program(std::vector<gl_shader> shaders)
{
id = glCreateProgram();
@@ -116,6 +121,11 @@ gl_program::operator GLuint()
return id;
}
gl_program::~gl_program()
{
//glDeleteProgram(*this); //m7todo: something is broken
}
gl_program_mvp::gl_program_mvp(std::vector<gl_shader> v) : gl_program(v)
{
mv_uniform = glGetUniformLocation(id, "modelview");
@@ -151,26 +161,14 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
glUniform1i(glGetUniformLocation(id, "tex"), 0);
glUniform1i(glGetUniformLocation(id, "shadowmap"), 1);
lightview_uniform = glGetUniformLocation(id, "lightview");
ambient_uniform = glGetUniformLocation(id, "ambient");
emission_uniform = glGetUniformLocation(id, "emission");
specular_uniform = glGetUniformLocation(id, "specular");
fog_color_uniform = glGetUniformLocation(id, "fog_color");
fog_density_uniform = glGetUniformLocation(id, "fog_density");
lcount_uniform = glGetUniformLocation(id, "lights_count");
}
for (size_t i = 0; i < MAX_LIGHTS; i++)
{
lights_uniform[i].type = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].type").c_str());
lights_uniform[i].pos = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].pos").c_str());
lights_uniform[i].dir = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].dir").c_str());
lights_uniform[i].in_cutoff = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].in_cutoff").c_str());
lights_uniform[i].out_cutoff = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].out_cutoff").c_str());
lights_uniform[i].color = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].color").c_str());
lights_uniform[i].linear = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].linear").c_str());
lights_uniform[i].quadratic = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].quadratic").c_str());
}
glUniform1ui(lcount_uniform, 0);
void gl_program_light::bind_ubodata(GLuint point)
{
GLuint index = glGetUniformBlockIndex(*this, "ubodata");
glUniformBlockBinding(*this, index, point);
}
void gl_program_light::set_lightview(const glm::mat4 &lightview)
@@ -181,53 +179,6 @@ void gl_program_light::set_lightview(const glm::mat4 &lightview)
glUniformMatrix4fv(lightview_uniform, 1, GL_FALSE, glm::value_ptr(lightview));
}
void gl_program_light::set_ambient(const glm::vec3 &ambient)
{
if (current_program != this)
return;
glUniform3fv(ambient_uniform, 1, glm::value_ptr(ambient));
}
void gl_program_light::set_fog(float density, const glm::vec3 &color)
{
if (current_program != this)
return;
glUniform1f(fog_density_uniform, density);
glUniform3fv(fog_color_uniform, 1, glm::value_ptr(color));
}
void gl_program_light::set_light_count(GLuint count)
{
if (current_program != this)
return;
glUniform1ui(lcount_uniform, count);
}
void gl_program_light::set_light(GLuint i, type t, const glm::vec3 &pos, const glm::vec3 &dir,
float in_cutoff, float out_cutoff,
const glm::vec3 &color, float linear, float quadratic)
{
if (current_program != this)
return;
glm::mat4 mv = OpenGLMatrices.data(GL_MODELVIEW);
glm::vec3 trans_pos = mv * glm::vec4(pos.x, pos.y, pos.z, 1.0f);
glm::vec3 trans_dir = mv * glm::vec4(dir.x, dir.y, dir.z, 0.0f);
glUniform1ui(lights_uniform[i].type, (GLuint)t);
glUniform3fv(lights_uniform[i].pos, 1, glm::value_ptr(trans_pos));
glUniform3fv(lights_uniform[i].dir, 1, glm::value_ptr(trans_dir));
glUniform1f(lights_uniform[i].in_cutoff, in_cutoff);
glUniform1f(lights_uniform[i].out_cutoff, out_cutoff);
glUniform3fv(lights_uniform[i].color, 1, glm::value_ptr(color));
glUniform1f(lights_uniform[i].linear, linear);
glUniform1f(lights_uniform[i].quadratic, quadratic);
}
void gl_program_light::set_material(float specular, const glm::vec3 &emission)
{
if (current_program != this)
@@ -236,3 +187,34 @@ void gl_program_light::set_material(float specular, const glm::vec3 &emission)
glUniform1f(specular_uniform, specular);
glUniform3fv(emission_uniform, 1, glm::value_ptr(emission));
}
template<typename T>
GLuint gl_ubo<T>::binding_point_cnt = 0;
template<typename T>
void gl_ubo<T>::init()
{
glGenBuffers(1, &buffer_id);
glBindBuffer(GL_UNIFORM_BUFFER, buffer_id);
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), nullptr, GL_DYNAMIC_DRAW);
binding_point = binding_point_cnt++;
glBindBufferBase(GL_UNIFORM_BUFFER, binding_point, buffer_id);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
template<typename T>
void gl_ubo<T>::update()
{
glBindBuffer(GL_UNIFORM_BUFFER, buffer_id);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), &data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
template<typename T>
gl_ubo<T>::~gl_ubo()
{
if (buffer_id)
glDeleteBuffers(1, &buffer_id);
}
template class gl_ubo<gl_ubodata_light_params>;

View File

@@ -7,10 +7,11 @@
class gl_shader
{
GLuint id;
GLuint id = 0;
public:
gl_shader();
gl_shader(std::string);
~gl_shader();
operator GLuint();
};
@@ -18,10 +19,12 @@ public:
class gl_program
{
protected:
GLuint id;
GLuint id = 0;
public:
gl_program() = default;
gl_program(std::vector<gl_shader>);
~gl_program();
static gl_program* current_program;
static gl_program* last_program;
@@ -47,46 +50,85 @@ public:
void copy_gl_mvp();
};
class gl_program_light : public gl_program_mvp
{
public:
static const size_t MAX_LIGHTS = 8;
// layout std140
// structs must match with GLSL
// weird order to minimize padding
enum type
#define PAD(x) uint64_t : x * 4; uint64_t : x * 4;
#pragma pack(push, 1)
struct gl_ubodata_light
{
enum type_e
{
SPOT = 0,
POINT,
DIR
};
glm::vec3 pos;
type_e type;
glm::vec3 dir;
float in_cutoff;
glm::vec3 color;
float out_cutoff;
float linear;
float quadratic;
PAD(8);
};
static_assert(sizeof(gl_ubodata_light) == 64);
struct gl_ubodata_light_params
{
static const size_t MAX_LIGHTS = 8;
glm::vec3 ambient;
float fog_density;
glm::vec3 fog_color;
GLuint lights_count;
gl_ubodata_light lights[MAX_LIGHTS];
};
static_assert(sizeof(gl_ubodata_light_params) == 544);
#pragma pack(pop)
template<typename T>
class gl_ubo
{
GLuint buffer_id = 0;
GLuint binding_point;
static GLuint binding_point_cnt;
public:
T data;
void init();
~gl_ubo();
void update();
GLuint get_binding_point()
{
return binding_point;
};
};
class gl_program_light : public gl_program_mvp
{
public:
gl_program_light() = default;
gl_program_light(std::vector<gl_shader>);
void set_lightview(const glm::mat4 &lightview);
void set_ambient(const glm::vec3 &ambient);
void set_fog(float density, const glm::vec3 &color);
void set_material(float specular, const glm::vec3 &emission);
void set_light_count(GLuint count);
void set_light(GLuint id, type t, const glm::vec3 &pos, const glm::vec3 &dir, float in_cutoff, float out_cutoff,
const glm::vec3 &color, float linear, float quadratic);
void bind_ubodata(GLuint point);
private:
GLuint lightview_uniform;
GLuint ambient_uniform;
GLuint specular_uniform;
GLuint fog_color_uniform;
GLuint fog_density_uniform;
GLuint emission_uniform;
GLuint lcount_uniform;
struct light_s
{
GLuint type;
GLuint pos;
GLuint dir;
GLuint in_cutoff;
GLuint out_cutoff;
GLuint color;
GLuint linear;
GLuint quadratic;
} lights_uniform[MAX_LIGHTS];
};

View File

@@ -6,15 +6,14 @@ const uint LIGHT_DIR = 2U;
struct light_s
{
vec3 pos;
uint type;
vec3 pos;
vec3 dir;
vec3 dir;
float in_cutoff;
float out_cutoff;
vec3 color;
float out_cutoff;
float linear;
float quadratic;
@@ -30,14 +29,19 @@ out vec4 color;
uniform sampler2D tex;
uniform sampler2DShadow shadowmap;
uniform vec3 ambient;
uniform vec3 emission;
uniform vec3 fog_color;
uniform float fog_density;
uniform float specular;
uniform light_s lights[8];
uniform uint lights_count;
layout(std140) uniform ubodata
{
vec3 ambient;
float fog_density;
vec3 fog_color;
uint lights_count;
light_s lights[8];
};
float calc_shadow()
{
@@ -132,4 +136,4 @@ void main()
vec4 tex_color = texture(tex, f_coord);
color = vec4(apply_fog(result * tex_color.xyz), tex_color.w);
}
}