shadow works

This commit is contained in:
VB
2017-07-02 00:10:45 +02:00
parent 4b3d038c2b
commit 3a02a65ada
10 changed files with 170 additions and 33 deletions

View File

@@ -815,7 +815,7 @@ texture_manager::bind( texture_handle const Texture ) {
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
m_activetexture = texture(Texture).id;
m_activetexture = Texture;
#else
if( texture( Texture ).bind() == resource_state::good ) {
m_activetexture = Texture;

View File

@@ -51,6 +51,10 @@ public:
translate( glm::vec3 const &Translation ) {
m_stack.top() = glm::translate( m_stack.top(), Translation );
upload(); }
void
load(glm::mat4 const &Matrix) {
m_stack.top() = Matrix;
upload(); }
void
multiply( glm::mat4 const &Matrix ) {
m_stack.top() *= Matrix;
@@ -131,6 +135,11 @@ public:
multiply( Type_ const *Matrix ) {
m_stacks[ m_mode ].multiply(
glm::make_mat4( Matrix ) ); }
template <typename Type_>
void
load(Type_ const *Matrix) {
m_stacks[m_mode].load(
glm::make_mat4(Matrix)); }
template <typename Type_>
void
perspective( Type_ const Fovy, Type_ const Aspect, Type_ const Znear, Type_ const Zfar ) {
@@ -179,5 +188,6 @@ extern opengl_matrices OpenGLMatrices;
#define glMultMatrixf OpenGLMatrices.multiply
#define gluPerspective OpenGLMatrices.perspective
#define gluLookAt OpenGLMatrices.look_at
#define glLoadMatrixf OpenGLMatrices.load
//---------------------------------------------------------------------------

View File

@@ -22,6 +22,8 @@ http://mozilla.org/MPL/2.0/.
#include "usefull.h"
#include "World.h"
#include <glm/gtx/string_cast.hpp>
opengl_renderer GfxRenderer;
extern TWorld World;
@@ -101,10 +103,29 @@ opengl_renderer::Init( GLFWwindow *Window ) {
Global::daylight.color.x = 255.0f / 255.0f;
Global::daylight.color.y = 242.0f / 255.0f;
Global::daylight.color.z = 231.0f / 255.0f;
shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
Global::daylight.intensity = 1.0f; //m7todo: przenieść
shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
depth_shader = gl_program_mvp({ gl_shader("shadowmap.vert"), gl_shader("empty.frag") });
active_shader = &shader;
glGenFramebuffers(1, &depth_fbo);
glGenTextures(1, &depth_tex);
glBindTexture(GL_TEXTURE_2D, depth_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, depth_tex);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// preload some common textures
WriteLog( "Loading common gfx data..." );
@@ -139,30 +160,68 @@ opengl_renderer::Render() {
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
::glDepthFunc( GL_LEQUAL );
::glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
::gluPerspective(
Global::FieldOfView / Global::ZoomFactor,
::glMatrixMode( GL_PROJECTION );
glm::mat4 perspective = glm::perspective(
glm::radians(Global::FieldOfView / Global::ZoomFactor),
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
0.1f * Global::ZoomFactor,
m_drawrange * Global::fDistanceFactor );
glLoadMatrixf(glm::value_ptr(perspective));
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
::glMatrixMode( GL_MODELVIEW );
::glLoadIdentity();
if( World.InitPerformed() ) {
glDebug("rendering shadow map");
glDisable(GL_FRAMEBUFFER_SRGB);
glViewport(0, 0, 1024, 1024);
glm::mat4 depthproj = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.1f, 100.0f);
glm::vec3 playerpos = glm::vec3(World.Camera.Pos.x, World.Camera.Pos.y, World.Camera.Pos.z);
glm::vec3 shadoweye = playerpos - Global::daylight.direction * 50.0f;
Global::SetCameraPosition(Math3D::vector3(shadoweye));
glm::mat4 depthcam = glm::lookAt(shadoweye,
playerpos,
glm::vec3(0.0f, 1.0f, 0.0f));
m_camera.update_frustum(depthproj, depthcam);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(depthproj));
glMatrixMode(GL_MODELVIEW);
glMultMatrixf(glm::value_ptr(glm::mat4(glm::mat3(depthcam))));
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
active_shader = &depth_shader; depth_shader.bind();
Render(&World.Ground);
active_shader = nullptr; depth_shader.unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, Global::ScreenWidth, Global::ScreenHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(perspective));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, depth_tex);
glActiveTexture(GL_TEXTURE0);
glm::dmat4 worldcamera;
World.Camera.SetMatrix( worldcamera );
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
// 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 ))));
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera);
::glMultMatrixd(glm::value_ptr(glm::dmat4(glm::dmat3(worldcamera))));
glDebug("rendering environment");
glDisable(GL_FRAMEBUFFER_SRGB);
Render( &World.Environment );
glDebug("rendering world");
shader.bind();
glEnable(GL_FRAMEBUFFER_SRGB);
shader.bind(); active_shader = &shader;
glm::vec3 transdiff = Global::daylight.direction * 50.0f;
glm::mat3 rotdiff = glm::inverse(glm::mat3(depthcam)) * glm::mat3(worldcamera);
glm::mat4 lv = depthproj * glm::translate(glm::mat4(rotdiff), transdiff);
shader.set_lightview(lv);
Render( &World.Ground );
glDebug("rendering cab");
@@ -174,7 +233,7 @@ opengl_renderer::Render() {
}
glDebug("rendering ui");
shader.unbind();
gl_program::unbind(); active_shader = nullptr;
glEnable(GL_FRAMEBUFFER_SRGB);
UILayer.render();
glDebug("rendering end");
@@ -364,7 +423,7 @@ opengl_renderer::Texture( texture_handle const Texture ) {
bool
opengl_renderer::Render( TGround *Ground ) {
shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
active_shader->set_p(OpenGLMatrices.data(GL_PROJECTION));
::glEnable( GL_LIGHTING );
::glDisable( GL_BLEND );
@@ -525,7 +584,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
}
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
shader.set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
switch (Node->iType) {
@@ -722,16 +781,14 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
void opengl_renderer::Render(TSubModel *Submodel)
{
shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
active_shader->copy_gl_mvp();
Render(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
shader.set_material(0.0f, glm::vec3(0.0f));
}
void opengl_renderer::Render_Alpha(TSubModel *Submodel)
{
shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
active_shader->copy_gl_mvp();;
Render_Alpha(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
shader.set_material(0.0f, glm::vec3(0.0f));
}
@@ -750,7 +807,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
mm *= glm::make_mat4(Submodel->fMatrix->e);
if (Submodel->b_Anim)
Submodel->RaAnimation(mm, Submodel->b_Anim);
shader.set_mv(mm);
active_shader->set_mv(mm);
}
if( Submodel->eType < TP_ROTATOR ) {
@@ -796,6 +853,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
gl_program::unbind();
glEnableClientState(GL_VERTEX_ARRAY);
glPushMatrix();
glLoadMatrixf(glm::value_ptr(mm));
glVertexPointer(3, GL_FLOAT, sizeof(basic_vertex), static_cast<char *>(nullptr)); // pozycje
@@ -814,6 +872,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
// post-draw reset
::glPopAttrib();
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
gl_program::bind_last();
}
@@ -848,7 +907,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
Render( Submodel->Child, mm );
if( Submodel->iFlags & 0xC000 )
shader.set_mv(m);
active_shader->set_mv(m);
}
if( Submodel->b_Anim < at_SecondsJump )
@@ -960,7 +1019,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
}
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
shader.set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
switch (Node->iType)
{
@@ -1196,7 +1255,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
mm *= glm::make_mat4(Submodel->fMatrix->e);
if (Submodel->b_Anim)
Submodel->RaAnimation(mm, Submodel->b_Anim);
shader.set_mv(mm);
active_shader->set_mv(mm);
}
if( Submodel->eType < TP_ROTATOR ) {
@@ -1250,6 +1309,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
glm::mat4 x = glm::mat4(1.0f);
x = glm::translate(x, glm::vec3(lightcenter.x, lightcenter.y, lightcenter.z)); // początek układu zostaje bez zmian
x = glm::rotate(x, atan2(lightcenter.x, lightcenter.y), glm::vec3(0.0f, 1.0f, 0.0f)); // jedynie obracamy w pionie o kąt
glPushMatrix();
glLoadMatrixf(glm::value_ptr(x));
// main draw call
@@ -1262,6 +1322,7 @@ 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
*/
glPopMatrix();
::glPopAttrib();
glDisableClientState(GL_VERTEX_ARRAY);
@@ -1276,7 +1337,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
Render_Alpha( Submodel->Child, mm );
if( Submodel->iFlags & 0xC000 )
shader.set_mv(m);
active_shader->set_mv(m);
}
if( Submodel->b_aAnim < at_SecondsJump )

View File

@@ -61,6 +61,9 @@ class opengl_renderer {
public:
gl_program_light shader;
gl_program_mvp depth_shader;
gl_program_mvp *active_shader = nullptr;
GLuint depth_tex, depth_fbo;
// types

View File

@@ -131,9 +131,12 @@ void gl_program_mvp::copy_gl_mvp()
void gl_program_mvp::set_mv(const glm::mat4 &m)
{
glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(m)));
if (mvn_uniform != -1)
{
glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(m)));
glUniformMatrix3fv(mvn_uniform, 1, GL_FALSE, glm::value_ptr(mvn));
}
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)
@@ -145,6 +148,9 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
{
bind();
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");
@@ -167,22 +173,36 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
glUniform1ui(lcount_uniform, 0);
}
void gl_program_light::set_lightview(glm::mat4 &lightview)
{
if (current_program != this)
return;
glUniformMatrix4fv(lightview_uniform, 1, GL_FALSE, glm::value_ptr(lightview));
}
void gl_program_light::set_ambient(glm::vec3 &ambient)
{
bind();
if (current_program != this)
return;
glUniform3fv(ambient_uniform, 1, glm::value_ptr(ambient));
}
void gl_program_light::set_fog(float density, glm::vec3 &color)
{
bind();
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)
{
bind();
if (current_program != this)
return;
glUniform1ui(lcount_uniform, count);
}
@@ -190,12 +210,14 @@ void gl_program_light::set_light(GLuint i, type t, glm::vec3 &pos, glm::vec3 &di
float in_cutoff, float out_cutoff,
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);
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));
@@ -208,7 +230,9 @@ 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)
{
bind();
if (current_program != this)
return;
glUniform1f(specular_uniform, specular);
glUniform3fv(emission_uniform, 1, glm::value_ptr(emission));
}

