mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 13:59:19 +02:00
further pruning of legacy render code, now runs on opengl 3.3 core
profile
This commit is contained in:
@@ -6,8 +6,8 @@ set(DEPS_DIR ${DEPS_DIR} "${CMAKE_SOURCE_DIR}/ref")
|
|||||||
project("eu07")
|
project("eu07")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
include_directories("." "Console" "McZapkie")
|
include_directories("." "Console" "McZapkie" "gl")
|
||||||
file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h")
|
file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h" "gl/*.h")
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
"Texture.cpp"
|
"Texture.cpp"
|
||||||
@@ -54,7 +54,6 @@ set(SOURCES
|
|||||||
"skydome.cpp"
|
"skydome.cpp"
|
||||||
"sound.cpp"
|
"sound.cpp"
|
||||||
"Spring.cpp"
|
"Spring.cpp"
|
||||||
"shader.cpp"
|
|
||||||
"frustum.cpp"
|
"frustum.cpp"
|
||||||
"uilayer.cpp"
|
"uilayer.cpp"
|
||||||
"openglmatrixstack.cpp"
|
"openglmatrixstack.cpp"
|
||||||
@@ -81,6 +80,8 @@ set(SOURCES
|
|||||||
"light.cpp"
|
"light.cpp"
|
||||||
"uitranscripts.cpp"
|
"uitranscripts.cpp"
|
||||||
"station.cpp"
|
"station.cpp"
|
||||||
|
"gl/shader.cpp"
|
||||||
|
"gl/shader_mvp.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set (PREFIX "")
|
set (PREFIX "")
|
||||||
|
|||||||
4
EU07.cpp
4
EU07.cpp
@@ -300,6 +300,10 @@ int main(int argc, char *argv[])
|
|||||||
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
|
||||||
const GLFWvidmode *vmode = glfwGetVideoMode(monitor);
|
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_RED_BITS, vmode->redBits);
|
||||||
glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
|
glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
|
||||||
glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
|
glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
|
||||||
|
|||||||
5
Logs.cpp
5
Logs.cpp
@@ -82,25 +82,24 @@ void WriteLog( const char *str, logtype const Type ) {
|
|||||||
output.open( filename, std::ios::trunc );
|
output.open( filename, std::ios::trunc );
|
||||||
}
|
}
|
||||||
output << str << "\n";
|
output << str << "\n";
|
||||||
output.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_log->text_lines.emplace_back(std::string(str), Global.UITextColor);
|
ui_log->text_lines.emplace_back(std::string(str), Global.UITextColor);
|
||||||
if (ui_log->text_lines.size() > 20)
|
if (ui_log->text_lines.size() > 20)
|
||||||
ui_log->text_lines.pop_front();
|
ui_log->text_lines.pop_front();
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if( Global.iWriteLogEnabled & 2 ) {
|
if( Global.iWriteLogEnabled & 2 ) {
|
||||||
|
#ifdef _WIN32
|
||||||
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||||
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY );
|
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY );
|
||||||
DWORD wr = 0;
|
DWORD wr = 0;
|
||||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL );
|
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL );
|
||||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL );
|
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL );
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
printf("%s\n", str);
|
printf("%s\n", str);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ra: bezwarunkowa rejestracja poważnych błędów
|
// Ra: bezwarunkowa rejestracja poważnych błędów
|
||||||
void ErrorLog( const char *str, logtype const Type ) {
|
void ErrorLog( const char *str, logtype const Type ) {
|
||||||
|
|||||||
@@ -276,10 +276,8 @@ void TPythonScreenRenderer::updateTexture()
|
|||||||
*/
|
*/
|
||||||
GfxRenderer.Bind_Material(_textureId);
|
GfxRenderer.Bind_Material(_textureId);
|
||||||
// setup texture parameters
|
// 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_MAG_FILTER, GL_LINEAR );
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 );
|
|
||||||
// build texture
|
// build texture
|
||||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData );
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData );
|
||||||
|
|
||||||
|
|||||||
@@ -531,6 +531,8 @@ void TSegment::Render()
|
|||||||
Math3D::vector3 pt;
|
Math3D::vector3 pt;
|
||||||
GfxRenderer.Bind_Material( null_handle );
|
GfxRenderer.Bind_Material( null_handle );
|
||||||
|
|
||||||
|
//m7t
|
||||||
|
/*
|
||||||
if (bCurve)
|
if (bCurve)
|
||||||
{
|
{
|
||||||
glColor3f(0, 0, 1.0f);
|
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);
|
glVertex3f(Point2.x + CPointIn.x, Point2.y + CPointIn.y, Point2.z + CPointIn.z);
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
18
Texture.cpp
18
Texture.cpp
@@ -613,10 +613,6 @@ opengl_texture::create() {
|
|||||||
|
|
||||||
set_filtering();
|
set_filtering();
|
||||||
|
|
||||||
if( data_mapcount == 1 ) {
|
|
||||||
// fill missing mipmaps if needed
|
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
|
|
||||||
}
|
|
||||||
// upload texture data
|
// upload texture data
|
||||||
int dataoffset = 0,
|
int dataoffset = 0,
|
||||||
datasize = 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 )
|
if( ( true == Global.ResourceMove )
|
||||||
|| ( false == Global.ResourceSweep ) ) {
|
|| ( false == Global.ResourceSweep ) ) {
|
||||||
// if garbage collection is disabled we don't expect having to upload the texture more than once
|
// 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; }
|
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
|
void
|
||||||
|
|||||||
32
gl/object.h
Normal file
32
gl/object.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
105
gl/shader.cpp
Normal file
105
gl/shader.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#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<std::reference_wrapper<const gl::shader>> 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);
|
||||||
|
}
|
||||||
32
gl/shader.h
Normal file
32
gl/shader.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#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<std::reference_wrapper<const gl::shader>>);
|
||||||
|
~program();
|
||||||
|
|
||||||
|
void bind();
|
||||||
|
|
||||||
|
void attach(const shader &);
|
||||||
|
void link();
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
|
};
|
||||||
|
}
|
||||||
30
gl/shader_mvp.cpp
Normal file
30
gl/shader_mvp.cpp
Normal file
@@ -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));
|
||||||
|
}
|
||||||
22
gl/shader_mvp.h
Normal file
22
gl/shader_mvp.h
Normal file
@@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
12
moon.cpp
12
moon.cpp
@@ -49,17 +49,7 @@ cMoon::update() {
|
|||||||
void
|
void
|
||||||
cMoon::render() {
|
cMoon::render() {
|
||||||
|
|
||||||
::glColor4f( 225.f / 255.f, 225.f / 255.f, 255.f / 255.f, 1.f );
|
//m7t
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3
|
glm::vec3
|
||||||
|
|||||||
@@ -255,40 +255,31 @@ void
|
|||||||
opengl_vbogeometrybank::bind_streams( gfx::stream_units const &Units, unsigned int const Streams ) {
|
opengl_vbogeometrybank::bind_streams( gfx::stream_units const &Units, unsigned int const Streams ) {
|
||||||
|
|
||||||
if( Streams & gfx::stream::position ) {
|
if( Streams & gfx::stream::position ) {
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast<char *>( nullptr ) );
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)0);
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
glEnableVertexAttribArray(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableVertexAttribArray(0);
|
||||||
}
|
}
|
||||||
// NOTE: normal and color streams share the data, making them effectively mutually exclusive
|
// NOTE: normal and color streams share the data, making them effectively mutually exclusive
|
||||||
if( Streams & gfx::stream::normal ) {
|
if( Streams & gfx::stream::normal ) {
|
||||||
::glNormalPointer( GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast<char *>( nullptr ) + sizeof( float ) * 3 );
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(3 * sizeof(GL_FLOAT)));
|
||||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
glEnableVertexAttribArray(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
glDisableVertexAttribArray(1);
|
||||||
}
|
}
|
||||||
if( Streams & gfx::stream::color ) {
|
if( Streams & gfx::stream::color ) {
|
||||||
::glColorPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast<char *>( nullptr ) + sizeof( float ) * 3 );
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(3 * sizeof(GL_FLOAT)));
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
glEnableVertexAttribArray(1);
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
|
||||||
}
|
}
|
||||||
if( Streams & gfx::stream::texture ) {
|
if( Streams & gfx::stream::texture ) {
|
||||||
for( auto unit : Units.texture ) {
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(6 * sizeof(GL_FLOAT)));
|
||||||
::glClientActiveTexture( unit );
|
glEnableVertexAttribArray(2);
|
||||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( gfx::basic_vertex ), static_cast<char *>( nullptr ) + 24 );
|
|
||||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
m_activetexturearrays = Units.texture;
|
m_activetexturearrays = Units.texture;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( auto unit : Units.texture ) {
|
glDisableVertexAttribArray(2);
|
||||||
::glClientActiveTexture( unit );
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
m_activetexturearrays.clear(); // NOTE: we're simplifying here, since we always toggle the same texture coord sets
|
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
|
void
|
||||||
opengl_vbogeometrybank::release_streams() {
|
opengl_vbogeometrybank::release_streams() {
|
||||||
|
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
glDisableVertexAttribArray(0);
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
glDisableVertexAttribArray(1);
|
||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
glDisableVertexAttribArray(2);
|
||||||
for( auto unit : m_activetexturearrays ) {
|
|
||||||
::glClientActiveTexture( unit );
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_activestreams = gfx::stream::none;
|
m_activestreams = gfx::stream::none;
|
||||||
m_activetexturearrays.clear();
|
m_activetexturearrays.clear();
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ private:
|
|||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
void
|
void
|
||||||
upload() { ::glLoadMatrixf( glm::value_ptr( m_stack.top() ) ); }
|
upload() { }
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
mat4_stack m_stack;
|
mat4_stack m_stack;
|
||||||
@@ -109,7 +109,7 @@ public:
|
|||||||
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
||||||
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
|
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
|
||||||
default: { break; } }
|
default: { break; } }
|
||||||
::glMatrixMode( Mode ); }
|
}
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
data( GLuint const Mode = -1 ) const {
|
data( GLuint const Mode = -1 ) const {
|
||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
|
|||||||
457
renderer.cpp
457
renderer.cpp
@@ -27,37 +27,17 @@ int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental
|
|||||||
|
|
||||||
void
|
void
|
||||||
opengl_light::apply_intensity( float const Factor ) {
|
opengl_light::apply_intensity( float const Factor ) {
|
||||||
|
// m7t setup light ubo here
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_light::apply_angle() {
|
opengl_light::apply_angle() {
|
||||||
|
// m7t setup light ubo here
|
||||||
::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 ) );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
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 );
|
m_frustum.calculate( Projection, Modelview );
|
||||||
// cache inverse tranformation matrix
|
// cache inverse tranformation matrix
|
||||||
// NOTE: transformation is done only to camera-centric space
|
// 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
|
// returns true if specified object is within camera frustum, false otherwise
|
||||||
bool
|
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 );
|
return ( m_frustum.sphere_inside( Area.center, Area.radius ) > 0.f );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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
|
// sphere test is faster than AABB, so we'll use it here
|
||||||
glm::vec3 diagonal(
|
glm::vec3 diagonal(
|
||||||
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
||||||
@@ -92,13 +72,16 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
|||||||
|
|
||||||
// debug helper, draws shape of frustum in world space
|
// debug helper, draws shape of frustum in world space
|
||||||
void
|
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 );
|
::glBegin( GL_LINES );
|
||||||
for( auto const pointindex : frustumshapepoinstorder ) {
|
for( auto const pointindex : frustumshapepoinstorder ) {
|
||||||
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
||||||
}
|
}
|
||||||
::glEnd();
|
::glEnd();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -108,16 +91,14 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
m_window = Window;
|
m_window = Window;
|
||||||
|
|
||||||
::glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||||
::glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
||||||
|
|
||||||
glClearDepth( 1.0f );
|
glClearDepth( 1.0f );
|
||||||
glClearColor( 51.0f / 255.0f, 102.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // initial background Color
|
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 );
|
||||||
glFrontFace( GL_CCW ); // Counter clock-wise polygons face out
|
glEnable( GL_CULL_FACE );
|
||||||
glEnable( GL_CULL_FACE ); // Cull back-facing triangles
|
|
||||||
glShadeModel( GL_SMOOTH ); // Enable Smooth Shading
|
|
||||||
|
|
||||||
m_geometry.units().texture = (
|
m_geometry.units().texture = (
|
||||||
Global.BasicRenderer ?
|
Global.BasicRenderer ?
|
||||||
@@ -127,34 +108,18 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
UILayer.set_unit( m_diffusetextureunit );
|
UILayer.set_unit( m_diffusetextureunit );
|
||||||
select_unit( m_diffusetextureunit );
|
select_unit( m_diffusetextureunit );
|
||||||
|
|
||||||
::glDepthFunc( GL_LEQUAL );
|
glDepthFunc( GL_LEQUAL );
|
||||||
glEnable( GL_DEPTH_TEST );
|
glEnable( GL_DEPTH_TEST );
|
||||||
glAlphaFunc( GL_GREATER, 0.f );
|
|
||||||
glEnable( GL_ALPHA_TEST );
|
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
glEnable( GL_BLEND );
|
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 );
|
glLineWidth( 1.0f );
|
||||||
glPointSize( 3.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 ) {
|
if( true == Global.ScaleSpecularValues ) {
|
||||||
m_specularopaquescalefactor = 0.25f;
|
m_specularopaquescalefactor = 0.25f;
|
||||||
m_speculartranslucentscalefactor = 1.5f;
|
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
|
// rgb value for 5780 kelvin
|
||||||
Global.DayLight.diffuse[ 0 ] = 255.0f / 255.0f;
|
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.diffuse[ 2 ] = 231.0f / 255.0f;
|
||||||
Global.DayLight.is_directional = true;
|
Global.DayLight.is_directional = true;
|
||||||
m_sunlight.id = opengl_renderer::sunlight;
|
m_sunlight.id = opengl_renderer::sunlight;
|
||||||
// ::glLightf( opengl_renderer::sunlight, GL_SPOT_CUTOFF, 90.0f );
|
|
||||||
|
|
||||||
// create dynamic light pool
|
// create dynamic light pool
|
||||||
for( int idx = 0; idx < Global.DynamicLightCount; ++idx ) {
|
for( int idx = 0; idx < Global.DynamicLightCount; ++idx ) {
|
||||||
@@ -171,12 +135,8 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
light.id = GL_LIGHT1 + idx;
|
light.id = GL_LIGHT1 + idx;
|
||||||
|
|
||||||
light.is_directional = false;
|
light.is_directional = false;
|
||||||
::glEnable( light.id ); // experimental intel chipset fix
|
|
||||||
::glLightf( light.id, GL_SPOT_CUTOFF, 7.5f );
|
//m7t config light ubo here
|
||||||
::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
|
|
||||||
|
|
||||||
m_lights.emplace_back( light );
|
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(), { 0.f, 1.f } },
|
||||||
{ { -size, -size, 0.f }, glm::vec3(), { 1.f, 0.f } },
|
{ { -size, -size, 0.f }, glm::vec3(), { 1.f, 0.f } },
|
||||||
{ { size, -size, 0.f }, glm::vec3(), { 0.f, 0.f } } },
|
{ { size, -size, 0.f }, glm::vec3(), { 0.f, 0.f } } },
|
||||||
geometrybank,
|
geometrybank, GL_TRIANGLE_STRIP );
|
||||||
GL_TRIANGLE_STRIP );
|
|
||||||
// prepare debug mode objects
|
gl::shader vert("shaders/simple.vert");
|
||||||
m_quadric = ::gluNewQuadric();
|
gl::shader frag("shaders/simple.frag");
|
||||||
::gluQuadricNormals( m_quadric, GLU_FLAT );
|
shader = std::make_unique<gl::program_mvp>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||||
|
shader->init();
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -278,20 +243,11 @@ opengl_renderer::Render() {
|
|||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void
|
void
|
||||||
opengl_renderer::Render_pass( rendermode const Mode ) {
|
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 );
|
setup_pass( m_renderpass, Mode );
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
|
glDebug("color pass");
|
||||||
|
|
||||||
if( ( true == m_environmentcubetexturesupport )
|
if( ( true == m_environmentcubetexturesupport )
|
||||||
&& ( true == World.InitPerformed() ) ) {
|
&& ( true == World.InitPerformed() ) ) {
|
||||||
@@ -318,30 +274,15 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
// render
|
// render
|
||||||
setup_drawing( true );
|
setup_drawing( true );
|
||||||
setup_units( true, false, false );
|
setup_units( true, false, false );
|
||||||
|
glDebug("render environment");
|
||||||
Render( &World.Environment );
|
Render( &World.Environment );
|
||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
setup_units( true, true, true );
|
setup_units( true, true, true );
|
||||||
#ifdef EU07_USE_DEBUG_CAMERA
|
shader->bind();
|
||||||
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
|
|
||||||
if( false == FreeFlyModeFlag ) {
|
if( false == FreeFlyModeFlag ) {
|
||||||
|
glDebug("render cab opaque");
|
||||||
switch_units( true, true, false );
|
switch_units( true, true, false );
|
||||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||||
// cache shadow colour in case we need to account for cab light
|
// 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 );
|
setup_shadow_color( shadowcolor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDebug("render opaque region");
|
||||||
switch_units( true, true, true );
|
switch_units( true, true, true );
|
||||||
setup_shadow_map( m_shadowtexture, m_shadowtexturematrix );
|
setup_shadow_map( m_shadowtexture, m_shadowtexturematrix );
|
||||||
Render( simulation::Region );
|
Render( simulation::Region );
|
||||||
|
|
||||||
// ...translucent parts
|
// ...translucent parts
|
||||||
|
glDebug("render translucent region");
|
||||||
setup_drawing( true );
|
setup_drawing( true );
|
||||||
Render_Alpha( simulation::Region );
|
Render_Alpha( simulation::Region );
|
||||||
if( false == FreeFlyModeFlag ) {
|
if( false == FreeFlyModeFlag ) {
|
||||||
|
glDebug("render translucent cab");
|
||||||
// cab render is performed without shadows, due to low resolution and number of models without windows :|
|
// cab render is performed without shadows, due to low resolution and number of models without windows :|
|
||||||
switch_units( true, true, false );
|
switch_units( true, true, false );
|
||||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||||
@@ -377,6 +323,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
if( m_environmentcubetexturesupport ) {
|
if( m_environmentcubetexturesupport ) {
|
||||||
// restore default texture matrix for reflections cube map
|
// restore default texture matrix for reflections cube map
|
||||||
select_unit( m_helpertextureunit );
|
select_unit( m_helpertextureunit );
|
||||||
@@ -385,8 +333,13 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
select_unit( m_diffusetextureunit );
|
select_unit( m_diffusetextureunit );
|
||||||
::glMatrixMode( GL_MODELVIEW );
|
::glMatrixMode( GL_MODELVIEW );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDebug("color pass done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glDebug("render ui");
|
||||||
UILayer.render();
|
UILayer.render();
|
||||||
|
glDebug("ui render done");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,32 +461,21 @@ opengl_renderer::setup_matrices() {
|
|||||||
void
|
void
|
||||||
opengl_renderer::setup_drawing( bool const Alpha ) {
|
opengl_renderer::setup_drawing( bool const Alpha ) {
|
||||||
|
|
||||||
if( true == Alpha ) {
|
if( true == Alpha )
|
||||||
|
|
||||||
::glEnable( GL_BLEND );
|
::glEnable( GL_BLEND );
|
||||||
::glAlphaFunc( GL_ALWAYS, 0.0f );
|
else
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glDisable( GL_BLEND );
|
::glDisable( GL_BLEND );
|
||||||
::glAlphaFunc( GL_GREATER, 0.5f );
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::reflections: {
|
case rendermode::reflections: {
|
||||||
::glEnable( GL_LIGHTING );
|
|
||||||
::glShadeModel( GL_SMOOTH );
|
|
||||||
if( Global.iMultisampling ) {
|
if( Global.iMultisampling ) {
|
||||||
::glEnable( GL_MULTISAMPLE );
|
::glEnable( GL_MULTISAMPLE );
|
||||||
}
|
}
|
||||||
// setup fog
|
// setup fog
|
||||||
if( Global.fFogEnd > 0 ) {
|
if( Global.fFogEnd > 0 ) {
|
||||||
// fog setup
|
// m7t setup fog ubo
|
||||||
::glFogfv( GL_FOG_COLOR, glm::value_ptr( Global.FogColor ) );
|
|
||||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / Global.fFogEnd ) );
|
|
||||||
::glEnable( GL_FOG );
|
|
||||||
}
|
}
|
||||||
else { ::glDisable( GL_FOG ); }
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -553,7 +495,6 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
|||||||
// diffuse texture unit.
|
// diffuse texture unit.
|
||||||
// NOTE: diffuse texture mapping is never fully disabled, alpha channel information is always included
|
// NOTE: diffuse texture mapping is never fully disabled, alpha channel information is always included
|
||||||
select_unit( m_diffusetextureunit );
|
select_unit( m_diffusetextureunit );
|
||||||
::glEnable( GL_TEXTURE_2D );
|
|
||||||
|
|
||||||
// update unit state
|
// update unit state
|
||||||
m_unitstate.diffuse = Diffuse;
|
m_unitstate.diffuse = Diffuse;
|
||||||
@@ -573,14 +514,10 @@ opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool cons
|
|||||||
// diffuse texture unit.
|
// diffuse texture unit.
|
||||||
// NOTE: toggle actually disables diffuse texture mapping, unlike setup counterpart
|
// NOTE: toggle actually disables diffuse texture mapping, unlike setup counterpart
|
||||||
if( true == Diffuse ) {
|
if( true == Diffuse ) {
|
||||||
|
|
||||||
select_unit( m_diffusetextureunit );
|
select_unit( m_diffusetextureunit );
|
||||||
::glEnable( GL_TEXTURE_2D );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
select_unit( m_diffusetextureunit );
|
select_unit( m_diffusetextureunit );
|
||||||
::glDisable( GL_TEXTURE_2D );
|
|
||||||
}
|
}
|
||||||
// update unit state
|
// update unit state
|
||||||
m_unitstate.diffuse = Diffuse;
|
m_unitstate.diffuse = Diffuse;
|
||||||
@@ -641,7 +578,6 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bind_Material( null_handle );
|
Bind_Material( null_handle );
|
||||||
::glDisable( GL_LIGHTING );
|
|
||||||
::glDisable( GL_DEPTH_TEST );
|
::glDisable( GL_DEPTH_TEST );
|
||||||
::glDepthMask( GL_FALSE );
|
::glDepthMask( GL_FALSE );
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
@@ -650,129 +586,20 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
Environment->m_skydome.Render();
|
Environment->m_skydome.Render();
|
||||||
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
|
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
|
||||||
gfx::opengl_vbogeometrybank::reset();
|
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
|
//m7t: restore 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 );
|
|
||||||
|
|
||||||
if( DebugModeFlag == true ) {
|
shader->bind();
|
||||||
// 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<float>(
|
|
||||||
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();
|
|
||||||
|
|
||||||
// clouds
|
// clouds
|
||||||
if( Environment->m_clouds.mdCloud ) {
|
if( Environment->m_clouds.mdCloud ) {
|
||||||
// setup
|
// setup
|
||||||
Disable_Lights();
|
Disable_Lights();
|
||||||
::glEnable( GL_LIGHTING );
|
//m7t set cloud color
|
||||||
::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
|
|
||||||
) );
|
|
||||||
// render
|
// render
|
||||||
Render( Environment->m_clouds.mdCloud, nullptr, 100.0 );
|
Render( Environment->m_clouds.mdCloud, nullptr, 100.0 );
|
||||||
Render_Alpha( Environment->m_clouds.mdCloud, nullptr, 100.0 );
|
Render_Alpha( Environment->m_clouds.mdCloud, nullptr, 100.0 );
|
||||||
// post-render cleanup
|
// 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();
|
m_sunlight.apply_angle();
|
||||||
@@ -781,7 +608,6 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
::glDepthMask( GL_TRUE );
|
::glDepthMask( GL_TRUE );
|
||||||
::glEnable( GL_DEPTH_TEST );
|
::glEnable( GL_DEPTH_TEST );
|
||||||
::glEnable( GL_LIGHTING );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1110,6 +936,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( data.geometry );
|
m_geometry.draw( data.geometry );
|
||||||
// debug data
|
// debug data
|
||||||
++m_debugstats.shapes;
|
++m_debugstats.shapes;
|
||||||
@@ -1203,14 +1030,14 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
|
|
||||||
// crude way to light the cabin, until we have something more complete in place
|
// 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 );
|
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||||
|
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
// reset the overall ambient
|
// 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 ) {
|
if( Dynamic->InteriorLightLevel > 0.f ) {
|
||||||
// crude way to light the cabin, until we have something more complete in place
|
// 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
|
// render
|
||||||
if( true == Alpha ) {
|
if( true == Alpha ) {
|
||||||
@@ -1300,7 +1127,7 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) {
|
|||||||
}
|
}
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
// reset the overall ambient
|
// reset the overall ambient
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
//m7t set ambient
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1409,9 +1236,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( true == m_renderspecular ) {
|
|
||||||
::glEnable( GL_NORMALIZE );
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
// material configuration:
|
// material configuration:
|
||||||
// textures...
|
// textures...
|
||||||
@@ -1422,40 +1246,25 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
// również 0
|
// również 0
|
||||||
Bind_Material( Submodel->m_material );
|
Bind_Material( Submodel->m_material );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//m7t set material
|
||||||
|
|
||||||
// ...colors...
|
// ...colors...
|
||||||
::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub
|
|
||||||
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
|
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
|
// 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
|
// ...luminance
|
||||||
auto const unitstate = m_unitstate;
|
auto const unitstate = m_unitstate;
|
||||||
if( Global.fLuminance < Submodel->fLight ) {
|
if( Global.fLuminance < Submodel->fLight ) {
|
||||||
// zeby swiecilo na kolorowo
|
// 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
|
// main draw call
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
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
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
switch( Submodel->m_normalizenormals ) {
|
switch( Submodel->m_normalizenormals ) {
|
||||||
case TSubModel::normalize: {
|
case TSubModel::normalize: {
|
||||||
@@ -1466,9 +1275,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( true == m_renderspecular ) {
|
|
||||||
::glDisable( GL_NORMALIZE );
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1510,12 +1316,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
if( lightlevel > 0.f ) {
|
if( lightlevel > 0.f ) {
|
||||||
// material configuration:
|
// material configuration:
|
||||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
|
|
||||||
|
|
||||||
Bind_Material( null_handle );
|
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 );
|
::glEnable( GL_BLEND );
|
||||||
|
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
@@ -1528,6 +1330,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
switch_units( m_unitstate.diffuse, false, false );
|
switch_units( m_unitstate.diffuse, false, false );
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
@@ -1538,7 +1341,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
::glPopAttrib();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1556,17 +1358,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
case rendermode::reflections: {
|
case rendermode::reflections: {
|
||||||
if( Global.fLuminance < Submodel->fLight ) {
|
if( Global.fLuminance < Submodel->fLight ) {
|
||||||
|
|
||||||
// material configuration:
|
|
||||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
|
|
||||||
|
|
||||||
Bind_Material( null_handle );
|
Bind_Material( null_handle );
|
||||||
::glDisable( GL_LIGHTING );
|
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
||||||
|
|
||||||
// post-draw reset
|
|
||||||
::glPopAttrib();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1605,6 +1401,8 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
++m_debugstats.paths;
|
++m_debugstats.paths;
|
||||||
++m_debugstats.drawcalls;
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
|
shader->copy_gl_mvp();
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::reflections: {
|
case rendermode::reflections: {
|
||||||
@@ -1639,7 +1437,6 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
void
|
void
|
||||||
opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last ) {
|
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
|
// setup
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
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
|
// first pass, material 1
|
||||||
for( auto first { First }; first != Last; ++first ) {
|
for( auto first { First }; first != Last; ++first ) {
|
||||||
|
|
||||||
@@ -1747,13 +1546,6 @@ opengl_renderer::Render( TMemCell *Memcell ) {
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
@@ -1833,8 +1625,6 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
// third pass draws the wires;
|
// third pass draws the wires;
|
||||||
// wires use section vbos, but for the time being we want to draw them at the very end
|
// 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 };
|
auto first{ First };
|
||||||
while( first != Last ) {
|
while( first != Last ) {
|
||||||
|
|
||||||
@@ -1864,8 +1654,6 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
|
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
|
|
||||||
::glEnable( GL_LIGHTING );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1944,12 +1732,8 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
|
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
|
||||||
1.f, 1.5f ) );
|
1.f, 1.5f ) );
|
||||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
// 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
|
// render
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( Traction->m_geometry );
|
m_geometry.draw( Traction->m_geometry );
|
||||||
// debug data
|
// debug data
|
||||||
++m_debugstats.traction;
|
++m_debugstats.traction;
|
||||||
@@ -1986,12 +1770,8 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
|||||||
clamp(
|
clamp(
|
||||||
0.5f * linealpha + data.line_width * data.area.radius / 1000.f,
|
0.5f * linealpha + data.line_width * data.area.radius / 1000.f,
|
||||||
1.f, 8.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
|
// render
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( data.geometry );
|
m_geometry.draw( data.geometry );
|
||||||
++m_debugstats.lines;
|
++m_debugstats.lines;
|
||||||
++m_debugstats.drawcalls;
|
++m_debugstats.drawcalls;
|
||||||
@@ -2034,15 +1814,10 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
|
|
||||||
// crude way to light the cabin, until we have something more complete in place
|
// 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 );
|
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; }
|
break; }
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( true == m_renderspecular ) {
|
|
||||||
::glEnable( GL_NORMALIZE );
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
// material configuration:
|
// material configuration:
|
||||||
// textures...
|
// textures...
|
||||||
@@ -2170,37 +1942,16 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
Bind_Material( Submodel->m_material );
|
Bind_Material( Submodel->m_material );
|
||||||
}
|
}
|
||||||
// ...colors...
|
// ...colors...
|
||||||
::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub
|
// m7t set material
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
// ...luminance
|
// ...luminance
|
||||||
auto const unitstate = m_unitstate;
|
auto const unitstate = m_unitstate;
|
||||||
if( Global.fLuminance < Submodel->fLight ) {
|
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
|
// main draw call
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
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
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
switch( Submodel->m_normalizenormals ) {
|
switch( Submodel->m_normalizenormals ) {
|
||||||
case TSubModel::normalize: {
|
case TSubModel::normalize: {
|
||||||
@@ -2211,26 +1962,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( true == m_renderspecular ) {
|
|
||||||
::glDisable( GL_NORMALIZE );
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::cabshadows: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -2266,12 +2001,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
glarelevel = clamp( glarelevel - static_cast<float>(Global.fLuminance), 0.f, 1.f );
|
glarelevel = clamp( glarelevel - static_cast<float>(Global.fLuminance), 0.f, 1.f );
|
||||||
|
|
||||||
if( glarelevel > 0.0f ) {
|
if( glarelevel > 0.0f ) {
|
||||||
// setup
|
|
||||||
::glPushAttrib( GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
|
|
||||||
|
|
||||||
Bind_Texture( m_glaretexture );
|
Bind_Texture( m_glaretexture );
|
||||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
|
||||||
::glDisable( GL_LIGHTING );
|
|
||||||
::glDepthMask( GL_FALSE );
|
::glDepthMask( GL_FALSE );
|
||||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
::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
|
::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
|
::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
|
// disable shadows so they don't obstruct self-lit items
|
||||||
/*
|
|
||||||
setup_shadow_color( colors::white );
|
|
||||||
*/
|
|
||||||
auto const unitstate = m_unitstate;
|
auto const unitstate = m_unitstate;
|
||||||
switch_units( unitstate.diffuse, false, false );
|
switch_units( unitstate.diffuse, false, false );
|
||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
|
shader->copy_gl_mvp();
|
||||||
m_geometry.draw( m_billboardgeometry );
|
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();
|
::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 } ),
|
glm::max( glm::vec3{ colors::none }, scenelight.color * glm::vec3{ scenelight.intensity } - glm::vec3{ luminance } ),
|
||||||
renderlight->ambient[ 3 ] };
|
renderlight->ambient[ 3 ] };
|
||||||
|
|
||||||
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, static_cast<GLfloat>( (0.25 * scenelight.count) / std::pow( scenelight.count, 2 ) * (scenelight.owner->DimHeadlights ? 1.25 : 1.0) ) );
|
//m7t fill light
|
||||||
::glEnable( renderlight->id );
|
|
||||||
|
|
||||||
renderlight->apply_intensity();
|
renderlight->apply_intensity();
|
||||||
renderlight->apply_angle();
|
renderlight->apply_angle();
|
||||||
@@ -2518,7 +2231,6 @@ opengl_renderer::Update_Lights( light_array &Lights ) {
|
|||||||
|
|
||||||
while( renderlight != m_lights.end() ) {
|
while( renderlight != m_lights.end() ) {
|
||||||
// if we went through all scene lights and there's still opengl lights remaining, kill these
|
// if we went through all scene lights and there's still opengl lights remaining, kill these
|
||||||
::glDisable( renderlight->id );
|
|
||||||
++renderlight;
|
++renderlight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2528,7 +2240,6 @@ opengl_renderer::Disable_Lights() {
|
|||||||
|
|
||||||
for( size_t idx = 0; idx < m_lights.size() + 1; ++idx ) {
|
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 ) )
|
+ " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) )
|
||||||
+ " OpenGL Version: " + oglversion );
|
+ " OpenGL Version: " + oglversion );
|
||||||
|
|
||||||
if( !GLEW_VERSION_1_5 ) {
|
if( !GLEW_VERSION_3_3 ) {
|
||||||
ErrorLog( "Requires openGL >= 1.5" );
|
ErrorLog( "Requires openGL >= 3.3" );
|
||||||
return false;
|
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 ) {
|
if( GLEW_EXT_framebuffer_object ) {
|
||||||
m_framebuffersupport = true;
|
m_framebuffersupport = true;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "MemCell.h"
|
#include "MemCell.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
#include "gl/shader_mvp.h"
|
||||||
|
|
||||||
#define EU07_USE_PICKING_FRAMEBUFFER
|
#define EU07_USE_PICKING_FRAMEBUFFER
|
||||||
//#define EU07_USE_DEBUG_SHADOWMAP
|
//#define EU07_USE_DEBUG_SHADOWMAP
|
||||||
@@ -395,6 +396,8 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
GLuint m_gltimequery = 0;
|
GLuint m_gltimequery = 0;
|
||||||
GLuint64 m_gllasttime = 0;
|
GLuint64 m_gllasttime = 0;
|
||||||
|
|
||||||
|
std::unique_ptr<gl::program_mvp> shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern opengl_renderer GfxRenderer;
|
extern opengl_renderer GfxRenderer;
|
||||||
|
|||||||
267
shader.cpp
267
shader.cpp
@@ -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 <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
|
||||||
|
|
||||||
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<gl_shader> 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<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()
|
|
||||||
{
|
|
||||||
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<gl_shader> 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<typename T>
|
|
||||||
GLuint gl_ubo<T>::binding_point_cnt = 0;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void gl_ubo<T>::init()
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &buffer_id);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, buffer_id);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), nullptr, GL_DYNAMIC_DRAW);
|
|
||||||
binding_point = binding_point_cnt++;
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, binding_point, buffer_id);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void gl_ubo<T>::update()
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, buffer_id);
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), &data);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
gl_ubo<T>::~gl_ubo()
|
|
||||||
{
|
|
||||||
if (buffer_id)
|
|
||||||
glDeleteBuffers(1, &buffer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template class gl_ubo<gl_ubodata_light_params>;
|
|
||||||
148
shader.h
148
shader.h
@@ -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_shader>);
|
|
||||||
~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<gl_shader>);
|
|
||||||
|
|
||||||
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<typename T>
|
|
||||||
class gl_ubo
|
|
||||||
{
|
|
||||||
GLuint buffer_id = 0;
|
|
||||||
GLuint binding_point;
|
|
||||||
static GLuint binding_point_cnt;
|
|
||||||
|
|
||||||
public:
|
|
||||||
T data;
|
|
||||||
void init();
|
|
||||||
~gl_ubo();
|
|
||||||
void update();
|
|
||||||
GLuint get_binding_point()
|
|
||||||
{
|
|
||||||
return binding_point;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class gl_program_light : public gl_program_mvp
|
|
||||||
{
|
|
||||||
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<gl_shader>);
|
|
||||||
|
|
||||||
void set_lightview(const glm::mat4 &lightview);
|
|
||||||
void set_material(const material_s &mat);
|
|
||||||
void bind_ubodata(GLuint point);
|
|
||||||
void update();
|
|
||||||
};
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
in vec3 f_color;
|
in vec3 f_color;
|
||||||
|
|
||||||
out vec4 color;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
color = vec4(f_color, 1.0f);
|
gl_FragColor = vec4(f_color, 1.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
layout (location = 0) in vec3 v_vert;
|
in vec3 v_vert;
|
||||||
layout (location = 1) in vec3 v_color;
|
in vec3 v_color;
|
||||||
|
|
||||||
out vec3 f_color;
|
out vec3 f_color;
|
||||||
|
|
||||||
|
|||||||
38
skydome.cpp
38
skydome.cpp
@@ -117,6 +117,14 @@ void CSkyDome::Update( glm::vec3 const &Sun ) {
|
|||||||
// render skydome to screen
|
// render skydome to screen
|
||||||
void CSkyDome::Render() {
|
void CSkyDome::Render() {
|
||||||
|
|
||||||
|
if (!m_shader)
|
||||||
|
{
|
||||||
|
gl::shader vert("shaders/vbocolor.vert");
|
||||||
|
gl::shader frag("shaders/color.frag");
|
||||||
|
m_shader = std::make_unique<gl::program_mvp>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||||
|
m_shader->init();
|
||||||
|
}
|
||||||
|
|
||||||
if( m_vertexbuffer == -1 ) {
|
if( m_vertexbuffer == -1 ) {
|
||||||
// build the buffers
|
// build the buffers
|
||||||
::glGenBuffers( 1, &m_vertexbuffer );
|
::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 );
|
::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
|
// NOTE: vertex and index source data is superfluous past this point, but, eh
|
||||||
}
|
}
|
||||||
// begin
|
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
m_shader->bind();
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
m_shader->copy_gl_mvp();
|
||||||
// positions
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0);
|
||||||
// colours
|
glEnableVertexAttribArray(0);
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
glBindBuffer(GL_ARRAY_BUFFER, m_coloursbuffer);
|
||||||
::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), 0);
|
||||||
// indices
|
glEnableVertexAttribArray(1);
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
glDisableVertexAttribArray(2);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer);
|
||||||
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
||||||
// cleanup
|
|
||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
glUseProgram(0);
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {
|
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gl/shader_mvp.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// sky gradient based on "A practical analytic model for daylight"
|
// sky gradient based on "A practical analytic model for daylight"
|
||||||
// by A. J. Preetham Peter Shirley Brian Smits (University of Utah)
|
// 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 GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity );
|
||||||
float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval );
|
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 );
|
float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval );
|
||||||
|
|
||||||
|
std::unique_ptr<gl::program_mvp> m_shader;
|
||||||
};
|
};
|
||||||
|
|||||||
13
sun.cpp
13
sun.cpp
@@ -50,18 +50,7 @@ cSun::update() {
|
|||||||
void
|
void
|
||||||
cSun::render() {
|
cSun::render() {
|
||||||
|
|
||||||
::glColor4f( 255.f / 255.f, 242.f / 255.f, 231.f / 255.f, 1.f );
|
//m7t
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
glm::vec3
|
glm::vec3
|
||||||
|
|||||||
33
uilayer.cpp
33
uilayer.cpp
@@ -974,31 +974,19 @@ ui_layer::render() {
|
|||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
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_DEPTH_TEST );
|
||||||
glDisable( GL_ALPHA_TEST );
|
|
||||||
glEnable( GL_TEXTURE_2D );
|
|
||||||
glEnable( GL_BLEND );
|
glEnable( GL_BLEND );
|
||||||
|
|
||||||
::glColor4fv( glm::value_ptr( colors::white ) );
|
|
||||||
|
|
||||||
// render code here
|
// render code here
|
||||||
render_background();
|
render_background();
|
||||||
render_texture();
|
render_texture();
|
||||||
|
|
||||||
glDisable( GL_TEXTURE_2D );
|
|
||||||
glDisable( GL_TEXTURE_CUBE_MAP );
|
|
||||||
|
|
||||||
render_progress();
|
render_progress();
|
||||||
|
|
||||||
glDisable( GL_BLEND );
|
glDisable( GL_BLEND );
|
||||||
|
|
||||||
render_panels();
|
render_panels();
|
||||||
render_tooltip();
|
render_tooltip();
|
||||||
|
|
||||||
glPopAttrib();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1064,6 +1052,8 @@ ui_layer::render_progress() {
|
|||||||
Global.iWindowHeight / 768.f * screenratio / ( 4.0f / 3.0f ) );
|
Global.iWindowHeight / 768.f * screenratio / ( 4.0f / 3.0f ) );
|
||||||
float const height = 768.0f * heightratio;
|
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 );
|
::glColor4f( 216.0f / 255.0f, 216.0f / 255.0f, 216.0f / 255.0f, 1.0f );
|
||||||
auto const charsize = 9.0f;
|
auto const charsize = 9.0f;
|
||||||
auto const textwidth = m_progresstext.size() * charsize;
|
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.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 ) );
|
( 0.5f * ( Global.iWindowHeight - height ) + origin.y * heightratio ) + ( charsize ) + ( ( size.y * heightratio - textheight ) * 0.5f * heightratio ) );
|
||||||
print( m_progresstext );
|
print( m_progresstext );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,12 +1080,14 @@ ui_layer::render_panels() {
|
|||||||
|
|
||||||
int lineidx = 0;
|
int lineidx = 0;
|
||||||
for( auto const &line : panel->text_lines ) {
|
for( auto const &line : panel->text_lines ) {
|
||||||
|
/*
|
||||||
::glColor4fv( glm::value_ptr( line.color ) );
|
::glColor4fv( glm::value_ptr( line.color ) );
|
||||||
::glRasterPos2f(
|
::glRasterPos2f(
|
||||||
0.5f * ( Global.iWindowWidth - width ) + panel->origin_x * height,
|
0.5f * ( Global.iWindowWidth - width ) + panel->origin_x * height,
|
||||||
panel->origin_y * height + 20.f * lineidx );
|
panel->origin_y * height + 20.f * lineidx );
|
||||||
print( line.data );
|
print( line.data );
|
||||||
|
*/
|
||||||
|
// m7t: port to core
|
||||||
++lineidx;
|
++lineidx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1110,9 +1103,12 @@ ui_layer::render_tooltip() {
|
|||||||
glm::dvec2 mousepos;
|
glm::dvec2 mousepos;
|
||||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||||
|
|
||||||
|
// m7t: port to core
|
||||||
|
/*
|
||||||
::glColor4fv( glm::value_ptr( colors::white ) );
|
::glColor4fv( glm::value_ptr( colors::white ) );
|
||||||
::glRasterPos2f( mousepos.x + 20.0f, mousepos.y + 25.0f );
|
::glRasterPos2f( mousepos.x + 20.0f, mousepos.y + 25.0f );
|
||||||
print( m_tooltip );
|
print( m_tooltip );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1141,7 +1137,6 @@ void
|
|||||||
ui_layer::render_texture() {
|
ui_layer::render_texture() {
|
||||||
|
|
||||||
if( m_texture != 0 ) {
|
if( m_texture != 0 ) {
|
||||||
::glColor4fv( glm::value_ptr( colors::white ) );
|
|
||||||
|
|
||||||
GfxRenderer.Bind_Texture( null_handle );
|
GfxRenderer.Bind_Texture( null_handle );
|
||||||
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
||||||
@@ -1149,6 +1144,8 @@ ui_layer::render_texture() {
|
|||||||
auto const size = 512.f;
|
auto const size = 512.f;
|
||||||
auto const offset = 64.f;
|
auto const offset = 64.f;
|
||||||
|
|
||||||
|
//m7t
|
||||||
|
/*
|
||||||
glBegin( GL_TRIANGLE_STRIP );
|
glBegin( GL_TRIANGLE_STRIP );
|
||||||
|
|
||||||
glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( offset, Global.iWindowHeight - offset - size );
|
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 );
|
glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( offset + size, Global.iWindowHeight - offset );
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
*/
|
||||||
|
|
||||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||||
}
|
}
|
||||||
@@ -1165,6 +1163,8 @@ ui_layer::render_texture() {
|
|||||||
void
|
void
|
||||||
ui_layer::print( std::string const &Text )
|
ui_layer::print( std::string const &Text )
|
||||||
{
|
{
|
||||||
|
//m7t
|
||||||
|
/*
|
||||||
if( (false == Global.DLFont)
|
if( (false == Global.DLFont)
|
||||||
|| (true == Text.empty()) )
|
|| (true == Text.empty()) )
|
||||||
return;
|
return;
|
||||||
@@ -1183,11 +1183,13 @@ ui_layer::print( std::string const &Text )
|
|||||||
|
|
||||||
::glPopAttrib();
|
::glPopAttrib();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) {
|
ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) {
|
||||||
|
//m7t
|
||||||
|
/*
|
||||||
float const screenratio = static_cast<float>( Global.iWindowWidth ) / Global.iWindowHeight;
|
float const screenratio = static_cast<float>( Global.iWindowWidth ) / Global.iWindowHeight;
|
||||||
float const width =
|
float const width =
|
||||||
( screenratio >= ( 4.f / 3.f ) ?
|
( 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 );
|
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();
|
glEnd();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user