From 0c5f990528dd8f4d0dd25e8543d0ffa15c402cee Mon Sep 17 00:00:00 2001 From: milek7 Date: Sun, 24 Jun 2018 20:21:07 +0200 Subject: [PATCH] further pruning of legacy render code, now runs on opengl 3.3 core profile --- CMakeLists.txt | 7 +- EU07.cpp | 4 + Logs.cpp | 5 +- PyInt.cpp | 4 +- Segment.cpp | 3 + Texture.cpp | 18 +- gl/object.h | 32 +++ gl/shader.cpp | 105 ++++++++ gl/shader.h | 32 +++ gl/shader_mvp.cpp | 30 +++ gl/shader_mvp.h | 22 ++ moon.cpp | 12 +- openglgeometrybank.cpp | 41 ++- openglmatrixstack.h | 4 +- renderer.cpp | 457 +++++++--------------------------- renderer.h | 3 + shader.cpp | 267 -------------------- shader.h | 148 ----------- shaders/blinnphong.frag | 141 ----------- shaders/color.frag | 4 +- shaders/empty.frag | 10 - shaders/lighting.vert | 24 -- shaders/notex-blinnphong.frag | 137 ---------- shaders/notex-lighting.vert | 21 -- shaders/shadowmap.vert | 15 -- shaders/vbocolor.vert | 6 +- skydome.cpp | 38 +-- skydome.h | 5 + sun.cpp | 13 +- uilayer.cpp | 33 +-- 30 files changed, 400 insertions(+), 1241 deletions(-) create mode 100644 gl/object.h create mode 100644 gl/shader.cpp create mode 100644 gl/shader.h create mode 100644 gl/shader_mvp.cpp create mode 100644 gl/shader_mvp.h delete mode 100644 shader.cpp delete mode 100644 shader.h delete mode 100644 shaders/blinnphong.frag delete mode 100644 shaders/empty.frag delete mode 100644 shaders/lighting.vert delete mode 100644 shaders/notex-blinnphong.frag delete mode 100644 shaders/notex-lighting.vert delete mode 100644 shaders/shadowmap.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index dc42695f..409bc6d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ set(DEPS_DIR ${DEPS_DIR} "${CMAKE_SOURCE_DIR}/ref") project("eu07") set(CMAKE_CXX_STANDARD 14) -include_directories("." "Console" "McZapkie") -file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h") +include_directories("." "Console" "McZapkie" "gl") +file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h" "gl/*.h") set(SOURCES "Texture.cpp" @@ -54,7 +54,6 @@ set(SOURCES "skydome.cpp" "sound.cpp" "Spring.cpp" -"shader.cpp" "frustum.cpp" "uilayer.cpp" "openglmatrixstack.cpp" @@ -81,6 +80,8 @@ set(SOURCES "light.cpp" "uitranscripts.cpp" "station.cpp" +"gl/shader.cpp" +"gl/shader_mvp.cpp" ) set (PREFIX "") diff --git a/EU07.cpp b/EU07.cpp index 20a7757d..d8f7633a 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -300,6 +300,10 @@ int main(int argc, char *argv[]) GLFWmonitor *monitor = glfwGetPrimaryMonitor(); const GLFWvidmode *vmode = glfwGetVideoMode(monitor); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_RED_BITS, vmode->redBits); glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits); glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits); diff --git a/Logs.cpp b/Logs.cpp index f22be881..61e405b3 100644 --- a/Logs.cpp +++ b/Logs.cpp @@ -82,24 +82,23 @@ void WriteLog( const char *str, logtype const Type ) { output.open( filename, std::ios::trunc ); } output << str << "\n"; - output.flush(); } ui_log->text_lines.emplace_back(std::string(str), Global.UITextColor); if (ui_log->text_lines.size() > 20) ui_log->text_lines.pop_front(); -#ifdef _WIN32 if( Global.iWriteLogEnabled & 2 ) { +#ifdef _WIN32 // hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY ); DWORD wr = 0; WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL ); WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL ); - } #else printf("%s\n", str); #endif + } } // Ra: bezwarunkowa rejestracja poważnych błędów diff --git a/PyInt.cpp b/PyInt.cpp index e8570c6d..333f99ff 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -276,10 +276,8 @@ void TPythonScreenRenderer::updateTexture() */ GfxRenderer.Bind_Material(_textureId); // setup texture parameters - glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); - glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); // build texture glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData ); diff --git a/Segment.cpp b/Segment.cpp index b723be85..6330b8e6 100644 --- a/Segment.cpp +++ b/Segment.cpp @@ -531,6 +531,8 @@ void TSegment::Render() Math3D::vector3 pt; GfxRenderer.Bind_Material( null_handle ); + //m7t + /* if (bCurve) { glColor3f(0, 0, 1.0f); @@ -572,6 +574,7 @@ void TSegment::Render() glVertex3f(Point2.x + CPointIn.x, Point2.y + CPointIn.y, Point2.z + CPointIn.z); glEnd(); } + */ } //--------------------------------------------------------------------------- diff --git a/Texture.cpp b/Texture.cpp index d80508ce..f3ffbcfd 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -613,10 +613,6 @@ opengl_texture::create() { set_filtering(); - if( data_mapcount == 1 ) { - // fill missing mipmaps if needed - ::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); - } // upload texture data int dataoffset = 0, datasize = 0, @@ -654,6 +650,11 @@ opengl_texture::create() { } } + if( data_mapcount == 1 ) { + // fill missing mipmaps if needed + glGenerateMipmap(GL_TEXTURE_2D); + } + if( ( true == Global.ResourceMove ) || ( false == Global.ResourceSweep ) ) { // if garbage collection is disabled we don't expect having to upload the texture more than once @@ -730,15 +731,6 @@ opengl_texture::set_filtering() const { default: { break; } } } - - if( true == sharpen ) { - // #: sharpen more - ::glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -2.0 ); - } - else { - // regular texture sharpening - ::glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 ); - } } void diff --git a/gl/object.h b/gl/object.h new file mode 100644 index 00000000..ce975a60 --- /dev/null +++ b/gl/object.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace gl +{ + class object + { + private: + GLuint id = 0; + + public: + inline operator GLuint() const + { + return id; + } + + inline operator GLuint* const() + { + return &id; + } + + inline operator const GLuint* const() const + { + return &id; + } + + object() = default; + object(const object&) = delete; + object& operator=(const object&) = delete; + }; +} diff --git a/gl/shader.cpp b/gl/shader.cpp new file mode 100644 index 00000000..07d86f71 --- /dev/null +++ b/gl/shader.cpp @@ -0,0 +1,105 @@ +#include "stdafx.h" + +#include +#include +#include "shader.h" + +inline bool strcend(std::string const &value, std::string const &ending) +{ + if (ending.size() > value.size()) + return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +gl::shader::shader(const std::string &filename) +{ + std::stringstream stream; + std::ifstream f; + f.exceptions(std::ifstream::badbit); + + f.open(filename); + stream << f.rdbuf(); + f.close(); + + std::string str = stream.str(); + const GLchar *cstr = str.c_str(); + + if (!cstr[0]) + throw std::runtime_error("cannot read shader " + filename); + + GLuint type; + if (strcend(filename, ".vert")) + type = GL_VERTEX_SHADER; + else if (strcend(filename, ".frag")) + type = GL_FRAGMENT_SHADER; + else + throw std::runtime_error("unknown shader " + filename); + + **this = glCreateShader(type); + glShaderSource(*this, 1, &cstr, 0); + glCompileShader(*this); + + GLint status; + glGetShaderiv(*this, GL_COMPILE_STATUS, &status); + if (!status) + { + GLchar info[512]; + glGetShaderInfoLog(*this, 512, 0, info); + throw std::runtime_error("failed to compile " + filename + ": " + std::string(info)); + } + +} + +gl::shader::~shader() +{ + glDeleteShader(*this); +} + +void gl::program::init() +{ + bind(); + glUniform1i(glGetUniformLocation(*this, "tex"), 3); +} + +gl::program::program() +{ + **this = glCreateProgram(); +} + +gl::program::program(std::vector> shaders) : program() +{ + for (const gl::shader &s : shaders) + attach(s); + link(); +} + +void gl::program::attach(const gl::shader &s) +{ + glAttachShader(*this, *s); +} + +void gl::program::link() +{ + glLinkProgram(*this); + + GLint status; + glGetProgramiv(*this, GL_LINK_STATUS, &status); + if (!status) + { + GLchar info[512]; + glGetProgramInfoLog(*this, 512, 0, info); + throw std::runtime_error("failed to link program: " + std::string(info)); + } + + init(); +} + +gl::program::~program() +{ + glDeleteProgram(*this); +} + +void gl::program::bind() +{ + glUseProgram(*this); +} diff --git a/gl/shader.h b/gl/shader.h new file mode 100644 index 00000000..fa13fcbf --- /dev/null +++ b/gl/shader.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include + +#include "object.h" + +namespace gl +{ + class shader : public object + { + public: + shader(const std::string &filename); + ~shader(); + }; + + class program : public object + { + public: + program(); + program(std::vector>); + ~program(); + + void bind(); + + void attach(const shader &); + void link(); + + virtual void init(); + }; +} diff --git a/gl/shader_mvp.cpp b/gl/shader_mvp.cpp new file mode 100644 index 00000000..f518a498 --- /dev/null +++ b/gl/shader_mvp.cpp @@ -0,0 +1,30 @@ +#include "stdafx.h" +#include "shader_mvp.h" + +void gl::program_mvp::init() +{ + mv_uniform = glGetUniformLocation(*this, "modelview"); + mvn_uniform = glGetUniformLocation(*this, "modelviewnormal"); + p_uniform = glGetUniformLocation(*this, "projection"); +} + +void gl::program_mvp::set_mv(const glm::mat4 &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)); +} + +void gl::program_mvp::set_p(const glm::mat4 &m) +{ + glUniformMatrix4fv(p_uniform, 1, GL_FALSE, glm::value_ptr(m)); +} + +void gl::program_mvp::copy_gl_mvp() +{ + set_mv(OpenGLMatrices.data(GL_MODELVIEW)); + set_p(OpenGLMatrices.data(GL_PROJECTION)); +} diff --git a/gl/shader_mvp.h b/gl/shader_mvp.h new file mode 100644 index 00000000..7e309fc7 --- /dev/null +++ b/gl/shader_mvp.h @@ -0,0 +1,22 @@ +#pragma once + +#include "shader.h" + +namespace gl +{ + class program_mvp : public program + { + GLuint mv_uniform; + GLint mvn_uniform; + GLuint p_uniform; + + public: + using program::program; + + void set_mv(const glm::mat4 &); + void set_p(const glm::mat4 &); + void copy_gl_mvp(); + + virtual void init() override; + }; +} diff --git a/moon.cpp b/moon.cpp index 799d5e1c..5b0158dd 100644 --- a/moon.cpp +++ b/moon.cpp @@ -49,17 +49,7 @@ cMoon::update() { void cMoon::render() { - ::glColor4f( 225.f / 255.f, 225.f / 255.f, 255.f / 255.f, 1.f ); - // debug line to locate the moon easier - auto const position { m_position * 2000.f }; - ::glBegin( GL_LINES ); - ::glVertex3fv( glm::value_ptr( position ) ); - ::glVertex3f( position.x, 0.f, position.z ); - ::glEnd(); - ::glPushMatrix(); - ::glTranslatef( position.x, position.y, position.z ); - ::gluSphere( moonsphere, /* (float)( Global.iWindowHeight / Global.FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 ); - ::glPopMatrix(); + //m7t } glm::vec3 diff --git a/openglgeometrybank.cpp b/openglgeometrybank.cpp index 87214a5b..8dba5843 100644 --- a/openglgeometrybank.cpp +++ b/openglgeometrybank.cpp @@ -255,40 +255,31 @@ void opengl_vbogeometrybank::bind_streams( gfx::stream_units const &Units, unsigned int const Streams ) { if( Streams & gfx::stream::position ) { - ::glVertexPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast( nullptr ) ); - ::glEnableClientState( GL_VERTEX_ARRAY ); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)0); + glEnableVertexAttribArray(0); } else { - ::glDisableClientState( GL_VERTEX_ARRAY ); + glDisableVertexAttribArray(0); } // NOTE: normal and color streams share the data, making them effectively mutually exclusive if( Streams & gfx::stream::normal ) { - ::glNormalPointer( GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast( nullptr ) + sizeof( float ) * 3 ); - ::glEnableClientState( GL_NORMAL_ARRAY ); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(3 * sizeof(GL_FLOAT))); + glEnableVertexAttribArray(1); } else { - ::glDisableClientState( GL_NORMAL_ARRAY ); + glDisableVertexAttribArray(1); } if( Streams & gfx::stream::color ) { - ::glColorPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast( nullptr ) + sizeof( float ) * 3 ); - ::glEnableClientState( GL_COLOR_ARRAY ); - } - else { - ::glDisableClientState( GL_COLOR_ARRAY ); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(3 * sizeof(GL_FLOAT))); + glEnableVertexAttribArray(1); } if( Streams & gfx::stream::texture ) { - for( auto unit : Units.texture ) { - ::glClientActiveTexture( unit ); - ::glTexCoordPointer( 2, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast( nullptr ) + 24 ); - ::glEnableClientState( GL_TEXTURE_COORD_ARRAY ); - } + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(6 * sizeof(GL_FLOAT))); + glEnableVertexAttribArray(2); m_activetexturearrays = Units.texture; } else { - for( auto unit : Units.texture ) { - ::glClientActiveTexture( unit ); - ::glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - } + glDisableVertexAttribArray(2); m_activetexturearrays.clear(); // NOTE: we're simplifying here, since we always toggle the same texture coord sets } @@ -298,13 +289,9 @@ opengl_vbogeometrybank::bind_streams( gfx::stream_units const &Units, unsigned i void opengl_vbogeometrybank::release_streams() { - ::glDisableClientState( GL_VERTEX_ARRAY ); - ::glDisableClientState( GL_NORMAL_ARRAY ); - ::glDisableClientState( GL_COLOR_ARRAY ); - for( auto unit : m_activetexturearrays ) { - ::glClientActiveTexture( unit ); - ::glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); m_activestreams = gfx::stream::none; m_activetexturearrays.clear(); diff --git a/openglmatrixstack.h b/openglmatrixstack.h index fd453877..1b8ba1d3 100644 --- a/openglmatrixstack.h +++ b/openglmatrixstack.h @@ -84,7 +84,7 @@ private: // methods: void - upload() { ::glLoadMatrixf( glm::value_ptr( m_stack.top() ) ); } + upload() { } // members: mat4_stack m_stack; @@ -109,7 +109,7 @@ public: case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; } case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; } default: { break; } } - ::glMatrixMode( Mode ); } + } glm::mat4 const & data( GLuint const Mode = -1 ) const { switch( Mode ) { diff --git a/renderer.cpp b/renderer.cpp index 48717f03..f8f46298 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -27,37 +27,17 @@ int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental void opengl_light::apply_intensity( float const Factor ) { - - if( Factor == 1.0 ) { - - ::glLightfv( id, GL_AMBIENT, glm::value_ptr( ambient ) ); - ::glLightfv( id, GL_DIFFUSE, glm::value_ptr( diffuse ) ); - ::glLightfv( id, GL_SPECULAR, glm::value_ptr( specular ) ); - } - else { - // temporary light scaling mechanics (ultimately this work will be left to the shaders - glm::vec4 scaledambient( ambient.r * Factor, ambient.g * Factor, ambient.b * Factor, ambient.a ); - glm::vec4 scaleddiffuse( diffuse.r * Factor, diffuse.g * Factor, diffuse.b * Factor, diffuse.a ); - glm::vec4 scaledspecular( specular.r * Factor, specular.g * Factor, specular.b * Factor, specular.a ); - glLightfv( id, GL_AMBIENT, glm::value_ptr( scaledambient ) ); - glLightfv( id, GL_DIFFUSE, glm::value_ptr( scaleddiffuse ) ); - glLightfv( id, GL_SPECULAR, glm::value_ptr( scaledspecular ) ); - } + // m7t setup light ubo here } void opengl_light::apply_angle() { - - ::glLightfv( id, GL_POSITION, glm::value_ptr( glm::vec4{ position, ( is_directional ? 0.f : 1.f ) } ) ); - if( false == is_directional ) { - ::glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr( direction ) ); - } + // m7t setup light ubo here } - void -opengl_camera::update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview ) { - +opengl_camera::update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview ) +{ m_frustum.calculate( Projection, Modelview ); // cache inverse tranformation matrix // NOTE: transformation is done only to camera-centric space @@ -71,14 +51,14 @@ opengl_camera::update_frustum( glm::mat4 const &Projection, glm::mat4 const &Mod // returns true if specified object is within camera frustum, false otherwise bool -opengl_camera::visible( scene::bounding_area const &Area ) const { - +opengl_camera::visible( scene::bounding_area const &Area ) const +{ return ( m_frustum.sphere_inside( Area.center, Area.radius ) > 0.f ); } bool -opengl_camera::visible( TDynamicObject const *Dynamic ) const { - +opengl_camera::visible( TDynamicObject const *Dynamic ) const +{ // sphere test is faster than AABB, so we'll use it here glm::vec3 diagonal( static_cast( Dynamic->MoverParameters->Dim.L ), @@ -92,13 +72,16 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const { // debug helper, draws shape of frustum in world space void -opengl_camera::draw( glm::vec3 const &Offset ) const { - +opengl_camera::draw( glm::vec3 const &Offset ) const +{ + // m7t port to core gl + /* ::glBegin( GL_LINES ); for( auto const pointindex : frustumshapepoinstorder ) { ::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) ); } ::glEnd(); + */ } bool @@ -108,16 +91,14 @@ opengl_renderer::Init( GLFWwindow *Window ) { m_window = Window; - ::glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - ::glPixelStorei( GL_PACK_ALIGNMENT, 1 ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glPixelStorei( GL_PACK_ALIGNMENT, 1 ); glClearDepth( 1.0f ); glClearColor( 51.0f / 255.0f, 102.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // initial background Color - glPolygonMode( GL_FRONT, GL_FILL ); - glFrontFace( GL_CCW ); // Counter clock-wise polygons face out - glEnable( GL_CULL_FACE ); // Cull back-facing triangles - glShadeModel( GL_SMOOTH ); // Enable Smooth Shading + glFrontFace( GL_CCW ); + glEnable( GL_CULL_FACE ); m_geometry.units().texture = ( Global.BasicRenderer ? @@ -127,34 +108,18 @@ opengl_renderer::Init( GLFWwindow *Window ) { UILayer.set_unit( m_diffusetextureunit ); select_unit( m_diffusetextureunit ); - ::glDepthFunc( GL_LEQUAL ); + glDepthFunc( GL_LEQUAL ); glEnable( GL_DEPTH_TEST ); - glAlphaFunc( GL_GREATER, 0.f ); - glEnable( GL_ALPHA_TEST ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_BLEND ); - glEnable( GL_TEXTURE_2D ); // Enable Texture Mapping - glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Really Nice Perspective Calculations - glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST ); - glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glLineWidth( 1.0f ); glPointSize( 3.0f ); - glEnable( GL_POINT_SMOOTH ); - ::glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR ); - ::glMaterialf( GL_FRONT, GL_SHININESS, 15.0f ); if( true == Global.ScaleSpecularValues ) { m_specularopaquescalefactor = 0.25f; m_speculartranslucentscalefactor = 1.5f; } - ::glEnable( GL_COLOR_MATERIAL ); - ::glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); - - // setup lighting - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) ); - ::glEnable( GL_LIGHTING ); - ::glEnable( opengl_renderer::sunlight ); // rgb value for 5780 kelvin Global.DayLight.diffuse[ 0 ] = 255.0f / 255.0f; @@ -162,7 +127,6 @@ opengl_renderer::Init( GLFWwindow *Window ) { Global.DayLight.diffuse[ 2 ] = 231.0f / 255.0f; Global.DayLight.is_directional = true; m_sunlight.id = opengl_renderer::sunlight; - // ::glLightf( opengl_renderer::sunlight, GL_SPOT_CUTOFF, 90.0f ); // create dynamic light pool for( int idx = 0; idx < Global.DynamicLightCount; ++idx ) { @@ -171,12 +135,8 @@ opengl_renderer::Init( GLFWwindow *Window ) { light.id = GL_LIGHT1 + idx; light.is_directional = false; - ::glEnable( light.id ); // experimental intel chipset fix - ::glLightf( light.id, GL_SPOT_CUTOFF, 7.5f ); - ::glLightf( light.id, GL_SPOT_EXPONENT, 7.5f ); - ::glLightf( light.id, GL_CONSTANT_ATTENUATION, 0.0f ); - ::glLightf( light.id, GL_LINEAR_ATTENUATION, 0.035f ); - ::glDisable( light.id ); // experimental intel chipset fix + + //m7t config light ubo here m_lights.emplace_back( light ); } @@ -199,11 +159,16 @@ opengl_renderer::Init( GLFWwindow *Window ) { { { size, size, 0.f }, glm::vec3(), { 0.f, 1.f } }, { { -size, -size, 0.f }, glm::vec3(), { 1.f, 0.f } }, { { size, -size, 0.f }, glm::vec3(), { 0.f, 0.f } } }, - geometrybank, -GL_TRIANGLE_STRIP ); - // prepare debug mode objects - m_quadric = ::gluNewQuadric(); - ::gluQuadricNormals( m_quadric, GLU_FLAT ); + geometrybank, GL_TRIANGLE_STRIP ); + + gl::shader vert("shaders/simple.vert"); + gl::shader frag("shaders/simple.frag"); + shader = std::make_unique(std::vector>({vert, frag})); + shader->init(); + + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); return true; } @@ -278,20 +243,11 @@ opengl_renderer::Render() { // runs jobs needed to generate graphics for specified render pass void opengl_renderer::Render_pass( rendermode const Mode ) { - -#ifdef EU07_USE_DEBUG_CAMERA - // setup world camera for potential visualization - setup_pass( - m_worldcamera, - rendermode::color, - 0.f, - 1.0, - true ); -#endif setup_pass( m_renderpass, Mode ); switch( m_renderpass.draw_mode ) { case rendermode::color: { + glDebug("color pass"); if( ( true == m_environmentcubetexturesupport ) && ( true == World.InitPerformed() ) ) { @@ -318,30 +274,15 @@ opengl_renderer::Render_pass( rendermode const Mode ) { // render setup_drawing( true ); setup_units( true, false, false ); + glDebug("render environment"); Render( &World.Environment ); // opaque parts... setup_drawing( false ); setup_units( true, true, true ); -#ifdef EU07_USE_DEBUG_CAMERA - if( DebugModeFlag ) { - // draw light frustum - ::glLineWidth( 2.f ); - ::glColor4f( 1.f, 0.9f, 0.8f, 1.f ); - ::glDisable( GL_LIGHTING ); - ::glDisable( GL_TEXTURE_2D ); - if( ( true == Global.RenderShadows ) && ( false == Global.bWireFrame ) ) { - m_shadowpass.camera.draw( m_renderpass.camera.position() - m_shadowpass.camera.position() ); - } - if( DebugCameraFlag ) { - ::glColor4f( 0.8f, 1.f, 0.9f, 1.f ); - m_worldcamera.camera.draw( m_renderpass.camera.position() - m_worldcamera.camera.position() ); - } - ::glLineWidth( 1.f ); - ::glEnable( GL_LIGHTING ); - ::glEnable( GL_TEXTURE_2D ); - } -#endif + shader->bind(); + if( false == FreeFlyModeFlag ) { + glDebug("render cab opaque"); switch_units( true, true, false ); setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix ); // cache shadow colour in case we need to account for cab light @@ -355,13 +296,18 @@ opengl_renderer::Render_pass( rendermode const Mode ) { setup_shadow_color( shadowcolor ); } } + + glDebug("render opaque region"); switch_units( true, true, true ); setup_shadow_map( m_shadowtexture, m_shadowtexturematrix ); Render( simulation::Region ); + // ...translucent parts + glDebug("render translucent region"); setup_drawing( true ); Render_Alpha( simulation::Region ); if( false == FreeFlyModeFlag ) { + glDebug("render translucent cab"); // cab render is performed without shadows, due to low resolution and number of models without windows :| switch_units( true, true, false ); setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix ); @@ -377,6 +323,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) { } } + glUseProgram(0); + if( m_environmentcubetexturesupport ) { // restore default texture matrix for reflections cube map select_unit( m_helpertextureunit ); @@ -385,8 +333,13 @@ opengl_renderer::Render_pass( rendermode const Mode ) { select_unit( m_diffusetextureunit ); ::glMatrixMode( GL_MODELVIEW ); } + + glDebug("color pass done"); } + + glDebug("render ui"); UILayer.render(); + glDebug("ui render done"); break; } @@ -508,32 +461,21 @@ opengl_renderer::setup_matrices() { void opengl_renderer::setup_drawing( bool const Alpha ) { - if( true == Alpha ) { - + if( true == Alpha ) ::glEnable( GL_BLEND ); - ::glAlphaFunc( GL_ALWAYS, 0.0f ); - } - else { + else ::glDisable( GL_BLEND ); - ::glAlphaFunc( GL_GREATER, 0.5f ); - } switch( m_renderpass.draw_mode ) { case rendermode::color: case rendermode::reflections: { - ::glEnable( GL_LIGHTING ); - ::glShadeModel( GL_SMOOTH ); if( Global.iMultisampling ) { ::glEnable( GL_MULTISAMPLE ); } // setup fog if( Global.fFogEnd > 0 ) { - // fog setup - ::glFogfv( GL_FOG_COLOR, glm::value_ptr( Global.FogColor ) ); - ::glFogf( GL_FOG_DENSITY, static_cast( 1.0 / Global.fFogEnd ) ); - ::glEnable( GL_FOG ); + // m7t setup fog ubo } - else { ::glDisable( GL_FOG ); } break; } @@ -553,7 +495,6 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const // diffuse texture unit. // NOTE: diffuse texture mapping is never fully disabled, alpha channel information is always included select_unit( m_diffusetextureunit ); - ::glEnable( GL_TEXTURE_2D ); // update unit state m_unitstate.diffuse = Diffuse; @@ -573,14 +514,10 @@ opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool cons // diffuse texture unit. // NOTE: toggle actually disables diffuse texture mapping, unlike setup counterpart if( true == Diffuse ) { - select_unit( m_diffusetextureunit ); - ::glEnable( GL_TEXTURE_2D ); } else { - select_unit( m_diffusetextureunit ); - ::glDisable( GL_TEXTURE_2D ); } // update unit state m_unitstate.diffuse = Diffuse; @@ -641,7 +578,6 @@ opengl_renderer::Render( world_environment *Environment ) { } Bind_Material( null_handle ); - ::glDisable( GL_LIGHTING ); ::glDisable( GL_DEPTH_TEST ); ::glDepthMask( GL_FALSE ); ::glPushMatrix(); @@ -650,129 +586,20 @@ opengl_renderer::Render( world_environment *Environment ) { Environment->m_skydome.Render(); // skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh gfx::opengl_vbogeometrybank::reset(); - // stars - if( Environment->m_stars.m_stars != nullptr ) { - // setup - ::glPushMatrix(); - ::glRotatef( Environment->m_stars.m_latitude, 1.f, 0.f, 0.f ); // ustawienie osi OY na północ - ::glRotatef( -std::fmod( (float)Global.fTimeAngleDeg, 360.f ), 0.f, 1.f, 0.f ); // obrót dobowy osi OX - ::glPointSize( 2.f ); - // render - GfxRenderer.Render( Environment->m_stars.m_stars, nullptr, 1.0 ); - // post-render cleanup - ::glPointSize( 3.f ); - ::glPopMatrix(); - } - // celestial bodies - float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f; - glm::vec3 suncolor = interpolate( - glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ), - glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ), - duskfactor ); + //m7t: restore celestial bodies - if( DebugModeFlag == true ) { - // mark sun position for easier debugging - Environment->m_sun.render(); - Environment->m_moon.render(); - } - // render actual sun and moon - ::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT ); - - ::glDisable( GL_LIGHTING ); - ::glDisable( GL_ALPHA_TEST ); - ::glEnable( GL_BLEND ); - ::glBlendFunc( GL_SRC_ALPHA, GL_ONE ); - - auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW ); - // sun - { - Bind_Texture( m_suntexture ); - ::glColor4f( suncolor.x, suncolor.y, suncolor.z, 1.0f ); - auto const sunvector = Environment->m_sun.getDirection(); - auto const sunposition = modelview * glm::vec4( sunvector.x, sunvector.y, sunvector.z, 1.0f ); - - ::glPushMatrix(); - ::glLoadIdentity(); // macierz jedynkowa - ::glTranslatef( sunposition.x, sunposition.y, sunposition.z ); // początek układu zostaje bez zmian - - float const size = 0.045f; - ::glBegin( GL_TRIANGLE_STRIP ); - ::glMultiTexCoord2f( m_diffusetextureunit, 1.f, 1.f ); ::glVertex3f( -size, size, 0.f ); - ::glMultiTexCoord2f( m_diffusetextureunit, 1.f, 0.f ); ::glVertex3f( -size, -size, 0.f ); - ::glMultiTexCoord2f( m_diffusetextureunit, 0.f, 1.f ); ::glVertex3f( size, size, 0.f ); - ::glMultiTexCoord2f( m_diffusetextureunit, 0.f, 0.f ); ::glVertex3f( size, -size, 0.f ); - ::glEnd(); - - ::glPopMatrix(); - } - // moon - { - Bind_Texture( m_moontexture ); - glm::vec3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ); - // fade the moon if it's near the sun in the sky, especially during the day - ::glColor4f( - mooncolor.r, mooncolor.g, mooncolor.b, - std::max( - 0.f, - 1.0 - - 0.5 * Global.fLuminance - - 0.65 * std::max( 0.f, glm::dot( Environment->m_sun.getDirection(), Environment->m_moon.getDirection() ) ) ) ); - - auto const moonposition = modelview * glm::vec4( Environment->m_moon.getDirection(), 1.0f ); - ::glPushMatrix(); - ::glLoadIdentity(); // macierz jedynkowa - ::glTranslatef( moonposition.x, moonposition.y, moonposition.z ); - - float const size = interpolate( // TODO: expose distance/scale factor from the moon object - 0.0175f, - 0.015f, - clamp( Environment->m_moon.getAngle(), 0.f, 90.f ) / 90.f ); - // choose the moon appearance variant, based on current moon phase - // NOTE: implementation specific, 8 variants are laid out in 3x3 arrangement - // from new moon onwards, top left to right bottom (last spot is left for future use, if any) - auto const moonphase = Environment->m_moon.getPhase(); - float moonu, moonv; - if( moonphase < 1.84566f ) { moonv = 1.0f - 0.0f; moonu = 0.0f; } - else if( moonphase < 5.53699f ) { moonv = 1.0f - 0.0f; moonu = 0.333f; } - else if( moonphase < 9.22831f ) { moonv = 1.0f - 0.0f; moonu = 0.667f; } - else if( moonphase < 12.91963f ) { moonv = 1.0f - 0.333f; moonu = 0.0f; } - else if( moonphase < 16.61096f ) { moonv = 1.0f - 0.333f; moonu = 0.333f; } - else if( moonphase < 20.30228f ) { moonv = 1.0f - 0.333f; moonu = 0.667f; } - else if( moonphase < 23.99361f ) { moonv = 1.0f - 0.667f; moonu = 0.0f; } - else if( moonphase < 27.68493f ) { moonv = 1.0f - 0.667f; moonu = 0.333f; } - else { moonv = 1.0f - 0.0f; moonu = 0.0f; } - - ::glBegin( GL_TRIANGLE_STRIP ); - ::glMultiTexCoord2f( m_diffusetextureunit, moonu, moonv ); ::glVertex3f( -size, size, 0.0f ); - ::glMultiTexCoord2f( m_diffusetextureunit, moonu, moonv - 0.333f ); ::glVertex3f( -size, -size, 0.0f ); - ::glMultiTexCoord2f( m_diffusetextureunit, moonu + 0.333f, moonv ); ::glVertex3f( size, size, 0.0f ); - ::glMultiTexCoord2f( m_diffusetextureunit, moonu + 0.333f, moonv - 0.333f ); ::glVertex3f( size, -size, 0.0f ); - ::glEnd(); - - ::glPopMatrix(); - } - ::glPopAttrib(); + shader->bind(); // clouds if( Environment->m_clouds.mdCloud ) { // setup Disable_Lights(); - ::glEnable( GL_LIGHTING ); - ::glLightModelfv( - GL_LIGHT_MODEL_AMBIENT, - glm::value_ptr( - interpolate( Environment->m_skydome.GetAverageColor(), suncolor, duskfactor * 0.25f ) - * interpolate( 1.f, 0.35f, Global.Overcast / 2.f ) // overcast darkens the clouds - * 2.5f // arbitrary adjustment factor - ) ); + //m7t set cloud color // render Render( Environment->m_clouds.mdCloud, nullptr, 100.0 ); Render_Alpha( Environment->m_clouds.mdCloud, nullptr, 100.0 ); // post-render cleanup - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( colors::none ) ); - ::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update - ::glDisable( GL_LIGHTING ); } m_sunlight.apply_angle(); @@ -781,7 +608,6 @@ opengl_renderer::Render( world_environment *Environment ) { ::glPopMatrix(); ::glDepthMask( GL_TRUE ); ::glEnable( GL_DEPTH_TEST ); - ::glEnable( GL_LIGHTING ); return true; } @@ -1110,6 +936,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange } } // render + shader->copy_gl_mvp(); m_geometry.draw( data.geometry ); // debug data ++m_debugstats.shapes; @@ -1203,14 +1030,14 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { if( Dynamic->InteriorLightLevel > 0.0f ) { // crude way to light the cabin, until we have something more complete in place - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) ); + //m7t set cabin ambient } 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 ) ); + //m7t set ambient } } } @@ -1282,7 +1109,7 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) { } if( Dynamic->InteriorLightLevel > 0.f ) { // crude way to light the cabin, until we have something more complete in place - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) ); + } // render if( true == Alpha ) { @@ -1300,7 +1127,7 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) { } if( Dynamic->InteriorLightLevel > 0.0f ) { // reset the overall ambient - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) ); + //m7t set ambient } break; } @@ -1409,9 +1236,6 @@ opengl_renderer::Render( TSubModel *Submodel ) { break; } } #else - if( true == m_renderspecular ) { - ::glEnable( GL_NORMALIZE ); - } #endif // material configuration: // textures... @@ -1422,40 +1246,25 @@ opengl_renderer::Render( TSubModel *Submodel ) { // również 0 Bind_Material( Submodel->m_material ); } + + //m7t set material + // ...colors... - ::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) { // specular strength in legacy models is set uniformly to 150, 150, 150 so we scale it down for opaque elements - ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * m_sunlight.specular.a * m_specularopaquescalefactor ) ); - ::glEnable( GL_RESCALE_NORMAL ); + } // ...luminance auto const unitstate = m_unitstate; if( Global.fLuminance < Submodel->fLight ) { // zeby swiecilo na kolorowo - ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) ); - // disable shadows so they don't obstruct self-lit items -/* - setup_shadow_color( colors::white ); -*/ - switch_units( unitstate.diffuse, false, false ); } // main draw call + shader->copy_gl_mvp(); m_geometry.draw( Submodel->m_geometry ); - // post-draw reset - if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) { - ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) ); - } - if( Global.fLuminance < Submodel->fLight ) { - // restore default (lack of) brightness - ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) ); -/* - setup_shadow_color( m_shadowcolor ); -*/ - switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections ); - } + #ifdef EU07_USE_OPTIMIZED_NORMALIZATION switch( Submodel->m_normalizenormals ) { case TSubModel::normalize: { @@ -1466,9 +1275,6 @@ opengl_renderer::Render( TSubModel *Submodel ) { break; } } #else - if( true == m_renderspecular ) { - ::glDisable( GL_NORMALIZE ); - } #endif break; } @@ -1510,12 +1316,8 @@ opengl_renderer::Render( TSubModel *Submodel ) { if( lightlevel > 0.f ) { // material configuration: - ::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT ); Bind_Material( null_handle ); - ::glPointSize( std::max( 3.f, 5.f * distancefactor * anglefactor ) ); - ::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], lightlevel * anglefactor ); - ::glDisable( GL_LIGHTING ); ::glEnable( GL_BLEND ); ::glPushMatrix(); @@ -1528,6 +1330,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { switch_units( m_unitstate.diffuse, false, false ); // main draw call + shader->copy_gl_mvp(); m_geometry.draw( Submodel->m_geometry ); // post-draw reset @@ -1538,7 +1341,6 @@ opengl_renderer::Render( TSubModel *Submodel ) { switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections ); ::glPopMatrix(); - ::glPopAttrib(); } } break; @@ -1556,17 +1358,11 @@ opengl_renderer::Render( TSubModel *Submodel ) { case rendermode::reflections: { if( Global.fLuminance < Submodel->fLight ) { - // material configuration: - ::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT ); - Bind_Material( null_handle ); - ::glDisable( GL_LIGHTING ); // main draw call + shader->copy_gl_mvp(); m_geometry.draw( Submodel->m_geometry, gfx::color_streams ); - - // post-draw reset - ::glPopAttrib(); } break; } @@ -1605,6 +1401,8 @@ opengl_renderer::Render( TTrack *Track ) { ++m_debugstats.paths; ++m_debugstats.drawcalls; + shader->copy_gl_mvp(); + switch( m_renderpass.draw_mode ) { case rendermode::color: case rendermode::reflections: { @@ -1639,7 +1437,6 @@ opengl_renderer::Render( TTrack *Track ) { void opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last ) { - ::glColor3fv( glm::value_ptr( colors::white ) ); // setup switch( m_renderpass.draw_mode ) { case rendermode::shadows: { @@ -1651,6 +1448,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, } } + shader->copy_gl_mvp(); + // first pass, material 1 for( auto first { First }; first != Last; ++first ) { @@ -1747,13 +1546,6 @@ opengl_renderer::Render( TMemCell *Memcell ) { switch( m_renderpass.draw_mode ) { case rendermode::color: { - ::glPushAttrib( GL_ENABLE_BIT ); - ::glDisable( GL_TEXTURE_2D ); - ::glColor3f( 0.36f, 0.75f, 0.35f ); - - ::gluSphere( m_quadric, 0.35, 4, 2 ); - - ::glPopAttrib(); break; } case rendermode::shadows: @@ -1833,8 +1625,6 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque // third pass draws the wires; // wires use section vbos, but for the time being we want to draw them at the very end { - ::glDisable( GL_LIGHTING ); // linie nie powinny świecić - auto first{ First }; while( first != Last ) { @@ -1864,8 +1654,6 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque ++first; } - - ::glEnable( GL_LIGHTING ); } } @@ -1944,12 +1732,8 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) { 0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f, 1.f, 1.5f ) ); // McZapkie-261102: kolor zalezy od materialu i zasniedzenia - ::glColor4fv( - glm::value_ptr( - glm::vec4{ - Traction->wire_color() /* * ( DebugModeFlag ? 1.f : clamp( m_sunandviewangle, 0.25f, 1.f ) ) */, - linealpha } ) ); // render + shader->copy_gl_mvp(); m_geometry.draw( Traction->m_geometry ); // debug data ++m_debugstats.traction; @@ -1986,12 +1770,8 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) { clamp( 0.5f * linealpha + data.line_width * data.area.radius / 1000.f, 1.f, 8.f ) ); - ::glColor4fv( - glm::value_ptr( - glm::vec4{ - glm::vec3{ data.lighting.diffuse * m_sunlight.ambient }, // w zaleznosci od koloru swiatla - std::min( 1.f, linealpha ) } ) ); // render + shader->copy_gl_mvp(); m_geometry.draw( data.geometry ); ++m_debugstats.lines; ++m_debugstats.drawcalls; @@ -2034,15 +1814,10 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { if( Dynamic->InteriorLightLevel > 0.0f ) { // crude way to light the cabin, until we have something more complete in place - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) ); + // m7t } 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 ) ); - } } } @@ -2156,9 +1931,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { break; } } #else - if( true == m_renderspecular ) { - ::glEnable( GL_NORMALIZE ); - } #endif // material configuration: // textures... @@ -2170,37 +1942,16 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { Bind_Material( Submodel->m_material ); } // ...colors... - ::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub - if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) { - ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * m_sunlight.specular.a * m_speculartranslucentscalefactor ) ); - } + // m7t set material // ...luminance auto const unitstate = m_unitstate; if( Global.fLuminance < Submodel->fLight ) { - // zeby swiecilo na kolorowo - ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) ); - // disable shadows so they don't obstruct self-lit items -/* - setup_shadow_color( colors::white ); -*/ - switch_units( unitstate.diffuse, false, false ); } // main draw call + shader->copy_gl_mvp(); m_geometry.draw( Submodel->m_geometry ); - // post-draw reset - if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) { - ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) ); - } - if( Global.fLuminance < Submodel->fLight ) { - // restore default (lack of) brightness - ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) ); -/* - setup_shadow_color( m_shadowcolor ); -*/ - switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections ); - } #ifdef EU07_USE_OPTIMIZED_NORMALIZATION switch( Submodel->m_normalizenormals ) { case TSubModel::normalize: { @@ -2211,26 +1962,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { break; } } #else - if( true == m_renderspecular ) { - ::glDisable( GL_NORMALIZE ); - } #endif break; } case rendermode::cabshadows: { - // scenery picking and shadow both use enforced colour and no frills - // material configuration: - // textures... - if( Submodel->m_material < 0 ) { // zmienialne skóry - Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] ); - } - else { - // również 0 - Bind_Material( Submodel->m_material ); - } - // main draw call - m_geometry.draw( Submodel->m_geometry ); - // post-draw reset break; } default: { @@ -2266,12 +2001,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { glarelevel = clamp( glarelevel - static_cast(Global.fLuminance), 0.f, 1.f ); if( glarelevel > 0.0f ) { - // setup - ::glPushAttrib( GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT ); - Bind_Texture( m_glaretexture ); - ::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel ); - ::glDisable( GL_LIGHTING ); ::glDepthMask( GL_FALSE ); ::glBlendFunc( GL_SRC_ALPHA, GL_ONE ); @@ -2280,30 +2010,14 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { ::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian ::glRotated( std::atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt // disable shadows so they don't obstruct self-lit items -/* - setup_shadow_color( colors::white ); -*/ auto const unitstate = m_unitstate; switch_units( unitstate.diffuse, false, false ); // main draw call + shader->copy_gl_mvp(); m_geometry.draw( m_billboardgeometry ); -/* - // NOTE: we could do simply... - vec3 vertexPosition_worldspace = - particleCenter_wordspace - + CameraRight_worldspace * squareVertices.x * BillboardSize.x - + 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 -*/ - // post-render cleanup -/* - setup_shadow_color( m_shadowcolor ); -*/ - switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections ); ::glPopMatrix(); - ::glPopAttrib(); } } } @@ -2507,8 +2221,7 @@ opengl_renderer::Update_Lights( light_array &Lights ) { glm::max( glm::vec3{ colors::none }, scenelight.color * glm::vec3{ scenelight.intensity } - glm::vec3{ luminance } ), renderlight->ambient[ 3 ] }; - ::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, static_cast( (0.25 * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25 : 1.0) ) ); - ::glEnable( renderlight->id ); + //m7t fill light renderlight->apply_intensity(); renderlight->apply_angle(); @@ -2518,7 +2231,6 @@ opengl_renderer::Update_Lights( light_array &Lights ) { while( renderlight != m_lights.end() ) { // if we went through all scene lights and there's still opengl lights remaining, kill these - ::glDisable( renderlight->id ); ++renderlight; } } @@ -2528,7 +2240,6 @@ opengl_renderer::Disable_Lights() { for( size_t idx = 0; idx < m_lights.size() + 1; ++idx ) { - ::glDisable( GL_LIGHT0 + (int)idx ); } } @@ -2542,12 +2253,20 @@ opengl_renderer::Init_caps() { + " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) ) + " OpenGL Version: " + oglversion ); - if( !GLEW_VERSION_1_5 ) { - ErrorLog( "Requires openGL >= 1.5" ); + if( !GLEW_VERSION_3_3 ) { + ErrorLog( "Requires openGL >= 3.3" ); return false; } - WriteLog( "Supported extensions: " + std::string((char *)glGetString( GL_EXTENSIONS )) ); + GLint extCount = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &extCount); + + WriteLog("Supported extensions: "); + for (int i = 0; i < extCount; i++) + { + const char *ext = (const char *)glGetStringi(GL_EXTENSIONS, i); + WriteLog(ext); + } if( GLEW_EXT_framebuffer_object ) { m_framebuffersupport = true; diff --git a/renderer.h b/renderer.h index 7737a6b9..020f46b8 100644 --- a/renderer.h +++ b/renderer.h @@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/. #include "MemCell.h" #include "scene.h" #include "light.h" +#include "gl/shader_mvp.h" #define EU07_USE_PICKING_FRAMEBUFFER //#define EU07_USE_DEBUG_SHADOWMAP @@ -395,6 +396,8 @@ private: #endif GLuint m_gltimequery = 0; GLuint64 m_gllasttime = 0; + + std::unique_ptr shader; }; extern opengl_renderer GfxRenderer; diff --git a/shader.cpp b/shader.cpp deleted file mode 100644 index 7fd1e513..00000000 --- a/shader.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "stdafx.h" -#include "shader.h" -#include "Float3d.h" -#include "Logs.h" - -#include -#include -#include - -inline bool strcend(std::string const &value, std::string const &ending) -{ - if (ending.size() > value.size()) - return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} - -gl_shader::gl_shader(std::string filename) -{ - WriteLog("loading shader " + filename + " .."); - - std::stringstream stream; - std::ifstream f; - f.exceptions(std::ifstream::badbit); - - f.open("shaders/" + filename); - stream << f.rdbuf(); - f.close(); - - std::string str = stream.str(); - const GLchar *cstr = str.c_str(); - - if (!cstr[0]) - throw std::runtime_error("cannot read shader " + filename); - - GLuint type; - if (strcend(filename, ".vert")) - type = GL_VERTEX_SHADER; - else if (strcend(filename, ".frag")) - type = GL_FRAGMENT_SHADER; - else - throw std::runtime_error("unknown shader " + filename); - - id = glCreateShader(type); - glShaderSource(id, 1, &cstr, 0); - glCompileShader(id); - - GLint status; - glGetShaderiv(id, GL_COMPILE_STATUS, &status); - if (!status) - { - GLchar info[512]; - glGetShaderInfoLog(id, 512, 0, info); - throw std::runtime_error("failed to compile " + filename + ": " + std::string(info)); - } - - WriteLog("done."); -} - -gl_shader::operator GLuint() -{ - return id; -} - -gl_shader::~gl_shader() -{ - //glDeleteShader(*this); //m7todo: something is broken -} - -gl_program::gl_program(std::vector shaders) -{ - id = glCreateProgram(); - for (auto s : shaders) - glAttachShader(id, s); - glLinkProgram(id); - - GLint status; - glGetProgramiv(id, GL_LINK_STATUS, &status); - if (!status) - { - GLchar info[512]; - glGetProgramInfoLog(id, 512, 0, info); - throw std::runtime_error("failed to link program: " + std::string(info)); - } -} - -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; -} - -gl_program::~gl_program() -{ - //glDeleteProgram(*this); //m7todo: something is broken -} - -gl_program_mvp::gl_program_mvp(std::vector 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() -{ - set_mv(OpenGLMatrices.data(GL_MODELVIEW)); - set_p(OpenGLMatrices.data(GL_PROJECTION)); -} - -void gl_program_mvp::set_mv(const glm::mat4 &m) -{ - if (m != mv) - { - mv = m; - mv_dirty = true; - } -} - -void gl_program_mvp::set_p(const glm::mat4 &m) -{ - if (m != p) - { - p = m; - p_dirty = true; - } -} - -void gl_program_mvp::update() -{ - if (current_program != this) - return; - - if (mv_dirty) - { - if (mvn_uniform != -1) - { - glm::mat3 mvn = glm::mat3(glm::transpose(glm::inverse(mv))); - glUniformMatrix3fv(mvn_uniform, 1, GL_FALSE, glm::value_ptr(mvn)); - } - glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, glm::value_ptr(mv)); - mv_dirty = false; - } - - if (p_dirty) - { - glUniformMatrix4fv(p_uniform, 1, GL_FALSE, glm::value_ptr(p)); - mv_dirty = false; - } -} - -gl_program_light::gl_program_light(std::vector v) : gl_program_mvp(v) -{ - bind(); - - glUniform1i(glGetUniformLocation(id, "tex"), 0); - glUniform1i(glGetUniformLocation(id, "shadowmap"), 1); - lightview_uniform = glGetUniformLocation(id, "lightview"); - emission_uniform = glGetUniformLocation(id, "emission"); - specular_uniform = glGetUniformLocation(id, "specular"); - color_uniform = glGetUniformLocation(id, "color"); -} - -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) -{ - if (current_program != this) - return; - - glUniformMatrix4fv(lightview_uniform, 1, GL_FALSE, glm::value_ptr(lightview)); -} - -void gl_program_light::set_material(const material_s &mat) -{ - if (current_program != this) - return; - - if (std::memcmp(&material, &mat, sizeof(material_s))) - { - material_dirty = true; - material = mat; - } -} - -void gl_program_light::update() -{ - if (current_program != this) - return; - - gl_program_mvp::update(); - - if (material_dirty) - { - glUniform1f(specular_uniform, material.specular); - glUniform3fv(emission_uniform, 1, glm::value_ptr(material.emission)); - if (color_uniform != -1) - glUniform4fv(color_uniform, 1, glm::value_ptr(material.color)); - - material_dirty = false; - } -} - -template -GLuint gl_ubo::binding_point_cnt = 0; - -template -void gl_ubo::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 -void gl_ubo::update() -{ - glBindBuffer(GL_UNIFORM_BUFFER, buffer_id); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), &data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); -} - -template -gl_ubo::~gl_ubo() -{ - if (buffer_id) - glDeleteBuffers(1, &buffer_id); -} - -template class gl_ubo; diff --git a/shader.h b/shader.h deleted file mode 100644 index e2540329..00000000 --- a/shader.h +++ /dev/null @@ -1,148 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once -#include "Float3d.h" - -class gl_shader -{ - GLuint id = 0; -public: - gl_shader(); - gl_shader(std::string); - ~gl_shader(); - - operator GLuint(); -}; - -class gl_program -{ -protected: - GLuint id = 0; - -public: - gl_program() = default; - gl_program(std::vector); - ~gl_program(); - - 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; - GLint mvn_uniform; - GLuint p_uniform; - - glm::mat4 mv, p; - bool mv_dirty, p_dirty; - -public: - gl_program_mvp() = default; - gl_program_mvp(std::vector); - - void set_mv(const glm::mat4 &); - void set_p(const glm::mat4 &); - void copy_gl_mvp(); - virtual void update(); -}; - -// layout std140 -// structs must match with GLSL -// weird order to minimize padding - -#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, "bad size of ubo structs"); - -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, "bad size of ubo structs"); - -#pragma pack(pop) - -template -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 -{ - GLuint lightview_uniform; - GLuint specular_uniform; - GLuint emission_uniform; - GLuint color_uniform; - - struct material_s - { - float specular; - glm::vec3 emission; - glm::vec4 color; - } material; - - bool material_dirty; - -public: - gl_program_light() = default; - gl_program_light(std::vector); - - void set_lightview(const glm::mat4 &lightview); - void set_material(const material_s &mat); - void bind_ubodata(GLuint point); - void update(); -}; diff --git a/shaders/blinnphong.frag b/shaders/blinnphong.frag deleted file mode 100644 index 86352d90..00000000 --- a/shaders/blinnphong.frag +++ /dev/null @@ -1,141 +0,0 @@ -#version 330 - -const uint LIGHT_SPOT = 0U; -const uint LIGHT_POINT = 1U; -const uint LIGHT_DIR = 2U; - -struct light_s -{ - vec3 pos; - uint type; - - vec3 dir; - float in_cutoff; - - vec3 color; - float out_cutoff; - - float linear; - float quadratic; -}; - -in vec3 f_normal; -in vec2 f_coord; -in vec3 f_pos; -in vec4 f_light_pos; - -out vec4 color; - -uniform sampler2D tex; -uniform sampler2DShadow shadowmap; - -uniform vec3 emission; -uniform float specular; - -layout(std140) uniform ubodata -{ - vec3 ambient; - float fog_density; - - vec3 fog_color; - uint lights_count; - - light_s lights[8]; -}; - -float calc_shadow() -{ - vec3 coords = f_light_pos.xyz; - float bias = clamp(0.0025*tan(acos(clamp(dot(f_normal, -lights[0].dir), 0.0, 1.0))), 0, 0.01); - - //sampler PCF - //float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias)); - - //sampler PCF + PCF - float shadow = 0.0; - vec2 texel = 1.0 / textureSize(shadowmap, 0); - for (float y = -1.5; y <= 1.5; y += 1.0) - for (float x = -1.5; x <= 1.5; x += 1.0) - shadow += texture(shadowmap, coords.xyz + vec3(vec2(x, y) * texel, -bias)); - shadow /= 16.0; - - return shadow; -} - -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() -{ - float shadow = calc_shadow(); - 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); - - if (i == 0U) - part *= shadow; - result += light.color * part; - } - - vec4 tex_color = texture(tex, f_coord); - vec3 c = apply_fog(result * tex_color.xyz); - //color = vec4(c / (c + vec3(1.0)), tex_color.w); - color = vec4(c, tex_color.w); -} diff --git a/shaders/color.frag b/shaders/color.frag index de5e4706..fc09746a 100644 --- a/shaders/color.frag +++ b/shaders/color.frag @@ -2,9 +2,7 @@ in vec3 f_color; -out vec4 color; - void main() { - color = vec4(f_color, 1.0f); + gl_FragColor = vec4(f_color, 1.0f); } diff --git a/shaders/empty.frag b/shaders/empty.frag deleted file mode 100644 index 563d9412..00000000 --- a/shaders/empty.frag +++ /dev/null @@ -1,10 +0,0 @@ -#version 330 - -in vec2 f_coord; - -uniform sampler2D tex; - -void main() -{ - gl_FragDepth = gl_FragCoord.z + (1.0 - texture(tex, f_coord).w); -} \ No newline at end of file diff --git a/shaders/lighting.vert b/shaders/lighting.vert deleted file mode 100644 index 4e3b3cae..00000000 --- a/shaders/lighting.vert +++ /dev/null @@ -1,24 +0,0 @@ -#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; -out vec4 f_light_pos; - -uniform mat4 lightview; -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)); - f_light_pos = lightview * vec4(f_pos, 1.0f); -} \ No newline at end of file diff --git a/shaders/notex-blinnphong.frag b/shaders/notex-blinnphong.frag deleted file mode 100644 index 4535e0f4..00000000 --- a/shaders/notex-blinnphong.frag +++ /dev/null @@ -1,137 +0,0 @@ -#version 330 - -const uint LIGHT_SPOT = 0U; -const uint LIGHT_POINT = 1U; -const uint LIGHT_DIR = 2U; - -struct light_s -{ - vec3 pos; - uint type; - - vec3 dir; - float in_cutoff; - - vec3 color; - float out_cutoff; - - float linear; - float quadratic; -}; - -in vec3 f_normal; -in vec3 f_pos; -in vec4 f_light_pos; - -out vec4 o_color; - -uniform sampler2DShadow shadowmap; - -uniform vec4 color; -uniform vec3 emission; -uniform float specular; - -layout(std140) uniform ubodata -{ - vec3 ambient; - float fog_density; - - vec3 fog_color; - uint lights_count; - - light_s lights[8]; -}; - -float calc_shadow() -{ - vec3 coords = f_light_pos.xyz; - float bias = clamp(0.0025*tan(acos(clamp(dot(f_normal, -lights[0].dir), 0.0, 1.0))), 0, 0.01); - - //sampler PCF - //float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias)); - - //sampler PCF + PCF - float shadow = 0.0; - vec2 texel = 1.0 / textureSize(shadowmap, 0); - for (float y = -1.5; y <= 1.5; y += 1.0) - for (float x = -1.5; x <= 1.5; x += 1.0) - shadow += texture(shadowmap, coords.xyz + vec3(vec2(x, y) * texel, -bias)); - shadow /= 16.0; - - return shadow; -} - -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() -{ - float shadow = calc_shadow(); - 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); - - if (i == 0U) - part *= shadow; - result += light.color * part; - } - - o_color = vec4(apply_fog(result * color.xyz), color.w); -} diff --git a/shaders/notex-lighting.vert b/shaders/notex-lighting.vert deleted file mode 100644 index f0f97124..00000000 --- a/shaders/notex-lighting.vert +++ /dev/null @@ -1,21 +0,0 @@ -#version 330 - -layout (location = 0) in vec3 v_vert; -layout (location = 1) in vec3 v_normal; - -out vec3 f_normal; -out vec3 f_pos; -out vec4 f_light_pos; - -uniform mat4 lightview; -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_pos = vec3(modelview * vec4(v_vert, 1.0f)); - f_light_pos = lightview * vec4(f_pos, 1.0f); -} \ No newline at end of file diff --git a/shaders/shadowmap.vert b/shaders/shadowmap.vert deleted file mode 100644 index 48aea27f..00000000 --- a/shaders/shadowmap.vert +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -layout (location = 0) in vec3 v_vert; -layout (location = 2) in vec2 v_coord; - -out vec2 f_coord; - -uniform mat4 modelview; -uniform mat4 projection; - -void main() -{ - gl_Position = (projection * modelview) * vec4(v_vert, 1.0f); - f_coord = v_coord; -} \ No newline at end of file diff --git a/shaders/vbocolor.vert b/shaders/vbocolor.vert index aaf23e6b..e1f698db 100644 --- a/shaders/vbocolor.vert +++ b/shaders/vbocolor.vert @@ -1,7 +1,7 @@ #version 330 -layout (location = 0) in vec3 v_vert; -layout (location = 1) in vec3 v_color; +in vec3 v_vert; +in vec3 v_color; out vec3 f_color; @@ -12,4 +12,4 @@ void main() { gl_Position = projection * modelview * vec4(v_vert, 1.0f); f_color = v_color; -} \ No newline at end of file +} diff --git a/skydome.cpp b/skydome.cpp index a781dfe6..ba1d1034 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -117,6 +117,14 @@ void CSkyDome::Update( glm::vec3 const &Sun ) { // render skydome to screen void CSkyDome::Render() { + if (!m_shader) + { + gl::shader vert("shaders/vbocolor.vert"); + gl::shader frag("shaders/color.frag"); + m_shader = std::make_unique(std::vector>({vert, frag})); + m_shader->init(); + } + if( m_vertexbuffer == -1 ) { // build the buffers ::glGenBuffers( 1, &m_vertexbuffer ); @@ -132,21 +140,23 @@ void CSkyDome::Render() { ::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW ); // NOTE: vertex and index source data is superfluous past this point, but, eh } - // begin - ::glEnableClientState( GL_VERTEX_ARRAY ); - ::glEnableClientState( GL_COLOR_ARRAY ); - // positions - ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); - ::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast( 0 ) ); - // colours - ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); - ::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast( 0 ) ); - // indices - ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); + + m_shader->bind(); + m_shader->copy_gl_mvp(); + + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, m_coloursbuffer); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0); + glEnableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer); ::glDrawElements( GL_TRIANGLES, static_cast( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast( 0 ) ); - // cleanup - ::glDisableClientState( GL_COLOR_ARRAY ); - ::glDisableClientState( GL_VERTEX_ARRAY ); + + glUseProgram(0); } bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) { diff --git a/skydome.h b/skydome.h index 9b867499..6214df4d 100644 --- a/skydome.h +++ b/skydome.h @@ -1,5 +1,8 @@ #pragma once +#include "gl/shader_mvp.h" +#include + // sky gradient based on "A practical analytic model for daylight" // by A. J. Preetham Peter Shirley Brian Smits (University of Utah) @@ -60,4 +63,6 @@ private: float GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ); float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ); float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ); + + std::unique_ptr m_shader; }; diff --git a/sun.cpp b/sun.cpp index d41a9d00..8b4f649d 100644 --- a/sun.cpp +++ b/sun.cpp @@ -50,18 +50,7 @@ cSun::update() { void cSun::render() { - ::glColor4f( 255.f / 255.f, 242.f / 255.f, 231.f / 255.f, 1.f ); - // debug line to locate the sun easier - auto const position { m_position * 2000.f }; - ::glBegin( GL_LINES ); - ::glVertex3fv( glm::value_ptr( position ) ); - ::glVertex3f( position.x, 0.f, position.z ); - ::glEnd(); - ::glPushMatrix(); - ::glTranslatef( position.x, position.y, position.z ); - // radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio - ::gluSphere( sunsphere, m_body.distance * 9.359157, 12, 12 ); - ::glPopMatrix(); + //m7t } /* glm::vec3 diff --git a/uilayer.cpp b/uilayer.cpp index 7ffffc43..fc7c26bf 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -974,31 +974,19 @@ ui_layer::render() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - - glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT ); // blendfunc included since 3rd party gui doesn't play nice - glDisable( GL_LIGHTING ); glDisable( GL_DEPTH_TEST ); - glDisable( GL_ALPHA_TEST ); - glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); - ::glColor4fv( glm::value_ptr( colors::white ) ); - // render code here render_background(); render_texture(); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_TEXTURE_CUBE_MAP ); - render_progress(); glDisable( GL_BLEND ); render_panels(); render_tooltip(); - - glPopAttrib(); } void @@ -1064,6 +1052,8 @@ ui_layer::render_progress() { Global.iWindowHeight / 768.f * screenratio / ( 4.0f / 3.0f ) ); float const height = 768.0f * heightratio; + // m7t: port to core + /* ::glColor4f( 216.0f / 255.0f, 216.0f / 255.0f, 216.0f / 255.0f, 1.0f ); auto const charsize = 9.0f; auto const textwidth = m_progresstext.size() * charsize; @@ -1072,6 +1062,7 @@ ui_layer::render_progress() { ( 0.5f * ( Global.iWindowWidth - width ) + origin.x * heightratio ) + ( ( size.x * heightratio - textwidth ) * 0.5f * heightratio ), ( 0.5f * ( Global.iWindowHeight - height ) + origin.y * heightratio ) + ( charsize ) + ( ( size.y * heightratio - textheight ) * 0.5f * heightratio ) ); print( m_progresstext ); + */ } } @@ -1089,12 +1080,14 @@ ui_layer::render_panels() { int lineidx = 0; for( auto const &line : panel->text_lines ) { - + /* ::glColor4fv( glm::value_ptr( line.color ) ); ::glRasterPos2f( 0.5f * ( Global.iWindowWidth - width ) + panel->origin_x * height, panel->origin_y * height + 20.f * lineidx ); print( line.data ); + */ + // m7t: port to core ++lineidx; } } @@ -1110,9 +1103,12 @@ ui_layer::render_tooltip() { glm::dvec2 mousepos; glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y ); + // m7t: port to core + /* ::glColor4fv( glm::value_ptr( colors::white ) ); ::glRasterPos2f( mousepos.x + 20.0f, mousepos.y + 25.0f ); print( m_tooltip ); + */ } void @@ -1141,7 +1137,6 @@ void ui_layer::render_texture() { if( m_texture != 0 ) { - ::glColor4fv( glm::value_ptr( colors::white ) ); GfxRenderer.Bind_Texture( null_handle ); ::glBindTexture( GL_TEXTURE_2D, m_texture ); @@ -1149,6 +1144,8 @@ ui_layer::render_texture() { auto const size = 512.f; auto const offset = 64.f; + //m7t + /* glBegin( GL_TRIANGLE_STRIP ); glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( offset, Global.iWindowHeight - offset - size ); @@ -1157,6 +1154,7 @@ ui_layer::render_texture() { glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( offset + size, Global.iWindowHeight - offset ); glEnd(); + */ ::glBindTexture( GL_TEXTURE_2D, 0 ); } @@ -1165,6 +1163,8 @@ ui_layer::render_texture() { void ui_layer::print( std::string const &Text ) { + //m7t + /* if( (false == Global.DLFont) || (true == Text.empty()) ) return; @@ -1183,11 +1183,13 @@ ui_layer::print( std::string const &Text ) ::glPopAttrib(); } + */ } void ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) { - + //m7t +/* float const screenratio = static_cast( Global.iWindowWidth ) / Global.iWindowHeight; float const width = ( screenratio >= ( 4.f / 3.f ) ? @@ -1209,4 +1211,5 @@ ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) { glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( 0.5f * ( Global.iWindowWidth - width ) + Coordinates.z * heightratio, 0.5f * ( Global.iWindowHeight - height ) + Coordinates.w * heightratio ); glEnd(); +*/ }