View File

@@ -35,7 +35,7 @@ public:
class gl_program_mvp : public gl_program
{
GLuint mv_uniform;
GLuint mvn_uniform;
GLint mvn_uniform;
GLuint p_uniform;
public:
@@ -62,6 +62,7 @@ public:
gl_program_light() = default;
gl_program_light(std::vector<gl_shader>);
void set_lightview(glm::mat4 &lightview);
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);
@@ -70,6 +71,7 @@ public:
glm::vec3 &color, float linear, float quadratic);
private:
GLuint lightview_uniform;
GLuint ambient_uniform;
GLuint specular_uniform;
GLuint fog_color_uniform;

View File

@@ -23,10 +23,12 @@ struct light_s
in vec3 f_normal;
in vec2 f_coord;
in vec3 f_pos;
in vec4 f_light_pos;
out vec4 color;
uniform sampler2D tex;
uniform sampler2D shadowmap;
uniform vec3 ambient;
uniform vec3 emission;
@@ -37,6 +39,16 @@ uniform float specular;
uniform light_s lights[8];
uniform uint lights_count;
float calc_shadow()
{
vec3 coords = f_light_pos.xyz / f_light_pos.w;
coords = coords * 0.5 + 0.5;
float closest_depth = texture(shadowmap, coords.xy).r;
float current_depth = coords.z;
float shadow = current_depth > closest_depth ? 0.0 : 1.0;
return shadow;
}
vec3 apply_fog(vec3 color)
{
float sun_amount = 0.0;
@@ -90,6 +102,7 @@ float calc_dir_light(light_s light)
void main()
{
float shadow = calc_shadow();
vec3 result = ambient * 0.3 + emission;
for (uint i = 0U; i < lights_count; i++)
{
@@ -103,7 +116,7 @@ void main()
else if (light.type == LIGHT_DIR)
part = calc_dir_light(light);
result += light.color * part;
result += light.color * part * shadow;
}
vec4 tex_color = texture(tex, f_coord);

7
shaders/empty.frag Normal file
View File

@@ -0,0 +1,7 @@
#version 330
in vec3 f_pos;
void main()
{
}

View File

@@ -7,7 +7,9 @@ layout (location = 2) in vec2 v_coord;
out vec3 f_normal;
out vec2 f_coord;
out vec3 f_pos;
out vec4 f_light_pos;
uniform mat4 lightview;
uniform mat4 modelview;
uniform mat3 modelviewnormal;
uniform mat4 projection;
@@ -18,4 +20,6 @@ void main()
f_normal = modelviewnormal * v_normal;
f_coord = v_coord;
f_pos = vec3(modelview * vec4(v_vert, 1.0f));
//f_light_pos = lightview * vec4(f_pos, 1.0f);
f_light_pos = lightview * vec4(f_pos, 1.0f);
}

13
shaders/shadowmap.vert Normal file
View File

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