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

fixes, fog experiments, add shaders to tree

This commit is contained in:
VB
2017-06-29 13:07:10 +02:00
parent 22f6d1f0f7
commit 2e022a91dd
10 changed files with 248 additions and 50 deletions

View File

@@ -1298,7 +1298,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;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
shader.set_ambient(glm::make_vec3(&cablight.x));
}
// render
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
@@ -1311,7 +1311,7 @@ TWorld::Render_Cab() {
if( dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
shader.set_ambient(glm::make_vec3(ambient));
}
}
glPopMatrix();

View File

@@ -206,7 +206,7 @@ opengl_vbogeometrybank::draw_( geometry_handle const &Geometry, unsigned int con
if( m_activestreams != Streams ) {
bind_streams( Streams );
}
glDebug("D97");
// ...render...
::glDrawArrays( chunk.type, (GLint)chunkrecord.offset, (GLsizei)chunkrecord.size );
// ...post-render cleanup

View File

@@ -102,17 +102,6 @@ opengl_renderer::Init( GLFWwindow *Window ) {
Global::daylight.color.y = 242.0f / 255.0f;
Global::daylight.color.z = 231.0f / 255.0f;
// setup fog
if( Global::fFogEnd > 0 ) {
// fog setup
::glFogi( GL_FOG_MODE, GL_LINEAR );
::glFogfv( GL_FOG_COLOR, Global::FogColor );
::glFogf( GL_FOG_START, Global::fFogStart );
::glFogf( GL_FOG_END, Global::fFogEnd );
::glEnable( GL_FOG );
}
else { ::glDisable( GL_FOG ); }
World.shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
Global::daylight.intensity = 1.0f; //m7todo: przenieść
@@ -168,9 +157,11 @@ opengl_renderer::Render() {
// frustum tests are performed in 'world space' but after we set up frustum
// we no longer need camera translation, only rotation
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
glDebug("rendering environment");
glDisable(GL_FRAMEBUFFER_SRGB);
Render( &World.Environment );
glUseProgram(World.shader);
glDebug("rendering world");
World.shader.bind();
glEnable(GL_FRAMEBUFFER_SRGB);
Render( &World.Ground );
@@ -181,10 +172,13 @@ opengl_renderer::Render() {
m_drawtime = std::max( 20.0f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - timestart ) ).count());
m_drawcount = m_drawqueue.size();
}
glDebug("dis1");
glUseProgram(0);
glDebug("rendering ui");
World.shader.unbind();
glEnable(GL_FRAMEBUFFER_SRGB);
UILayer.render();
glDebug("rendering end");
glfwSwapBuffers( m_window );
return true; // for now always succeed
}
@@ -206,11 +200,10 @@ opengl_renderer::Render( world_environment *Environment ) {
// setup fog
if( Global::fFogEnd > 0 ) {
// fog setup
::glFogfv( GL_FOG_COLOR, Global::FogColor );
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / Global::fFogEnd ) );
::glEnable( GL_FOG );
//m7todo: set fog amount based on scenery settings
World.shader.set_fog(0.0005f, glm::make_vec3(Global::FogColor));
}
else { ::glDisable( GL_FOG ); }
else { World.shader.set_fog(0.0f, glm::make_vec3(Global::FogColor)); }
Environment->m_skydome.Render();
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
@@ -416,9 +409,7 @@ opengl_renderer::Render( TGround *Ground ) {
}
if( m_camera.visible( cell->m_area ) ) {
glDebug("to tu?");
Render( cell );
glDebug("koniec to tu");
}
}
}
@@ -642,14 +633,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;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
World.shader.set_ambient(glm::make_vec3(&cablight.x));
}
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
World.shader.set_ambient(glm::vec3(m_baseambient));
}
}
}
@@ -732,6 +723,7 @@ void opengl_renderer::Render(TSubModel *Submodel)
World.shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
World.shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
Render(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
World.shader.set_material(0.0f, glm::vec3(0.0f));
}
void opengl_renderer::Render_Alpha(TSubModel *Submodel)
@@ -739,6 +731,7 @@ void opengl_renderer::Render_Alpha(TSubModel *Submodel)
World.shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
World.shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
Render_Alpha(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
World.shader.set_material(0.0f, glm::vec3(0.0f));
}
void
@@ -778,8 +771,6 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
// main draw call
m_geometry.draw( Submodel->m_geometry );
World.shader.set_material(0.0f, glm::vec3(0.0f));
}
}
@@ -800,7 +791,8 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
float const distancefactor = static_cast<float>( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) );
if( lightlevel > 0.0f ) {
glUseProgram(0);
gl_program::unbind();
glEnableClientState(GL_VERTEX_ARRAY);
glLoadMatrixf(glm::value_ptr(mm));
glVertexPointer(3, GL_FLOAT, sizeof(basic_vertex), static_cast<char *>(nullptr)); // pozycje
@@ -821,13 +813,13 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
::glPopAttrib();
glDisableClientState(GL_VERTEX_ARRAY);
glUseProgram(World.shader);
gl_program::bind_last();
}
}
}
else if( Submodel->eType == TP_STARS ) {
//m7todo: reenable
//m7todo: restore
/*
if( Global::fLuminance < Submodel->fLight ) {
glUseProgram(0);
@@ -1101,14 +1093,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;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
World.shader.set_ambient(glm::make_vec3(&cablight.x));
}
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
World.shader.set_ambient(glm::vec3(m_baseambient));
}
}
}
@@ -1220,8 +1212,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
// main draw call
m_geometry.draw(Submodel->m_geometry);
World.shader.set_material(0.0f, glm::vec3(0.0f));
}
}
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
@@ -1240,7 +1230,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
glarelevel = std::max( 0.0f, glarelevel - static_cast<float>(Global::fLuminance) );
if( glarelevel > 0.0f ) {
glUseProgram(0);
gl_program::unbind();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(basic_vertex), static_cast<char *>(nullptr)); // pozycje
// setup
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
@@ -1264,10 +1257,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
+ CameraUp_worldspace * squareVertices.y * BillboardSize.y;
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
*/
::glEnd();
::glPopAttrib();
glDisableClientState(GL_VERTEX_ARRAY);
glUseProgram(World.shader);
gl_program::bind_last();
}
}
}

