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:
@@ -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();
|
||||
|
||||
46
renderer.cpp
46
renderer.cpp
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
110
shader.cpp
110
shader.cpp
@@ -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>;
|
||||
96
shader.h
96
shader.h
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user