View File

@@ -83,6 +83,34 @@ gl_program::gl_program(std::vector<gl_shader> shaders)
}
}
gl_program* gl_program::current_program = nullptr;
gl_program* gl_program::last_program = nullptr;
void gl_program::bind()
{
if (current_program == this)
return;
last_program = current_program;
current_program = this;
glUseProgram(*current_program);
}
void gl_program::bind_last()
{
current_program = last_program;
if (current_program != nullptr)
glUseProgram(*current_program);
else
glUseProgram(0);
}
void gl_program::unbind()
{
last_program = current_program;
current_program = nullptr;
glUseProgram(0);
}
gl_program::operator GLuint()
{
return id;
@@ -91,18 +119,21 @@ gl_program::operator GLuint()
gl_program_mvp::gl_program_mvp(std::vector<gl_shader> v) : gl_program(v)
{
mv_uniform = glGetUniformLocation(id, "modelview");
mvn_uniform = glGetUniformLocation(id, "modelviewnormal");
p_uniform = glGetUniformLocation(id, "projection");
}
void gl_program_mvp::copy_gl_mvp()
{
glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, glm::value_ptr(OpenGLMatrices.data(GL_MODELVIEW)));
glUniformMatrix4fv(p_uniform, 1, GL_FALSE, glm::value_ptr(OpenGLMatrices.data(GL_PROJECTION)));
set_mv(OpenGLMatrices.data(GL_MODELVIEW));
set_p(OpenGLMatrices.data(GL_PROJECTION));
}
void gl_program_mvp::set_mv(const glm::mat4 &m)
{
glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(m)));
glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, glm::value_ptr(m));
glUniformMatrix3fv(mvn_uniform, 1, GL_FALSE, glm::value_ptr(mvn));
}
void gl_program_mvp::set_p(const glm::mat4 &m)
@@ -112,9 +143,13 @@ void gl_program_mvp::set_p(const glm::mat4 &m)
gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
{
bind();
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++)
@@ -129,22 +164,25 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
lights_uniform[i].quadratic = glGetUniformLocation(id, std::string("lights[" + std::to_string(i) + "].quadratic").c_str());
}
glUseProgram(id);
glUniform3f(ambient_uniform, 0.0f, 0.0f, 0.0f);
glUniform3f(emission_uniform, 0.0f, 0.0f, 0.0f);
glUniform1f(specular_uniform, 0.0f);
glUniform1ui(lcount_uniform, 0);
}
void gl_program_light::set_ambient(glm::vec3 &ambient)
{
glUseProgram(id);
bind();
glUniform3fv(ambient_uniform, 1, glm::value_ptr(ambient));
}
void gl_program_light::set_fog(float density, glm::vec3 &color)
{
bind();
glUniform1f(fog_density_uniform, density);
glUniform3fv(fog_color_uniform, 1, glm::value_ptr(color));
}
void gl_program_light::set_light_count(GLuint count)
{
glUseProgram(id);
bind();
glUniform1ui(lcount_uniform, count);
}
@@ -157,7 +195,7 @@ void gl_program_light::set_light(GLuint i, type t, glm::vec3 &pos, glm::vec3 &di
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);
glUseProgram(id);
bind();
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));
@@ -170,7 +208,7 @@ void gl_program_light::set_light(GLuint i, type t, glm::vec3 &pos, glm::vec3 &di
void gl_program_light::set_material(float specular, glm::vec3 &emission)
{
glUseProgram(id);
bind();
glUniform1f(specular_uniform, specular);
glUniform3fv(emission_uniform, 1, glm::value_ptr(emission));
}

View File

@@ -23,12 +23,19 @@ public:
gl_program() = default;
gl_program(std::vector<gl_shader>);
static gl_program* current_program;
static gl_program* last_program;
void bind();
static void bind_last();
static void unbind();
operator GLuint();
};
class gl_program_mvp : public gl_program
{
GLuint mv_uniform;
GLuint mvn_uniform;
GLuint p_uniform;
public:
@@ -56,6 +63,7 @@ public:
gl_program_light(std::vector<gl_shader>);
void set_ambient(glm::vec3 &ambient);
void gl_program_light::set_fog(float density, glm::vec3 &color);
void set_material(float specular, glm::vec3 &emission);
void set_light_count(GLuint count);
void set_light(GLuint id, type t, glm::vec3 &pos, glm::vec3 &dir, float in_cutoff, float out_cutoff,
@@ -64,6 +72,8 @@ public:
private:
GLuint ambient_uniform;
GLuint specular_uniform;
GLuint fog_color_uniform;
GLuint fog_density_uniform;
GLuint emission_uniform;
GLuint lcount_uniform;
struct light_s

111
shaders/blinnphong.frag Normal file
View File

@@ -0,0 +1,111 @@
#version 330
const uint LIGHT_SPOT = 0U;
const uint LIGHT_POINT = 1U;
const uint LIGHT_DIR = 2U;
struct light_s
{
uint type;
vec3 pos;
vec3 dir;
float in_cutoff;
float out_cutoff;
vec3 color;
float linear;
float quadratic;
};
in vec3 f_normal;
in vec2 f_coord;
in vec3 f_pos;
out vec4 color;
uniform sampler2D tex;
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;
vec3 apply_fog(vec3 color)
{
float sun_amount = 0.0;
if (lights_count >= 1U && lights[0].type == LIGHT_DIR)
sun_amount = max(dot(normalize(f_pos), normalize(-lights[0].dir)), 0.0);
vec3 fog_color_v = mix(fog_color, lights[0].color, pow(sun_amount, 30.0));
float fog_amount_v = 1.0 - min(1.0, exp(-length(f_pos) * fog_density));
return mix(color, fog_color_v, fog_amount_v);
}
float calc_light(vec3 light_dir)
{
vec3 normal = normalize(f_normal);
vec3 view_dir = normalize(vec3(0.0f, 0.0f, 0.0f) - f_pos);
vec3 halfway_dir = normalize(light_dir + view_dir);
float diffuse_v = max(dot(normal, light_dir), 0.0);
float specular_v = pow(max(dot(normal, halfway_dir), 0.0), 15.0) * specular;
return specular_v + diffuse_v;
}
float calc_point_light(light_s light)
{
vec3 light_dir = normalize(light.pos - f_pos);
float val = calc_light(light_dir);
float distance = length(light.pos - f_pos);
float atten = 1.0f / (1.0f + light.linear * distance + light.quadratic * (distance * distance));
return val * atten;
}
float calc_spot_light(light_s light)
{
vec3 light_dir = normalize(light.pos - f_pos);
float theta = dot(light_dir, normalize(-light.dir));
float epsilon = light.in_cutoff - light.out_cutoff;
float intensity = clamp((theta - light.out_cutoff) / epsilon, 0.0, 1.0);
float point = calc_point_light(light);
return point * intensity;
}
float calc_dir_light(light_s light)
{
vec3 light_dir = normalize(-light.dir);
return calc_light(light_dir);
}
void main()
{
vec3 result = ambient * 0.3 + emission;
for (uint i = 0U; i < lights_count; i++)
{
light_s light = lights[i];
float part = 0.0;
if (light.type == LIGHT_SPOT)
part = calc_spot_light(light);
else if (light.type == LIGHT_POINT)
part = calc_point_light(light);
else if (light.type == LIGHT_DIR)
part = calc_dir_light(light);
result += light.color * part;
}
vec4 tex_color = texture(tex, f_coord);
color = vec4(apply_fog(result * tex_color.xyz), tex_color.w);
}

10
shaders/color.frag Normal file
View File

@@ -0,0 +1,10 @@
#version 330
in vec3 f_color;
out vec4 color;
void main()
{
color = vec4(f_color, 1.0f);
}

21
shaders/lighting.vert Normal file
View File

@@ -0,0 +1,21 @@
#version 330
layout (location = 0) in vec3 v_vert;
layout (location = 1) in vec3 v_normal;
layout (location = 2) in vec2 v_coord;
out vec3 f_normal;
out vec2 f_coord;
out vec3 f_pos;
uniform mat4 modelview;
uniform mat3 modelviewnormal;
uniform mat4 projection;
void main()
{
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
f_normal = modelviewnormal * v_normal;
f_coord = v_coord;
f_pos = vec3(modelview * vec4(v_vert, 1.0f));
}

15
shaders/vbocolor.vert Normal file
View File

@@ -0,0 +1,15 @@
#version 330
layout (location = 0) in vec3 v_vert;
layout (location = 1) in vec3 v_color;
out vec3 f_color;
uniform mat4 modelview;
uniform mat4 projection;
void main()
{
gl_Position = projection * modelview * vec4(v_vert, 1.0f);
f_color = v_color;
}

View File

@@ -162,15 +162,15 @@ void CSkyDome::Render() {
}
// begin
glUseProgram(m_shader);
m_shader.bind();
glBindVertexArray(m_vao);
m_shader.copy_gl_mvp();
glDrawElements(GL_TRIANGLES, (GLsizei)m_indices.size(), GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
glDebug("dis2");
glUseProgram(0);
m_shader.bind_last();
}
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {