mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
work
This commit is contained in:
@@ -84,6 +84,8 @@ set(SOURCES
|
||||
"gl/shader_mvp.cpp"
|
||||
"gl/vao.cpp"
|
||||
"gl/ubo.cpp"
|
||||
"gl/framebuffer.cpp"
|
||||
"gl/renderbuffer.cpp"
|
||||
)
|
||||
|
||||
set (PREFIX "")
|
||||
|
||||
10
Globals.cpp
10
Globals.cpp
@@ -349,12 +349,6 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
>> shadowtune.depth
|
||||
>> shadowtune.distance;
|
||||
}
|
||||
else if (token == "smoothtraction")
|
||||
{
|
||||
// podwójna jasność ambient
|
||||
Parser.getTokens();
|
||||
Parser >> bSmoothTraction;
|
||||
}
|
||||
else if( token == "splinefidelity" ) {
|
||||
// segment size during spline->geometry conversion
|
||||
float splinefidelity;
|
||||
@@ -680,10 +674,6 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
bEnableTraction = false; // false = pantograf się nie połamie
|
||||
bLiveTraction = false; // false = pantografy zawsze zbierają 95% MaxVoltage
|
||||
}
|
||||
if (iMultisampling)
|
||||
{ // antyaliasing całoekranowy wyłącza rozmywanie drutów
|
||||
bSmoothTraction = false;
|
||||
}
|
||||
if (iMultiplayer > 0)
|
||||
{
|
||||
bInactivePause = false; // okno "w tle" nie może pauzować, jeśli włączona komunikacja
|
||||
|
||||
@@ -105,7 +105,7 @@ struct global_settings {
|
||||
bool bWireFrame{ false };
|
||||
bool bAdjustScreenFreq{ true };
|
||||
float BaseDrawRange{ 2500.f };
|
||||
int DynamicLightCount{ 3 };
|
||||
int DynamicLightCount{ 8 };
|
||||
bool ScaleSpecularValues{ true };
|
||||
bool BasicRenderer{ false };
|
||||
bool RenderShadows{ true };
|
||||
@@ -119,7 +119,6 @@ struct global_settings {
|
||||
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
||||
GLint iMaxTextureSize{ 4096 }; // maksymalny rozmiar tekstury
|
||||
int iMultisampling{ 2 }; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
|
||||
bool bSmoothTraction{ true }; // wygładzanie drutów starym sposobem
|
||||
float SplineFidelity{ 1.f }; // determines segment size during conversion of splines to geometry
|
||||
bool ResourceSweep{ true }; // gfx resource garbage collection
|
||||
bool ResourceMove{ false }; // gfx resources are moved between cpu and gpu side instead of sending a copy
|
||||
|
||||
27
Texture.cpp
27
Texture.cpp
@@ -774,22 +774,13 @@ opengl_texture::flip_vertical() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
texture_manager::assign_units( GLint const Helper, GLint const Shadows, GLint const Normals, GLint const Diffuse ) {
|
||||
|
||||
m_units[ 0 ].unit = Helper;
|
||||
m_units[ 1 ].unit = Shadows;
|
||||
m_units[ 2 ].unit = Normals;
|
||||
m_units[ 3 ].unit = Diffuse;
|
||||
}
|
||||
|
||||
void
|
||||
texture_manager::unit( GLint const Textureunit ) {
|
||||
|
||||
if( m_activeunit == Textureunit ) { return; }
|
||||
|
||||
m_activeunit = Textureunit;
|
||||
::glActiveTexture( Textureunit );
|
||||
::glActiveTexture( GL_TEXTURE0 + Textureunit );
|
||||
}
|
||||
|
||||
// ustalenie numeru tekstury, wczytanie jeśli jeszcze takiej nie było
|
||||
@@ -860,32 +851,32 @@ texture_manager::bind( std::size_t const Unit, texture_handle const Texture ) {
|
||||
|
||||
m_textures[ Texture ].second = m_garbagecollector.timestamp();
|
||||
|
||||
if( Texture == m_units[ Unit ].texture ) {
|
||||
if( Texture == m_units[ Unit ] ) {
|
||||
// don't bind again what's already active
|
||||
return;
|
||||
}
|
||||
// TBD, TODO: do binding in texture object, add support for other types than 2d
|
||||
if( m_units[ Unit ].unit == 0 ) { return; }
|
||||
unit( m_units[ Unit ].unit );
|
||||
|
||||
unit(Unit);
|
||||
if( Texture != null_handle ) {
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
||||
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
||||
m_units[ Unit ].texture = Texture;
|
||||
m_units[ Unit ] = Texture;
|
||||
#else
|
||||
if( true == texture( Texture ).bind() ) {
|
||||
m_units[ Unit ].texture = Texture;
|
||||
m_units[ Unit ] = Texture;
|
||||
}
|
||||
else {
|
||||
// TODO: bind a special 'error' texture on failure
|
||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
m_units[ Unit ].texture = 0;
|
||||
m_units[ Unit ] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
m_units[ Unit ].texture = 0;
|
||||
m_units[ Unit ] = 0;
|
||||
}
|
||||
// all done
|
||||
return;
|
||||
@@ -909,7 +900,7 @@ texture_manager::update() {
|
||||
|
||||
if( m_garbagecollector.sweep() > 0 ) {
|
||||
for( auto &unit : m_units ) {
|
||||
unit.texture = -1;
|
||||
unit = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,6 @@ public:
|
||||
texture_manager();
|
||||
~texture_manager() { delete_textures(); }
|
||||
|
||||
void
|
||||
assign_units( GLint const Helper, GLint const Shadows, GLint const Normals, GLint const Diffuse );
|
||||
// activates specified texture unit
|
||||
void
|
||||
unit( GLint const Textureunit );
|
||||
@@ -112,11 +110,6 @@ private:
|
||||
|
||||
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||
|
||||
struct texture_unit {
|
||||
GLint unit { 0 };
|
||||
texture_handle texture { null_handle }; // current (most recently bound) texture
|
||||
};
|
||||
|
||||
// methods:
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
texture_handle
|
||||
@@ -132,7 +125,7 @@ private:
|
||||
texturetimepointpair_sequence m_textures;
|
||||
index_map m_texturemappings;
|
||||
garbage_collector<texturetimepointpair_sequence> m_garbagecollector { m_textures, 600, 60, "texture" };
|
||||
std::array<texture_unit, 4> m_units;
|
||||
std::array<texture_handle, 4> m_units;
|
||||
GLint m_activeunit { 0 };
|
||||
};
|
||||
|
||||
|
||||
14
Track.cpp
14
Track.cpp
@@ -1361,7 +1361,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
}
|
||||
if( ( Bank == 0 ) && ( false == Geometry2.empty() ) ) {
|
||||
// special variant, replace existing data for a turntable track
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 0 ], GL_TRIANGLE_STRIP );
|
||||
}
|
||||
}
|
||||
if (m_material1)
|
||||
@@ -1377,10 +1377,10 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
if( ( Bank == 0 ) && ( false == Geometry1.empty() ) ) {
|
||||
// special variant, replace existing data for a turntable track
|
||||
Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 0 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 0 ], GL_TRIANGLE_STRIP );
|
||||
vertices.clear(); // reuse the scratchpad
|
||||
Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 1 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 1 ], GL_TRIANGLE_STRIP );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2478,13 +2478,13 @@ TTrack * TTrack::RaAnimate()
|
||||
if( m_material1 ) {
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, fTexLength, 1.0, 0, bladelength, SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ], GL_TRIANGLE_STRIP );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, fTexLength, 1.0, 0, bladelength, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ], GL_TRIANGLE_STRIP );
|
||||
vertices.clear();
|
||||
}
|
||||
}
|
||||
@@ -2492,13 +2492,13 @@ TTrack * TTrack::RaAnimate()
|
||||
if( m_material1 ) {
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, fTexLength, 1.0, 0, bladelength, -SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ], GL_TRIANGLE_STRIP );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, fTexLength, 1.0, 0, bladelength, fMaxOffset - SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ], GL_TRIANGLE_STRIP );
|
||||
vertices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
56
Traction.cpp
56
Traction.cpp
@@ -566,37 +566,21 @@ TTraction::wire_color() const {
|
||||
switch( PowerState ) {
|
||||
|
||||
case 1: {
|
||||
// czerwone z podłączonym zasilaniem 1
|
||||
// color.r = 1.0f;
|
||||
// color.g = 0.0f;
|
||||
// color.b = 0.0f;
|
||||
// cyan
|
||||
color = glm::vec3 { 0.f, 174.f / 255.f, 239.f / 255.f };
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// zielone z podłączonym zasilaniem 2
|
||||
// color.r = 0.0f;
|
||||
// color.g = 1.0f;
|
||||
// color.b = 0.0f;
|
||||
// yellow
|
||||
color = glm::vec3 { 240.f / 255.f, 228.f / 255.f, 0.f };
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
//żółte z podłączonym zasilaniem z obu stron
|
||||
// color.r = 1.0f;
|
||||
// color.g = 1.0f;
|
||||
// color.b = 0.0f;
|
||||
// green
|
||||
color = glm::vec3 { 0.f, 239.f / 255.f, 118.f / 255.f };
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// niebieskie z podłączonym zasilaniem
|
||||
// color.r = 0.5f;
|
||||
// color.g = 0.5f;
|
||||
// color.b = 1.0f;
|
||||
// white for powered, red for ends
|
||||
color = (
|
||||
psPowered != nullptr ?
|
||||
@@ -611,46 +595,6 @@ TTraction::wire_color() const {
|
||||
color.g *= 0.6f;
|
||||
color.b *= 0.6f;
|
||||
}
|
||||
/*
|
||||
switch( iTries ) {
|
||||
case 0: {
|
||||
color = glm::vec3{ 239.f / 255.f, 128.f / 255.f, 128.f / 255.f }; // red
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
color = glm::vec3{ 240.f / 255.f, 228.f / 255.f, 0.f }; // yellow
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
color = glm::vec3{ 0.f / 255.f, 239.f / 255.f, 118.f / 255.f }; // green
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
color = glm::vec3{ 239.f / 255.f, 239.f / 255.f, 239.f / 255.f };
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
switch( iLast ) {
|
||||
case 0: {
|
||||
color = glm::vec3{ 240.f / 255.f, 228.f / 255.f, 0.f }; // yellow
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
color = glm::vec3{ 239.f / 255.f, 128.f / 255.f, 128.f / 255.f }; // red
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
color = glm::vec3{ 0.f / 255.f, 239.f / 255.f, 118.f / 255.f }; // green
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
color = glm::vec3{ 239.f / 255.f, 239.f / 255.f, 239.f / 255.f };
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace gl
|
||||
active = this;
|
||||
T::bind(*static_cast<T*>(active));
|
||||
}
|
||||
void unbind()
|
||||
static void unbind()
|
||||
{
|
||||
active = nullptr;
|
||||
T::bind(0);
|
||||
|
||||
0
gl/framebuffer.cpp
Normal file
0
gl/framebuffer.cpp
Normal file
0
gl/framebuffer.h
Normal file
0
gl/framebuffer.h
Normal file
58
gl/glsl_common.h
Normal file
58
gl/glsl_common.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "ubo.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
const std::string glsl_common =
|
||||
"const uint MAX_LIGHTS = " + std::to_string(MAX_LIGHTS) + "U;\n" +
|
||||
"const uint MAX_PARAMS = " + std::to_string(MAX_PARAMS) + "U;\n" +
|
||||
R"STRING(
|
||||
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;
|
||||
};
|
||||
|
||||
layout(std140) uniform light_ubo
|
||||
{
|
||||
vec3 ambient;
|
||||
float fog_density;
|
||||
|
||||
vec3 fog_color;
|
||||
uint lights_count;
|
||||
|
||||
light_s lights[MAX_LIGHTS];
|
||||
};
|
||||
|
||||
layout (std140) uniform model_ubo
|
||||
{
|
||||
mat4 modelview;
|
||||
mat3 modelviewnormal;
|
||||
vec4 param[MAX_PARAMS];
|
||||
|
||||
vec3 velocity;
|
||||
float opacity;
|
||||
float emission;
|
||||
};
|
||||
|
||||
layout (std140) uniform scene_ubo
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 lightview;
|
||||
float time;
|
||||
};
|
||||
|
||||
)STRING";
|
||||
}
|
||||
0
gl/renderbuffer.cpp
Normal file
0
gl/renderbuffer.cpp
Normal file
0
gl/renderbuffer.h
Normal file
0
gl/renderbuffer.h
Normal file
@@ -3,6 +3,7 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "shader.h"
|
||||
#include "glsl_common.h"
|
||||
|
||||
inline bool strcend(std::string const &value, std::string const &ending)
|
||||
{
|
||||
@@ -11,17 +12,51 @@ inline bool strcend(std::string const &value, std::string const &ending)
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
gl::shader::shader(const std::string &filename)
|
||||
std::string gl::shader::read_file(const std::string &filename)
|
||||
{
|
||||
std::stringstream stream;
|
||||
std::ifstream f;
|
||||
f.exceptions(std::ifstream::badbit);
|
||||
|
||||
f.open(filename);
|
||||
f.open("shaders/" + filename);
|
||||
stream << f.rdbuf();
|
||||
f.close();
|
||||
|
||||
std::string str = stream.str();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void gl::shader::expand_includes(std::string &str)
|
||||
{
|
||||
size_t start_pos = 0;
|
||||
|
||||
std::string magic = "#include";
|
||||
while ((start_pos = str.find(magic, start_pos)) != str.npos)
|
||||
{
|
||||
size_t fp = str.find('<', start_pos);
|
||||
size_t fe = str.find('>', start_pos);
|
||||
if (fp == str.npos || fe == str.npos)
|
||||
return;
|
||||
|
||||
std::string filename = str.substr(fp + 1, fe - fp - 1);
|
||||
std::string content;
|
||||
if (filename != "common")
|
||||
content = read_file(filename);
|
||||
else
|
||||
content = glsl_common;
|
||||
|
||||
str.replace(start_pos, fe - start_pos + 1, content);
|
||||
}
|
||||
}
|
||||
|
||||
gl::shader::shader(const std::string &filename)
|
||||
{
|
||||
std::string str = read_file(filename);
|
||||
expand_includes(str);
|
||||
|
||||
std::cout << (str) << std::endl;;
|
||||
|
||||
const GLchar *cstr = str.c_str();
|
||||
|
||||
if (!cstr[0])
|
||||
@@ -58,7 +93,19 @@ gl::shader::~shader()
|
||||
void gl::program::init()
|
||||
{
|
||||
bind();
|
||||
glUniform1i(glGetUniformLocation(*this, "tex"), 3);
|
||||
|
||||
int i = 0;
|
||||
GLuint loc;
|
||||
while (true)
|
||||
{
|
||||
std::string name = "tex" + std::to_string(i + 1);
|
||||
loc = glGetUniformLocation(*this, name.c_str());
|
||||
if (loc != -1)
|
||||
glUniform1i(loc, i);
|
||||
else
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
gl::program::program()
|
||||
|
||||
@@ -14,6 +14,10 @@ namespace gl
|
||||
public:
|
||||
shader(const std::string &filename);
|
||||
~shader();
|
||||
|
||||
private:
|
||||
void expand_includes(std::string &str);
|
||||
std::string read_file(const std::string &filename);
|
||||
};
|
||||
|
||||
class program : public object, public bindable<program>
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
|
||||
void gl::program_mvp::init()
|
||||
{
|
||||
glUniformBlockBinding(*this, 0, glGetUniformBlockIndex(*this, "scene_ubo"));
|
||||
glUniformBlockBinding(*this, 1, glGetUniformBlockIndex(*this, "model_ubo"));
|
||||
GLuint index;
|
||||
|
||||
if ((index = glGetUniformBlockIndex(*this, "scene_ubo")) != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(*this, 0, index);
|
||||
|
||||
if ((index = glGetUniformBlockIndex(*this, "model_ubo")) != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(*this, 1, index);
|
||||
|
||||
if ((index = glGetUniformBlockIndex(*this, "light_ubo")) != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(*this, 2, index);
|
||||
}
|
||||
|
||||
72
gl/ubo.h
72
gl/ubo.h
@@ -2,7 +2,6 @@
|
||||
#include "bindable.h"
|
||||
|
||||
#define UBS_PAD(x) uint64_t : x * 4; uint64_t : x * 4;
|
||||
#define DEFINE_UBS(x, y) _Pragma("pack(push, 1)"); struct x y; _Pragma("pack(pop)")
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@@ -20,29 +19,82 @@ namespace gl
|
||||
void update(void *data, int offset, int size);
|
||||
};
|
||||
|
||||
// layout std140
|
||||
// structs must match with GLSL
|
||||
// ordered to minimize padding
|
||||
|
||||
_Pragma("pack(push, 1)")
|
||||
|
||||
struct scene_ubs
|
||||
{
|
||||
glm::mat4 projection;
|
||||
|
||||
void set(const glm::mat4 &m)
|
||||
{
|
||||
projection = m;
|
||||
}
|
||||
glm::mat4 lightview;
|
||||
float time;
|
||||
};
|
||||
|
||||
static_assert(sizeof(scene_ubs) == 132, "bad size of ubs");
|
||||
|
||||
const size_t MAX_PARAMS = 3;
|
||||
|
||||
struct model_ubs
|
||||
{
|
||||
glm::mat4 modelview;
|
||||
glm::mat4 modelviewnormal;
|
||||
glm::mat3x4 modelviewnormal;
|
||||
glm::vec4 param[MAX_PARAMS];
|
||||
|
||||
void set(const glm::mat4 &m)
|
||||
glm::vec3 velocity;
|
||||
float opacity;
|
||||
float emission;
|
||||
|
||||
void set_modelview(const glm::mat4 &mv)
|
||||
{
|
||||
modelview = m;
|
||||
modelviewnormal = glm::mat3(glm::transpose(glm::inverse(m)));
|
||||
modelview = mv;
|
||||
modelviewnormal = glm::mat3(glm::transpose(glm::inverse(mv)));
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(model_ubs) == 156 + 8 * MAX_PARAMS, "bad size of ubs");
|
||||
|
||||
struct light_element_ubs
|
||||
{
|
||||
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;
|
||||
|
||||
UBS_PAD(8);
|
||||
};
|
||||
|
||||
static_assert(sizeof(light_element_ubs) == 64, "bad size of ubs");
|
||||
|
||||
const size_t MAX_LIGHTS = 16;
|
||||
|
||||
struct light_ubs
|
||||
{
|
||||
glm::vec3 ambient;
|
||||
float fog_density;
|
||||
|
||||
glm::vec3 fog_color;
|
||||
uint32_t lights_count;
|
||||
|
||||
light_element_ubs lights[MAX_LIGHTS];
|
||||
};
|
||||
|
||||
static_assert(sizeof(light_ubs) == 32 + sizeof(light_element_ubs) * MAX_LIGHTS, "bad size of ubs");
|
||||
|
||||
_Pragma("pack(pop)")
|
||||
}
|
||||
|
||||
189
lua_ffi.h
189
lua_ffi.h
@@ -1,93 +1,96 @@
|
||||
const char lua_ffi[] = "local ffi = require(\"ffi\")\n"
|
||||
"ffi.cdef[[\n"
|
||||
"struct memcell_values { const char *str; double num1; double num2; };\n"
|
||||
"\n"
|
||||
"typedef struct TEvent TEvent;\n"
|
||||
"typedef struct TTrack TTrack;\n"
|
||||
"typedef struct TIsolated TIsolated;\n"
|
||||
"typedef struct TDynamicObject TDynamicObject;\n"
|
||||
"typedef struct TMemCell TMemCell;\n"
|
||||
"typedef struct memcell_values memcell_values;\n"
|
||||
"\n"
|
||||
"TEvent* scriptapi_event_create(const char* name, double delay, double randomdelay, void (*handler)(TEvent*, TDynamicObject*));\n"
|
||||
"TEvent* scriptapi_event_find(const char* name);\n"
|
||||
"const char* scriptapi_event_getname(TEvent *e);\n"
|
||||
"void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator, double delay);\n"
|
||||
"\n"
|
||||
"TTrack* scriptapi_track_find(const char* name);\n"
|
||||
"bool scriptapi_track_isoccupied(TTrack *track);\n"
|
||||
"\n"
|
||||
"TIsolated* scriptapi_isolated_find(const char* name);\n"
|
||||
"bool scriptapi_isolated_isoccupied(TIsolated *isolated);\n"
|
||||
"\n"
|
||||
"const char* scriptapi_train_getname(TDynamicObject *dyn);\n"
|
||||
"void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2);\n"
|
||||
"\n"
|
||||
"TMemCell* scriptapi_memcell_find(const char *name);\n"
|
||||
"memcell_values scriptapi_memcell_read(TMemCell *mc);\n"
|
||||
"void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2);\n"
|
||||
"\n"
|
||||
"double scriptapi_random(double a, double b);\n"
|
||||
"void scriptapi_writelog(const char* txt);\n"
|
||||
"void scriptapi_writeerrorlog(const char* txt);\n"
|
||||
"]]\n"
|
||||
"\n"
|
||||
"local ns = ffi.C\n"
|
||||
"\n"
|
||||
"local module = {}\n"
|
||||
"\n"
|
||||
"module.event_create = ns.scriptapi_event_create\n"
|
||||
"function module.event_preparefunc(f)\n"
|
||||
" return ffi.cast(\"void (*)(TEvent*, TDynamicObject*)\", f)\n"
|
||||
"end\n"
|
||||
"module.event_find = ns.scriptapi_event_find\n"
|
||||
"function module.event_getname(a)\n"
|
||||
" return ffi.string(ns.scriptapi_event_getname(a))\n"
|
||||
"end\n"
|
||||
"module.event_dispatch = ns.scriptapi_event_dispatch\n"
|
||||
"function module.event_dispatch_n(a, b, c)\n"
|
||||
" ns.scriptapi_event_dispatch(ns.scriptapi_event_find(a), b, c)\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"module.track_find = ns.scriptapi_track_find\n"
|
||||
"module.track_isoccupied = ns.scriptapi_track_isoccupied\n"
|
||||
"function module.track_isoccupied_n(a)\n"
|
||||
" return ns.scriptapi_track_isoccupied(ns.scriptapi_track_find(a))\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"module.isolated_find = ns.scriptapi_isolated_find\n"
|
||||
"module.isolated_isoccupied = ns.scriptapi_isolated_isoccupied\n"
|
||||
"function module.isolated_isoccupied_n(a)\n"
|
||||
" return ns.scriptapi_isolated_isoccupied(ns.scriptapi_isolated_find(a))\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"function module.train_getname(a)\n"
|
||||
" return ffi.string(ns.scriptapi_train_getname(a))\n"
|
||||
"end\n"
|
||||
"function module.dynobj_putvalues(a, b)\n"
|
||||
" ns.scriptapi_dynobj_putvalues(a, b.str, b.num1, b.num2)\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"module.memcell_find = ns.scriptapi_memcell_find\n"
|
||||
"function module.memcell_read(a)\n"
|
||||
" native = ns.scriptapi_memcell_read(a)\n"
|
||||
" mc = { }\n"
|
||||
" mc.str = ffi.string(native.str)\n"
|
||||
" mc.num1 = native.num1\n"
|
||||
" mc.num2 = native.num2\n"
|
||||
" return mc\n"
|
||||
"end\n"
|
||||
"function module.memcell_read_n(a)\n"
|
||||
" return module.memcell_read(ns.scriptapi_memcell_find(a))\n"
|
||||
"end\n"
|
||||
"function module.memcell_update(a, b)\n"
|
||||
" ns.scriptapi_memcell_update(a, b.str, b.num1, b.num2)\n"
|
||||
"end\n"
|
||||
"function module.memcell_update_n(a, b)\n"
|
||||
" ns.scriptapi_memcell_update(ns.scriptapi_memcell_find(a), b.str, b.num1, b.num2)\n"
|
||||
"end\n"
|
||||
"\n"
|
||||
"module.random = ns.scriptapi_random\n"
|
||||
"module.writelog = ns.scriptapi_writelog\n"
|
||||
"module.writeerrorlog = ns.scriptapi_writeerrorlog\n"
|
||||
"\nreturn module\n";
|
||||
const char lua_ffi[] = R"STRING(
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
struct memcell_values { const char *str; double num1; double num2; };
|
||||
|
||||
typedef struct TEvent TEvent;
|
||||
typedef struct TTrack TTrack;
|
||||
typedef struct TIsolated TIsolated;
|
||||
typedef struct TDynamicObject TDynamicObject;
|
||||
typedef struct TMemCell TMemCell;
|
||||
typedef struct memcell_values memcell_values;
|
||||
|
||||
TEvent* scriptapi_event_create(const char* name, double delay, double randomdelay, void (*handler)(TEvent*, TDynamicObject*));
|
||||
TEvent* scriptapi_event_find(const char* name);
|
||||
const char* scriptapi_event_getname(TEvent *e);
|
||||
void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator, double delay);
|
||||
|
||||
TTrack* scriptapi_track_find(const char* name);
|
||||
bool scriptapi_track_isoccupied(TTrack *track);
|
||||
|
||||
TIsolated* scriptapi_isolated_find(const char* name);
|
||||
bool scriptapi_isolated_isoccupied(TIsolated *isolated);
|
||||
|
||||
const char* scriptapi_train_getname(TDynamicObject *dyn);
|
||||
void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2);
|
||||
|
||||
TMemCell* scriptapi_memcell_find(const char *name);
|
||||
memcell_values scriptapi_memcell_read(TMemCell *mc);
|
||||
void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2);
|
||||
|
||||
double scriptapi_random(double a, double b);
|
||||
void scriptapi_writelog(const char* txt);
|
||||
void scriptapi_writeerrorlog(const char* txt);
|
||||
]]
|
||||
|
||||
local ns = ffi.C
|
||||
|
||||
local module = {}
|
||||
|
||||
module.event_create = ns.scriptapi_event_create
|
||||
function module.event_preparefunc(f)
|
||||
return ffi.cast("void (*)(TEvent*, TDynamicObject*)", f)
|
||||
end
|
||||
module.event_find = ns.scriptapi_event_find
|
||||
function module.event_getname(a)
|
||||
return ffi.string(ns.scriptapi_event_getname(a))
|
||||
end
|
||||
module.event_dispatch = ns.scriptapi_event_dispatch
|
||||
function module.event_dispatch_n(a, b, c)
|
||||
ns.scriptapi_event_dispatch(ns.scriptapi_event_find(a), b, c)
|
||||
end
|
||||
|
||||
module.track_find = ns.scriptapi_track_find
|
||||
module.track_isoccupied = ns.scriptapi_track_isoccupied
|
||||
function module.track_isoccupied_n(a)
|
||||
return ns.scriptapi_track_isoccupied(ns.scriptapi_track_find(a))
|
||||
end
|
||||
|
||||
module.isolated_find = ns.scriptapi_isolated_find
|
||||
module.isolated_isoccupied = ns.scriptapi_isolated_isoccupied
|
||||
function module.isolated_isoccupied_n(a)
|
||||
return ns.scriptapi_isolated_isoccupied(ns.scriptapi_isolated_find(a))
|
||||
end
|
||||
|
||||
function module.train_getname(a)
|
||||
return ffi.string(ns.scriptapi_train_getname(a))
|
||||
end
|
||||
function module.dynobj_putvalues(a, b)
|
||||
ns.scriptapi_dynobj_putvalues(a, b.str, b.num1, b.num2)
|
||||
end
|
||||
|
||||
module.memcell_find = ns.scriptapi_memcell_find
|
||||
function module.memcell_read(a)
|
||||
native = ns.scriptapi_memcell_read(a)
|
||||
mc = { }
|
||||
mc.str = ffi.string(native.str)
|
||||
mc.num1 = native.num1
|
||||
mc.num2 = native.num2
|
||||
return mc
|
||||
end
|
||||
function module.memcell_read_n(a)
|
||||
return module.memcell_read(ns.scriptapi_memcell_find(a))
|
||||
end
|
||||
function module.memcell_update(a, b)
|
||||
ns.scriptapi_memcell_update(a, b.str, b.num1, b.num2)
|
||||
end
|
||||
function module.memcell_update_n(a, b)
|
||||
ns.scriptapi_memcell_update(ns.scriptapi_memcell_find(a), b.str, b.num1, b.num2)
|
||||
end
|
||||
|
||||
module.random = ns.scriptapi_random
|
||||
module.writelog = ns.scriptapi_writelog
|
||||
module.writeerrorlog = ns.scriptapi_writeerrorlog
|
||||
|
||||
return module;
|
||||
)STRING";
|
||||
|
||||
56
material.cpp
56
material.cpp
@@ -22,11 +22,6 @@ opengl_material::deserialize( cParser &Input, bool const Loadnow ) {
|
||||
result = true; // once would suffice but, eh
|
||||
}
|
||||
|
||||
has_alpha = (
|
||||
texture1 != null_handle ?
|
||||
GfxRenderer.Texture( texture1 ).has_alpha :
|
||||
false );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -34,7 +29,7 @@ opengl_material::deserialize( cParser &Input, bool const Loadnow ) {
|
||||
bool
|
||||
opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow ) {
|
||||
// token can be a key or block end
|
||||
std::string const key { Input.getToken<std::string>( true, "\n\r\t ,;[]" ) };
|
||||
std::string key = Input.getToken<std::string>( true, "\n\r\t ,;[]" );
|
||||
|
||||
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
|
||||
|
||||
@@ -55,21 +50,28 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
|
||||
; // all work is done in the header
|
||||
}
|
||||
}
|
||||
else if( key == "texture1:" ) {
|
||||
if( ( texture1 == null_handle )
|
||||
|| ( Priority > priority1 ) ) {
|
||||
else if (key.compare(0, 7, "texture") == 0) {
|
||||
key.erase(0, 7);
|
||||
size_t num = std::stoi(key) - 1;
|
||||
if (num < textures.size() &&
|
||||
(textures[num] == null_handle || Priority > m_priority[num]))
|
||||
{
|
||||
std::replace(value.begin(), value.end(), '\\', '/');
|
||||
texture1 = GfxRenderer.Fetch_Texture( value, Loadnow );
|
||||
priority1 = Priority;
|
||||
textures[num] = GfxRenderer.Fetch_Texture( value, Loadnow );
|
||||
m_priority[num] = Priority;
|
||||
}
|
||||
}
|
||||
else if( key == "texture2:" ) {
|
||||
if( ( texture2 == null_handle )
|
||||
|| ( Priority > priority2 ) ) {
|
||||
std::replace(value.begin(), value.end(), '\\', '/');
|
||||
texture2 = GfxRenderer.Fetch_Texture( value, Loadnow );
|
||||
priority2 = Priority;
|
||||
}
|
||||
else if (key == "shader:" &&
|
||||
(!shader || Priority > m_priority[max_textures]))
|
||||
{
|
||||
shader = GfxRenderer.Fetch_Shader(value);
|
||||
m_priority[max_textures] = Priority;
|
||||
}
|
||||
else if (key == "opacity:" &&
|
||||
Priority > m_priority[max_textures + 1])
|
||||
{
|
||||
opacity = std::stoi(value); //m7t: handle exception
|
||||
m_priority[max_textures + 1] = Priority;
|
||||
}
|
||||
else if( value == "{" ) {
|
||||
// unrecognized or ignored token, but comes with attribute block and potential further nesting
|
||||
@@ -129,16 +131,26 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
||||
}
|
||||
else {
|
||||
// if there's no .mat file, this could be legacy method of referring just to diffuse texture directly, make a material out of it in such case
|
||||
material.texture1 = GfxRenderer.Fetch_Texture( Filename, Loadnow );
|
||||
if( material.texture1 == null_handle ) {
|
||||
material.textures[0] = GfxRenderer.Fetch_Texture( Filename, Loadnow );
|
||||
if( material.textures[0] == null_handle ) {
|
||||
// if there's also no texture, give up
|
||||
return null_handle;
|
||||
}
|
||||
// use texture path and name to tell the newly created materials apart
|
||||
filename = GfxRenderer.Texture( material.texture1 ).name;
|
||||
filename = GfxRenderer.Texture( material.textures[0] ).name;
|
||||
erase_extension( filename );
|
||||
material.name = filename;
|
||||
material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha;
|
||||
}
|
||||
|
||||
if (!material.shader)
|
||||
material.shader = GfxRenderer.Fetch_Shader("default");
|
||||
|
||||
if (std::isnan(material.opacity))
|
||||
{
|
||||
if (material.textures[0] != null_handle)
|
||||
material.opacity = GfxRenderer.Texture( material.textures[0] ).has_alpha ? 0.0f : 1.0f;
|
||||
else
|
||||
material.opacity = 1.0f;
|
||||
}
|
||||
|
||||
material_handle handle = m_materials.size();
|
||||
|
||||
18
material.h
18
material.h
@@ -11,18 +11,22 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "Classes.h"
|
||||
#include "Texture.h"
|
||||
#include "gl/shader.h"
|
||||
|
||||
typedef int material_handle;
|
||||
|
||||
// a collection of parameters for the rendering setup.
|
||||
// for modern opengl this translates to set of attributes for the active shaders,
|
||||
// for legacy opengl this is basically just texture(s) assigned to geometry
|
||||
// for modern opengl this translates to set of attributes for shaders
|
||||
struct opengl_material {
|
||||
static const size_t max_textures = 2;
|
||||
|
||||
texture_handle texture1 { null_handle }; // primary texture, typically diffuse+apha
|
||||
texture_handle texture2 { null_handle }; // secondary texture, typically normal+reflection
|
||||
// primary texture, typically diffuse+apha
|
||||
// secondary texture, typically normal+reflection
|
||||
std::array<texture_handle, max_textures> textures = { null_handle };
|
||||
|
||||
std::shared_ptr<gl::program> shader;
|
||||
float opacity = std::numeric_limits<float>::quiet_NaN();
|
||||
|
||||
bool has_alpha { false }; // alpha state, calculated from presence of alpha in texture1
|
||||
std::string name;
|
||||
|
||||
// constructors
|
||||
@@ -39,8 +43,8 @@ private:
|
||||
deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow );
|
||||
|
||||
// members
|
||||
int priority1 { -1 }; // priority of last loaded primary texture
|
||||
int priority2 { -1 }; // priority of last loaded secondary texture
|
||||
// priorities for textures, shader, opacity
|
||||
std::array<int, max_textures + 2> m_priority = { -1 };
|
||||
};
|
||||
|
||||
class material_manager {
|
||||
|
||||
@@ -46,6 +46,104 @@ basic_vertex::deserialize( std::istream &s ) {
|
||||
texture.y = sn_utils::ld_float32( s );
|
||||
}
|
||||
|
||||
// based on
|
||||
// Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”.
|
||||
// Terathon Software, 2001. http://terathon.com/code/tangent.html
|
||||
void calculate_tangent(vertex_array &vertices, int type)
|
||||
{
|
||||
size_t vertex_count = vertices.size();
|
||||
|
||||
if (!vertex_count || vertices[0].tangent.w != 0.0f)
|
||||
return;
|
||||
|
||||
size_t triangle_count;
|
||||
if (type == GL_TRIANGLES)
|
||||
triangle_count = vertex_count / 3;
|
||||
else if (type == GL_TRIANGLE_STRIP)
|
||||
triangle_count = vertex_count - 2;
|
||||
else if (type == GL_TRIANGLE_FAN)
|
||||
triangle_count = vertex_count - 2;
|
||||
else
|
||||
return;
|
||||
|
||||
std::vector<glm::vec3> tan(vertex_count * 2);
|
||||
|
||||
for (size_t a = 0; a < triangle_count; a++)
|
||||
{
|
||||
size_t i1, i2, i3;
|
||||
if (type == GL_TRIANGLES)
|
||||
{
|
||||
i1 = a * 3;
|
||||
i2 = a * 3 + 1;
|
||||
i3 = a * 3 + 2;
|
||||
}
|
||||
else if (type == GL_TRIANGLE_STRIP)
|
||||
{
|
||||
if (a % 2 == 0)
|
||||
{
|
||||
i1 = a;
|
||||
i2 = a + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i1 = a + 1;
|
||||
i2 = a;
|
||||
}
|
||||
i3 = a + 2;
|
||||
}
|
||||
else if (type == GL_TRIANGLE_FAN)
|
||||
{
|
||||
i1 = 0;
|
||||
i2 = a + 1;
|
||||
i3 = a + 2;
|
||||
}
|
||||
|
||||
const glm::vec3 &v1 = vertices[i1].position;
|
||||
const glm::vec3 &v2 = vertices[i2].position;
|
||||
const glm::vec3 &v3 = vertices[i3].position;
|
||||
|
||||
const glm::vec2 &w1 = vertices[i1].texture;
|
||||
const glm::vec2 &w2 = vertices[i2].texture;
|
||||
const glm::vec2 &w3 = vertices[i3].texture;
|
||||
|
||||
float x1 = v2.x - v1.x;
|
||||
float x2 = v3.x - v1.x;
|
||||
float y1 = v2.y - v1.y;
|
||||
float y2 = v3.y - v1.y;
|
||||
float z1 = v2.z - v1.z;
|
||||
float z2 = v3.z - v1.z;
|
||||
|
||||
float s1 = w2.x - w1.x;
|
||||
float s2 = w3.x - w1.x;
|
||||
float t1 = w2.y - w1.y;
|
||||
float t2 = w3.y - w1.y;
|
||||
|
||||
float r = 1.0F / (s1 * t2 - s2 * t1);
|
||||
glm::vec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||
(t2 * z1 - t1 * z2) * r);
|
||||
glm::vec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||
(s1 * z2 - s2 * z1) * r);
|
||||
|
||||
tan[i1] += sdir;
|
||||
tan[i2] += sdir;
|
||||
tan[i3] += sdir;
|
||||
|
||||
tan[vertex_count + i1] += tdir;
|
||||
tan[vertex_count + i2] += tdir;
|
||||
tan[vertex_count + i3] += tdir;
|
||||
}
|
||||
|
||||
for (size_t a = 0; a < vertex_count; a++)
|
||||
{
|
||||
const glm::vec3 &n = vertices[a].normal;
|
||||
const glm::vec3 &t = tan[a];
|
||||
const glm::vec3 &t2 = tan[vertex_count + a];
|
||||
|
||||
vertices[a].tangent = glm::vec4(glm::normalize((t - n * glm::dot(n, t))),
|
||||
(glm::dot(glm::cross(n, t), t2) < 0.0F) ? -1.0F : 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
||||
|
||||
// creates a new geometry chunk of specified type from supplied vertex data. returns: handle to the chunk
|
||||
@@ -100,9 +198,9 @@ geometry_bank::append( gfx::vertex_array &Vertices, gfx::geometry_handle const &
|
||||
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
geometry_bank::draw( gfx::geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
geometry_bank::draw( gfx::geometry_handle const &Geometry ) {
|
||||
// template method implementation
|
||||
draw_( Geometry, Streams );
|
||||
draw_( Geometry );
|
||||
}
|
||||
|
||||
// frees subclass-specific resources associated with the bank, typically called when the bank wasn't in use for a period of time
|
||||
@@ -145,7 +243,7 @@ opengl_vbogeometrybank::replace_( gfx::geometry_handle const &Geometry ) {
|
||||
|
||||
// draw() subclass details
|
||||
void
|
||||
opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry) {
|
||||
|
||||
if( m_buffer == 0 ) {
|
||||
// if there's no buffer, we'll have to make one
|
||||
@@ -193,17 +291,11 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, unsigned in
|
||||
m_vao = std::make_unique<gl::vao>();
|
||||
glBindBuffer( GL_ARRAY_BUFFER, m_buffer );
|
||||
|
||||
if( Streams & gfx::stream::position )
|
||||
m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(basic_vertex), 0 * sizeof(GL_FLOAT));
|
||||
|
||||
// NOTE: normal and color streams share the data, making them effectively mutually exclusive
|
||||
if( Streams & gfx::stream::normal )
|
||||
m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(basic_vertex), 3 * sizeof(GL_FLOAT));
|
||||
else if( Streams & gfx::stream::color )
|
||||
m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(basic_vertex), 3 * sizeof(GL_FLOAT));
|
||||
|
||||
if( Streams & gfx::stream::texture )
|
||||
m_vao->setup_attrib(2, 2, GL_FLOAT, sizeof(basic_vertex), 6 * sizeof(GL_FLOAT));
|
||||
m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(basic_vertex), 0 * sizeof(GL_FLOAT));
|
||||
// NOTE: normal and color streams share the data
|
||||
m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(basic_vertex), 3 * sizeof(GL_FLOAT));
|
||||
m_vao->setup_attrib(2, 2, GL_FLOAT, sizeof(basic_vertex), 6 * sizeof(GL_FLOAT));
|
||||
m_vao->setup_attrib(3, 4, GL_FLOAT, sizeof(basic_vertex), 8 * sizeof(GL_FLOAT));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
m_vao->unbind();
|
||||
@@ -271,7 +363,6 @@ geometrybank_manager::create_bank() {
|
||||
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||
gfx::geometry_handle
|
||||
geometrybank_manager::create_chunk( gfx::vertex_array const &Vertices, gfx::geometrybank_handle const &Geometry, int const Type ) {
|
||||
|
||||
auto const newchunkhandle = bank( Geometry ).first->create( Vertices, Type );
|
||||
|
||||
if( newchunkhandle.chunk != 0 ) { return { Geometry.bank, newchunkhandle.chunk }; }
|
||||
@@ -293,14 +384,14 @@ geometrybank_manager::append( gfx::vertex_array &Vertices, gfx::geometry_handle
|
||||
}
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
geometrybank_manager::draw( gfx::geometry_handle const &Geometry, unsigned int const Streams ) {
|
||||
geometrybank_manager::draw( gfx::geometry_handle const &Geometry ) {
|
||||
|
||||
if( Geometry == null_handle ) { return; }
|
||||
|
||||
auto &bankrecord = bank( Geometry );
|
||||
|
||||
bankrecord.second = m_garbagecollector.timestamp();
|
||||
bankrecord.first->draw( Geometry, Streams );
|
||||
bankrecord.first->draw( Geometry );
|
||||
}
|
||||
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
|
||||
@@ -26,6 +26,7 @@ struct basic_vertex {
|
||||
glm::vec3 position; // 3d space
|
||||
glm::vec3 normal; // 3d space
|
||||
glm::vec2 texture; // uv space
|
||||
glm::vec4 tangent; // xyz - tangent, w - handedness
|
||||
|
||||
basic_vertex() = default;
|
||||
basic_vertex( glm::vec3 Position, glm::vec3 Normal, glm::vec2 Texture ) :
|
||||
@@ -35,19 +36,10 @@ struct basic_vertex {
|
||||
void deserialize( std::istream& );
|
||||
};
|
||||
|
||||
// data streams carried in a vertex
|
||||
enum stream {
|
||||
none = 0x0,
|
||||
position = 0x1,
|
||||
normal = 0x2,
|
||||
color = 0x4, // currently normal and colour streams are stored in the same slot, and mutually exclusive
|
||||
texture = 0x8
|
||||
};
|
||||
|
||||
unsigned int const basic_streams { stream::position | stream::normal | stream::texture };
|
||||
unsigned int const color_streams { stream::position | stream::color | stream::texture };
|
||||
typedef std::vector<basic_vertex> vertex_array;
|
||||
|
||||
void calculate_tangent(vertex_array &vertices, int type);
|
||||
|
||||
// generic geometry bank class, allows storage, update and drawing of geometry chunks
|
||||
|
||||
struct geometry_handle {
|
||||
@@ -100,11 +92,11 @@ public:
|
||||
append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry );
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
draw( gfx::geometry_handle const &Geometry, unsigned int const Streams = basic_streams );
|
||||
draw( gfx::geometry_handle const &Geometry );
|
||||
// draws geometry stored in supplied list of chunks
|
||||
template <typename Iterator_>
|
||||
void
|
||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) { while( First != Last ) { draw( *First, Streams ); ++First; } }
|
||||
draw( Iterator_ First, Iterator_ Last ) { while( First != Last ) { draw( *First ); ++First; } }
|
||||
// frees subclass-specific resources associated with the bank, typically called when the bank wasn't in use for a period of time
|
||||
void
|
||||
release();
|
||||
@@ -146,7 +138,7 @@ private:
|
||||
// replace() subclass details
|
||||
virtual void replace_( gfx::geometry_handle const &Geometry ) = 0;
|
||||
// draw() subclass details
|
||||
virtual void draw_( gfx::geometry_handle const &Geometry, unsigned int const Streams ) = 0;
|
||||
virtual void draw_( gfx::geometry_handle const &Geometry ) = 0;
|
||||
// resource release subclass details
|
||||
virtual void release_() = 0;
|
||||
};
|
||||
@@ -185,7 +177,7 @@ private:
|
||||
replace_( gfx::geometry_handle const &Geometry );
|
||||
// draw() subclass details
|
||||
void
|
||||
draw_( gfx::geometry_handle const &Geometry, unsigned int const Streams );
|
||||
draw_( gfx::geometry_handle const &Geometry );
|
||||
// release() subclass details
|
||||
void
|
||||
release_();
|
||||
@@ -224,12 +216,12 @@ public:
|
||||
append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry );
|
||||
// draws geometry stored in specified chunk
|
||||
void
|
||||
draw( gfx::geometry_handle const &Geometry, unsigned int const Streams = basic_streams );
|
||||
draw( gfx::geometry_handle const &Geometry);
|
||||
template <typename Iterator_>
|
||||
void
|
||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
||||
draw( Iterator_ First, Iterator_ Last ) {
|
||||
while( First != Last ) {
|
||||
draw( *First, Streams );
|
||||
draw( *First );
|
||||
++First; } }
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
gfx::vertex_array const &
|
||||
|
||||
337
renderer.cpp
337
renderer.cpp
@@ -27,12 +27,11 @@ int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental
|
||||
|
||||
void
|
||||
opengl_light::apply_intensity( float const Factor ) {
|
||||
// m7t setup light ubo here
|
||||
factor = Factor;
|
||||
}
|
||||
|
||||
void
|
||||
opengl_light::apply_angle() {
|
||||
// m7t setup light ubo here
|
||||
}
|
||||
|
||||
void
|
||||
@@ -100,18 +99,11 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
glFrontFace( GL_CCW );
|
||||
glEnable( GL_CULL_FACE );
|
||||
|
||||
m_textures.assign_units( m_helpertextureunit, m_shadowtextureunit, m_normaltextureunit, m_diffusetextureunit ); // TODO: add reflections unit
|
||||
UILayer.set_unit( m_diffusetextureunit );
|
||||
select_unit( m_diffusetextureunit );
|
||||
|
||||
glDepthFunc( GL_LEQUAL );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glEnable( GL_BLEND );
|
||||
|
||||
glLineWidth( 1.0f );
|
||||
glPointSize( 3.0f );
|
||||
|
||||
if( true == Global.ScaleSpecularValues ) {
|
||||
m_specularopaquescalefactor = 0.25f;
|
||||
m_speculartranslucentscalefactor = 1.5f;
|
||||
@@ -132,8 +124,6 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
|
||||
light.is_directional = false;
|
||||
|
||||
//m7t config light ubo here
|
||||
|
||||
m_lights.emplace_back( light );
|
||||
}
|
||||
// preload some common textures
|
||||
@@ -141,9 +131,6 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
m_glaretexture = Fetch_Texture( "fx/lightglare" );
|
||||
m_suntexture = Fetch_Texture( "fx/sun" );
|
||||
m_moontexture = Fetch_Texture( "fx/moon" );
|
||||
if( m_helpertextureunit >= 0 ) {
|
||||
m_reflectiontexture = Fetch_Texture( "fx/reflections" );
|
||||
}
|
||||
WriteLog( "...gfx data pre-loading done" );
|
||||
|
||||
// prepare basic geometry chunks
|
||||
@@ -157,13 +144,30 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
{ { size, -size, 0.f }, glm::vec3(), { 0.f, 0.f } } },
|
||||
geometrybank, GL_TRIANGLE_STRIP );
|
||||
|
||||
gl::shader vert("shaders/simple.vert");
|
||||
gl::shader frag("shaders/simple.frag");
|
||||
shader = std::make_unique<gl::program_mvp>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||
shader->init();
|
||||
|
||||
m_vertex_shader = std::make_unique<gl::shader>("simple.vert");
|
||||
scene_ubo = std::make_unique<gl::ubo>(sizeof(gl::scene_ubs), 0);
|
||||
model_ubo = std::make_unique<gl::ubo>(sizeof(gl::model_ubs), 1);
|
||||
light_ubo = std::make_unique<gl::ubo>(sizeof(gl::light_ubs), 2);
|
||||
memset(&light_ubs, 0, sizeof(light_ubs));
|
||||
|
||||
// m7t: tbd: plug into material system?
|
||||
{
|
||||
gl::shader vert("traction.vert");
|
||||
gl::shader frag("traction.frag");
|
||||
gl::program *prog = new gl::program_mvp({vert, frag});
|
||||
prog->init();
|
||||
m_line_shader = std::unique_ptr<gl::program>(prog);
|
||||
}
|
||||
|
||||
{
|
||||
gl::shader vert("freespot.vert");
|
||||
gl::shader frag("freespot.frag");
|
||||
gl::program *prog = new gl::program_mvp({vert, frag});
|
||||
prog->init();
|
||||
m_freespot_shader = std::unique_ptr<gl::program>(prog);
|
||||
}
|
||||
|
||||
m_invalid_material = Fetch_Material("invalid");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -268,17 +272,21 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
setup_matrices();
|
||||
// render
|
||||
setup_drawing( true );
|
||||
setup_units( true, false, false );
|
||||
|
||||
glDebug("render environment");
|
||||
|
||||
scene_ubs.time = Timer::GetTime();
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
Render( &World.Environment );
|
||||
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
// opaque parts...
|
||||
setup_drawing( false );
|
||||
setup_units( true, true, true );
|
||||
shader->bind();
|
||||
|
||||
if( false == FreeFlyModeFlag ) {
|
||||
glDebug("render cab opaque");
|
||||
switch_units( true, true, false );
|
||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const shadowcolor { m_shadowcolor };
|
||||
@@ -293,7 +301,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
}
|
||||
|
||||
glDebug("render opaque region");
|
||||
switch_units( true, true, true );
|
||||
setup_shadow_map( m_shadowtexture, m_shadowtexturematrix );
|
||||
Render( simulation::Region );
|
||||
|
||||
@@ -304,7 +311,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
if( false == FreeFlyModeFlag ) {
|
||||
glDebug("render translucent cab");
|
||||
// cab render is performed without shadows, due to low resolution and number of models without windows :|
|
||||
switch_units( true, true, false );
|
||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const shadowcolor{ m_shadowcolor };
|
||||
@@ -318,8 +324,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
}
|
||||
}
|
||||
|
||||
shader->unbind();
|
||||
|
||||
/*
|
||||
if( m_environmentcubetexturesupport ) {
|
||||
// restore default texture matrix for reflections cube map
|
||||
select_unit( m_helpertextureunit );
|
||||
@@ -328,6 +333,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
select_unit( m_diffusetextureunit );
|
||||
::glMatrixMode( GL_MODELVIEW );
|
||||
}
|
||||
*/
|
||||
|
||||
glDebug("color pass done");
|
||||
}
|
||||
@@ -438,6 +444,7 @@ opengl_renderer::setup_matrices() {
|
||||
::glMatrixMode( GL_PROJECTION );
|
||||
OpenGLMatrices.load_matrix( m_renderpass.camera.projection() );
|
||||
|
||||
/*
|
||||
if( ( m_renderpass.draw_mode == rendermode::color )
|
||||
&& ( m_environmentcubetexturesupport ) ) {
|
||||
// special case, for colour render pass setup texture matrix for reflections cube map
|
||||
@@ -447,6 +454,7 @@ opengl_renderer::setup_matrices() {
|
||||
::glMultMatrixf( glm::value_ptr( glm::inverse( glm::mat4{ glm::mat3{ m_renderpass.camera.modelview() } } ) ) );
|
||||
select_unit( m_diffusetextureunit );
|
||||
}
|
||||
*/
|
||||
|
||||
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space
|
||||
::glMatrixMode( GL_MODELVIEW );
|
||||
@@ -484,42 +492,12 @@ opengl_renderer::setup_drawing( bool const Alpha ) {
|
||||
}
|
||||
}
|
||||
|
||||
// configures, enables and disables specified texture units
|
||||
void
|
||||
opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const Reflections ) {
|
||||
// diffuse texture unit.
|
||||
// NOTE: diffuse texture mapping is never fully disabled, alpha channel information is always included
|
||||
select_unit( m_diffusetextureunit );
|
||||
|
||||
// update unit state
|
||||
m_unitstate.diffuse = Diffuse;
|
||||
m_unitstate.shadows = Shadows;
|
||||
m_unitstate.reflections = Reflections;
|
||||
}
|
||||
|
||||
// configures shadow texture unit for specified shadow map and conersion matrix
|
||||
void
|
||||
opengl_renderer::setup_shadow_map( GLuint const Texture, glm::mat4 const &Transformation ) {
|
||||
|
||||
}
|
||||
|
||||
// enables and disables specified texture units
|
||||
void
|
||||
opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool const Reflections ) {
|
||||
// diffuse texture unit.
|
||||
// NOTE: toggle actually disables diffuse texture mapping, unlike setup counterpart
|
||||
if( true == Diffuse ) {
|
||||
select_unit( m_diffusetextureunit );
|
||||
}
|
||||
else {
|
||||
select_unit( m_diffusetextureunit );
|
||||
}
|
||||
// update unit state
|
||||
m_unitstate.diffuse = Diffuse;
|
||||
m_unitstate.shadows = Shadows;
|
||||
m_unitstate.reflections = Reflections;
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::setup_shadow_color( glm::vec4 const &Shadowcolor ) {
|
||||
}
|
||||
@@ -577,10 +555,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
::glDepthMask( GL_FALSE );
|
||||
::glPushMatrix();
|
||||
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
// skydome
|
||||
@@ -590,12 +565,9 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
|
||||
//m7t: restore celestial bodies
|
||||
|
||||
shader->bind();
|
||||
|
||||
// clouds
|
||||
if( Environment->m_clouds.mdCloud ) {
|
||||
// setup
|
||||
Disable_Lights();
|
||||
//m7t set cloud color
|
||||
// render
|
||||
Render( Environment->m_clouds.mdCloud, nullptr, 100.0 );
|
||||
@@ -624,20 +596,23 @@ opengl_renderer::Create_Bank() {
|
||||
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
|
||||
gfx::geometry_handle
|
||||
opengl_renderer::Insert( gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type ) {
|
||||
gfx::calculate_tangent(Vertices, Type);
|
||||
|
||||
return m_geometry.create_chunk( Vertices, Geometry, Type );
|
||||
}
|
||||
|
||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||
bool
|
||||
opengl_renderer::Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, std::size_t const Offset ) {
|
||||
opengl_renderer::Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type, std::size_t const Offset ) {
|
||||
gfx::calculate_tangent(Vertices, Type);
|
||||
|
||||
return m_geometry.replace( Vertices, Geometry, Offset );
|
||||
}
|
||||
|
||||
// adds supplied vertex data at the end of specified chunk
|
||||
bool
|
||||
opengl_renderer::Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry ) {
|
||||
opengl_renderer::Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type ) {
|
||||
gfx::calculate_tangent(Vertices, Type);
|
||||
|
||||
return m_geometry.append( Vertices, Geometry );
|
||||
}
|
||||
@@ -656,14 +631,40 @@ opengl_renderer::Fetch_Material( std::string const &Filename, bool const Loadnow
|
||||
return m_materials.create( Filename, Loadnow );
|
||||
}
|
||||
|
||||
std::shared_ptr<gl::program>
|
||||
opengl_renderer::Fetch_Shader(const std::string &name)
|
||||
{
|
||||
auto it = m_shaders.find(name);
|
||||
if (it == m_shaders.end())
|
||||
{
|
||||
gl::shader fragment("mat_" + name + ".frag");
|
||||
gl::program *program = new gl::program_mvp({ fragment, *m_vertex_shader.get() });
|
||||
program->init();
|
||||
m_shaders.insert({name, std::shared_ptr<gl::program>(program)});
|
||||
}
|
||||
|
||||
return m_shaders[name];
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Bind_Material( material_handle const Material ) {
|
||||
|
||||
auto const &material = m_materials.material( Material );
|
||||
if( false == Global.BasicRenderer ) {
|
||||
m_textures.bind( textureunit::normals, material.texture2 );
|
||||
if (Material != null_handle)
|
||||
{
|
||||
auto &material = m_materials.material( Material );
|
||||
material.shader->bind();
|
||||
|
||||
size_t unit = 0;
|
||||
for (auto &tex : material.textures)
|
||||
{
|
||||
if (tex == null_handle)
|
||||
break;
|
||||
m_textures.bind(unit, tex);
|
||||
unit++;
|
||||
}
|
||||
}
|
||||
m_textures.bind( textureunit::diffuse, material.texture1 );
|
||||
else if (Material != m_invalid_material)
|
||||
Bind_Material(m_invalid_material);
|
||||
}
|
||||
|
||||
opengl_material const &
|
||||
@@ -672,13 +673,6 @@ opengl_renderer::Material( material_handle const Material ) const {
|
||||
return m_materials.material( Material );
|
||||
}
|
||||
|
||||
// texture methods
|
||||
void
|
||||
opengl_renderer::select_unit( GLint const Textureunit ) {
|
||||
|
||||
return m_textures.unit( Textureunit );
|
||||
}
|
||||
|
||||
texture_handle
|
||||
opengl_renderer::Fetch_Texture( std::string const &Filename, bool const Loadnow ) {
|
||||
|
||||
@@ -688,7 +682,7 @@ opengl_renderer::Fetch_Texture( std::string const &Filename, bool const Loadnow
|
||||
void
|
||||
opengl_renderer::Bind_Texture( texture_handle const Texture ) {
|
||||
|
||||
m_textures.bind( textureunit::diffuse, Texture );
|
||||
m_textures.bind( 0, Texture );
|
||||
}
|
||||
|
||||
opengl_texture const &
|
||||
@@ -937,10 +931,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange
|
||||
}
|
||||
}
|
||||
// render
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
m_geometry.draw( data.geometry );
|
||||
@@ -994,6 +985,7 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
glDebug("Render TDynamicObject");
|
||||
|
||||
Dynamic->renderme = m_renderpass.camera.visible( Dynamic );
|
||||
if( false == Dynamic->renderme ) {
|
||||
@@ -1206,6 +1198,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, float c
|
||||
|
||||
void
|
||||
opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
glDebug("Render TSubModel");
|
||||
|
||||
if( ( Submodel->iVisible )
|
||||
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
||||
@@ -1260,17 +1253,15 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// specular strength in legacy models is set uniformly to 150, 150, 150 so we scale it down for opaque elements
|
||||
|
||||
}
|
||||
|
||||
model_ubs.emission = 0;
|
||||
// ...luminance
|
||||
auto const unitstate = m_unitstate;
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
model_ubs.emission = Submodel->f4Emision.a;
|
||||
}
|
||||
|
||||
// main draw call
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
@@ -1328,7 +1319,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
if( lightlevel > 0.f ) {
|
||||
// material configuration:
|
||||
|
||||
Bind_Material( null_handle );
|
||||
::glEnable( GL_BLEND );
|
||||
|
||||
::glPushMatrix();
|
||||
@@ -1337,15 +1327,16 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
/*
|
||||
setup_shadow_color( colors::white );
|
||||
*/
|
||||
auto const unitstate = m_unitstate;
|
||||
switch_units( m_unitstate.diffuse, false, false );
|
||||
glPointSize( std::max( 3.f, 5.f * distancefactor * anglefactor ) * 2.0f );
|
||||
|
||||
// main draw call
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.param[0] = glm::vec4(glm::vec3(Submodel->f4Diffuse), 0.0f);
|
||||
model_ubs.param[1] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
model_ubs.emission = lightlevel * anglefactor;
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
model_ubs.emission = 0.0f;
|
||||
m_freespot_shader->bind();
|
||||
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
|
||||
@@ -1354,7 +1345,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
/*
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
*/
|
||||
switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
@@ -1377,13 +1367,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
Bind_Material( null_handle );
|
||||
|
||||
// main draw call
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
||||
//m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1422,10 +1409,7 @@ opengl_renderer::Render( TTrack *Track ) {
|
||||
++m_debugstats.paths;
|
||||
++m_debugstats.drawcalls;
|
||||
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
@@ -1473,10 +1457,7 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
||||
}
|
||||
}
|
||||
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
|
||||
// first pass, material 1
|
||||
@@ -1665,19 +1646,11 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
||||
::glPushMatrix();
|
||||
auto const originoffset { cell->m_area.center - m_renderpass.camera.position() };
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
if( !Global.bSmoothTraction ) {
|
||||
// na liniach kiepsko wygląda - robi gradient
|
||||
::glDisable( GL_LINE_SMOOTH );
|
||||
}
|
||||
Bind_Material( null_handle );
|
||||
// render
|
||||
for( auto *traction : cell->m_traction ) { Render_Alpha( traction ); }
|
||||
for( auto &lines : cell->m_lines ) { Render_Alpha( lines ); }
|
||||
// post-render cleanup
|
||||
::glLineWidth( 1.0 );
|
||||
if( !Global.bSmoothTraction ) {
|
||||
::glEnable( GL_LINE_SMOOTH );
|
||||
}
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
@@ -1720,6 +1693,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
||||
|
||||
void
|
||||
opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
glDebug("Render_Alpha TTraction");
|
||||
|
||||
double distancesquared;
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
@@ -1743,31 +1717,26 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
return;
|
||||
}
|
||||
// setup
|
||||
/*
|
||||
float const linealpha = static_cast<float>(
|
||||
std::min(
|
||||
1.25,
|
||||
5000 * Traction->WireThickness / ( distancesquared + 1.0 ) ) ); // zbyt grube nie są dobre
|
||||
::glLineWidth( linealpha );
|
||||
*/
|
||||
auto const distance { static_cast<float>( std::sqrt( distancesquared ) ) };
|
||||
auto const linealpha {
|
||||
20.f * Traction->WireThickness
|
||||
/ std::max(
|
||||
0.5f * Traction->radius() + 1.f,
|
||||
distance - ( 0.5f * Traction->radius() ) ) };
|
||||
::glLineWidth(
|
||||
clamp(
|
||||
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
|
||||
1.f, 1.5f ) );
|
||||
if (m_widelines_supported)
|
||||
glLineWidth(clamp(
|
||||
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
|
||||
1.f, 1.5f ) );
|
||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
// render
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.param[0] = glm::vec4(Traction->wire_color(), linealpha);
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
m_geometry.draw( Traction->m_geometry );
|
||||
m_line_shader->bind();
|
||||
|
||||
m_geometry.draw(Traction->m_geometry);
|
||||
|
||||
// debug data
|
||||
++m_debugstats.traction;
|
||||
++m_debugstats.drawcalls;
|
||||
@@ -1775,6 +1744,7 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
|
||||
void
|
||||
opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||
glDebug("Render_Alpha scene::lines_node");
|
||||
|
||||
auto const &data { Lines.data() };
|
||||
|
||||
@@ -1799,17 +1769,18 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||
0.5f * data.area.radius + 1.f,
|
||||
distance - ( 0.5f * data.area.radius ) ) :
|
||||
1.f ); // negative width means the lines are always opague
|
||||
::glLineWidth(
|
||||
clamp(
|
||||
0.5f * linealpha + data.line_width * data.area.radius / 1000.f,
|
||||
1.f, 8.f ) );
|
||||
// render
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
if (m_widelines_supported)
|
||||
glLineWidth(clamp(
|
||||
0.5f * linealpha + data.line_width * data.area.radius / 1000.f,
|
||||
1.f, 8.f ) );
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.param[0] = glm::vec4(glm::vec3(data.lighting.diffuse * m_sunlight.ambient), linealpha);
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
m_geometry.draw( data.geometry );
|
||||
m_line_shader->bind();
|
||||
|
||||
m_geometry.draw( data.geometry);
|
||||
|
||||
++m_debugstats.lines;
|
||||
++m_debugstats.drawcalls;
|
||||
}
|
||||
@@ -1975,21 +1946,16 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// ...colors...
|
||||
// m7t set material
|
||||
// ...luminance
|
||||
auto const unitstate = m_unitstate;
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
}
|
||||
|
||||
// main draw call
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
|
||||
@@ -2041,6 +2007,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
// reduce the glare in bright daylight
|
||||
glarelevel = clamp( glarelevel - static_cast<float>(Global.fLuminance), 0.f, 1.f );
|
||||
|
||||
/*
|
||||
if( glarelevel > 0.0f ) {
|
||||
Bind_Texture( m_glaretexture );
|
||||
::glDepthMask( GL_FALSE );
|
||||
@@ -2055,15 +2022,13 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
switch_units( unitstate.diffuse, false, false );
|
||||
|
||||
// main draw call
|
||||
scene_ubs.set(OpenGLMatrices.data(GL_PROJECTION));
|
||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
|
||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
||||
m_geometry.draw( m_billboardgeometry );
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2214,6 +2179,8 @@ opengl_renderer::info_stats() const {
|
||||
|
||||
void
|
||||
opengl_renderer::Update_Lights( light_array &Lights ) {
|
||||
glDebug("Update_Lights");
|
||||
|
||||
// arrange the light array from closest to farthest from current position of the camera
|
||||
auto const camera = m_renderpass.camera.position();
|
||||
std::sort(
|
||||
@@ -2230,6 +2197,9 @@ opengl_renderer::Update_Lights( light_array &Lights ) {
|
||||
if( count == 0 ) { return; }
|
||||
|
||||
auto renderlight = m_lights.begin();
|
||||
size_t light_i = 1;
|
||||
|
||||
glm::mat4 mv = OpenGLMatrices.data(GL_MODELVIEW);
|
||||
|
||||
for( auto const &scenelight : Lights.data ) {
|
||||
|
||||
@@ -2266,26 +2236,30 @@ opengl_renderer::Update_Lights( light_array &Lights ) {
|
||||
glm::max( glm::vec3{ colors::none }, scenelight.color * glm::vec3{ scenelight.intensity } - glm::vec3{ luminance } ),
|
||||
renderlight->ambient[ 3 ] };
|
||||
|
||||
//m7t fill light
|
||||
|
||||
renderlight->apply_intensity();
|
||||
renderlight->apply_angle();
|
||||
|
||||
gl::light_element_ubs *l = &light_ubs.lights[light_i];
|
||||
l->pos = mv * glm::vec4(renderlight->position, 1.0f);
|
||||
l->dir = mv * glm::vec4(renderlight->direction, 0.0f);
|
||||
l->type = gl::light_element_ubs::SPOT;
|
||||
l->in_cutoff = 0.906f;
|
||||
l->out_cutoff = 0.866f;
|
||||
l->color = renderlight->diffuse * renderlight->factor;
|
||||
l->linear = 0.007f;
|
||||
l->quadratic = 0.0002f;
|
||||
light_i++;
|
||||
|
||||
++renderlight;
|
||||
}
|
||||
|
||||
while( renderlight != m_lights.end() ) {
|
||||
// if we went through all scene lights and there's still opengl lights remaining, kill these
|
||||
++renderlight;
|
||||
}
|
||||
}
|
||||
light_ubs.ambient = m_sunlight.ambient * m_sunlight.factor;
|
||||
light_ubs.lights[0].type = gl::light_element_ubs::DIR;
|
||||
light_ubs.lights[0].dir = mv * glm::vec4(m_sunlight.direction, 0.0f);
|
||||
light_ubs.lights[0].color = m_sunlight.diffuse * m_sunlight.factor;
|
||||
light_ubs.lights_count = light_i;
|
||||
|
||||
void
|
||||
opengl_renderer::Disable_Lights() {
|
||||
|
||||
for( size_t idx = 0; idx < m_lights.size() + 1; ++idx ) {
|
||||
|
||||
}
|
||||
light_ubo->update(&light_ubs, 0, sizeof(light_ubs));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2330,40 +2304,19 @@ opengl_renderer::Init_caps() {
|
||||
m_shadowbuffersize = std::min( m_shadowbuffersize, texturesize );
|
||||
WriteLog( "Shadows map size capped at " + std::to_string( m_shadowbuffersize ) + " pixels" );
|
||||
}
|
||||
// cap the number of supported lights based on hardware
|
||||
{
|
||||
GLint maxlights;
|
||||
::glGetIntegerv( GL_MAX_LIGHTS, &maxlights );
|
||||
Global.DynamicLightCount = std::min( Global.DynamicLightCount, maxlights - 1 );
|
||||
WriteLog( "Dynamic light amount capped at " + std::to_string( Global.DynamicLightCount ) + " (" + std::to_string(maxlights) + " lights total supported by the gfx card)" );
|
||||
}
|
||||
// select renderer mode
|
||||
if( true == Global.BasicRenderer ) {
|
||||
WriteLog( "Basic renderer selected, shadow and reflection mapping will be disabled" );
|
||||
Global.RenderShadows = false;
|
||||
m_diffusetextureunit = GL_TEXTURE0;
|
||||
m_helpertextureunit = -1;
|
||||
m_shadowtextureunit = -1;
|
||||
m_normaltextureunit = -1;
|
||||
}
|
||||
else {
|
||||
GLint maxtextureunits;
|
||||
::glGetIntegerv( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureunits );
|
||||
if( maxtextureunits < 4 ) {
|
||||
WriteLog( "Less than 4 texture units, shadow and reflection mapping will be disabled" );
|
||||
Global.BasicRenderer = true;
|
||||
Global.RenderShadows = false;
|
||||
m_diffusetextureunit = GL_TEXTURE0;
|
||||
m_helpertextureunit = -1;
|
||||
m_shadowtextureunit = -1;
|
||||
m_normaltextureunit = -1;
|
||||
}
|
||||
}
|
||||
Global.DynamicLightCount = std::min(Global.DynamicLightCount, 8);
|
||||
|
||||
if( Global.iMultisampling ) {
|
||||
WriteLog( "Using multisampling x" + std::to_string( 1 << Global.iMultisampling ) );
|
||||
}
|
||||
|
||||
glGetError();
|
||||
glLineWidth(2.0f);
|
||||
if (!glGetError())
|
||||
m_widelines_supported = true;
|
||||
else
|
||||
WriteLog("warning: wide lines not supported");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
54
renderer.h
54
renderer.h
@@ -32,6 +32,8 @@ struct opengl_light : public basic_light {
|
||||
|
||||
GLuint id { (GLuint)-1 };
|
||||
|
||||
float factor;
|
||||
|
||||
void
|
||||
apply_intensity( float const Factor = 1.0f );
|
||||
void
|
||||
@@ -138,10 +140,10 @@ public:
|
||||
Insert( gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type );
|
||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
||||
bool
|
||||
Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 );
|
||||
Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type, std::size_t const Offset = 0 );
|
||||
// adds supplied vertex data at the end of specified chunk
|
||||
bool
|
||||
Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry );
|
||||
Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type );
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
gfx::vertex_array const &
|
||||
Vertices( gfx::geometry_handle const &Geometry ) const;
|
||||
@@ -150,6 +152,10 @@ public:
|
||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true );
|
||||
void
|
||||
Bind_Material( material_handle const Material );
|
||||
|
||||
// shader methods
|
||||
std::shared_ptr<gl::program> Fetch_Shader(std::string const &name);
|
||||
|
||||
opengl_material const &
|
||||
Material( material_handle const Material ) const;
|
||||
// texture methods
|
||||
@@ -159,9 +165,6 @@ public:
|
||||
Bind_Texture( texture_handle const Texture );
|
||||
opengl_texture const &
|
||||
Texture( texture_handle const Texture ) const;
|
||||
// light methods
|
||||
void
|
||||
Disable_Lights();
|
||||
// utility methods
|
||||
TSubModel const *
|
||||
Pick_Control() const { return m_pickcontrolitem; }
|
||||
@@ -196,13 +199,6 @@ private:
|
||||
pickscenery
|
||||
};
|
||||
|
||||
enum textureunit {
|
||||
helper = 0,
|
||||
shadows,
|
||||
normals,
|
||||
diffuse
|
||||
};
|
||||
|
||||
struct debug_stats {
|
||||
int dynamics { 0 };
|
||||
int models { 0 };
|
||||
@@ -225,13 +221,6 @@ private:
|
||||
float draw_range { 0.0f };
|
||||
};
|
||||
|
||||
struct units_state {
|
||||
|
||||
bool diffuse { false };
|
||||
bool shadows { false };
|
||||
bool reflections { false };
|
||||
};
|
||||
|
||||
typedef std::vector<opengl_light> opengllight_array;
|
||||
|
||||
// methods
|
||||
@@ -243,19 +232,12 @@ private:
|
||||
setup_matrices();
|
||||
void
|
||||
setup_drawing( bool const Alpha = false );
|
||||
void
|
||||
setup_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
||||
void
|
||||
setup_shadow_map( GLuint const Texture, glm::mat4 const &Transformation );
|
||||
void
|
||||
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
||||
void
|
||||
setup_environment_light( TEnvironmentType const Environment = e_flat );
|
||||
void
|
||||
switch_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
||||
// helper, texture manager method; activates specified texture unit
|
||||
void
|
||||
select_unit( GLint const Textureunit );
|
||||
// runs jobs needed to generate graphics for specified render pass
|
||||
void
|
||||
Render_pass( rendermode const Mode );
|
||||
@@ -362,12 +344,6 @@ private:
|
||||
int m_environmentupdatetime { 0 }; // time of the most recent environment map update
|
||||
glm::dvec3 m_environmentupdatelocation; // coordinates of most recent environment map update
|
||||
|
||||
int m_helpertextureunit { GL_TEXTURE0 };
|
||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||
int m_normaltextureunit { GL_TEXTURE2 };
|
||||
int m_diffusetextureunit{ GL_TEXTURE3 };
|
||||
units_state m_unitstate;
|
||||
|
||||
unsigned int m_framestamp; // id of currently rendered gfx frame
|
||||
float m_framerate;
|
||||
double m_updateaccumulator { 0.0 };
|
||||
@@ -398,11 +374,23 @@ private:
|
||||
GLuint m_gltimequery = 0;
|
||||
GLuint64 m_gllasttime = 0;
|
||||
|
||||
std::unique_ptr<gl::program_mvp> shader;
|
||||
std::unique_ptr<gl::shader> m_vertex_shader;
|
||||
|
||||
std::unique_ptr<gl::ubo> scene_ubo;
|
||||
std::unique_ptr<gl::ubo> model_ubo;
|
||||
std::unique_ptr<gl::ubo> light_ubo;
|
||||
gl::scene_ubs scene_ubs;
|
||||
gl::model_ubs model_ubs;
|
||||
gl::light_ubs light_ubs;
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<gl::program>> m_shaders;
|
||||
|
||||
std::unique_ptr<gl::program> m_line_shader;
|
||||
std::unique_ptr<gl::program> m_freespot_shader;
|
||||
|
||||
material_handle m_invalid_material;
|
||||
|
||||
bool m_widelines_supported;
|
||||
};
|
||||
|
||||
extern opengl_renderer GfxRenderer;
|
||||
|
||||
@@ -194,7 +194,7 @@ shape_node::import( cParser &Input, scene::node_data const &Nodedata ) {
|
||||
// TBT, TODO: add methods to material manager to access these simpler
|
||||
auto const texturehandle = (
|
||||
m_data.material != null_handle ?
|
||||
GfxRenderer.Material( m_data.material ).texture1 :
|
||||
GfxRenderer.Material( m_data.material ).textures[0] :
|
||||
null_handle );
|
||||
auto const &texture = (
|
||||
texturehandle ?
|
||||
@@ -340,7 +340,7 @@ shape_node::convert( TSubModel const *Submodel ) {
|
||||
m_data.lighting.diffuse = Submodel->f4Diffuse;
|
||||
m_data.lighting.specular = Submodel->f4Specular;
|
||||
m_data.material = Submodel->m_material;
|
||||
m_data.translucent = ( true == GfxRenderer.Material( m_data.material ).has_alpha );
|
||||
m_data.translucent = ( true == GfxRenderer.Material( m_data.material ).opacity < 1.0f );
|
||||
// NOTE: we set unlimited view range typical for terrain, because we don't expect to convert any other 3d models
|
||||
m_data.rangesquared_max = std::numeric_limits<double>::max();
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
in vec3 f_color;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(f_color, 1.0f);
|
||||
|
||||
13
shaders/freespot.frag
Normal file
13
shaders/freespot.frag
Normal file
@@ -0,0 +1,13 @@
|
||||
#version 330
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
float x = (gl_PointCoord.x - 0.5f) * 2.0f;
|
||||
float y = (gl_PointCoord.y - 0.5f) * 2.0f;
|
||||
float dist2 = abs(x * x + y * y);
|
||||
if (dist2 > 0.5f * 0.5f)
|
||||
discard;
|
||||
gl_FragColor = param[0] * emission;
|
||||
}
|
||||
12
shaders/freespot.vert
Normal file
12
shaders/freespot.vert
Normal file
@@ -0,0 +1,12 @@
|
||||
#version 330
|
||||
|
||||
in vec3 v_vert;
|
||||
in vec3 v_normal;
|
||||
in vec2 v_coord;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
|
||||
}
|
||||
83
shaders/mat_default.frag
Normal file
83
shaders/mat_default.frag
Normal file
@@ -0,0 +1,83 @@
|
||||
#version 330
|
||||
|
||||
in vec3 f_normal;
|
||||
in vec2 f_coord;
|
||||
in vec3 f_pos;
|
||||
|
||||
#include <common>
|
||||
|
||||
uniform sampler2D tex1;
|
||||
|
||||
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);
|
||||
|
||||
return specular_v + diffuse_v;
|
||||
}
|
||||
|
||||
float calc_point_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(light.pos - f_pos);
|
||||
float val = calc_light(light_dir);
|
||||
|
||||
float distance = length(light.pos - f_pos);
|
||||
float atten = 1.0f / (1.0f + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
return val * atten;
|
||||
}
|
||||
|
||||
float calc_spot_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(light.pos - f_pos);
|
||||
|
||||
float theta = dot(light_dir, normalize(-light.dir));
|
||||
float epsilon = light.in_cutoff - light.out_cutoff;
|
||||
float intensity = clamp((theta - light.out_cutoff) / epsilon, 0.0, 1.0);
|
||||
|
||||
float point = calc_point_light(light);
|
||||
return point * intensity;
|
||||
}
|
||||
|
||||
float calc_dir_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(-light.dir);
|
||||
return calc_light(light_dir);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 result = ambient * 0.3 + param[0].rgb * emission;
|
||||
for (uint i = 0U; i < lights_count; i++)
|
||||
{
|
||||
light_s light = lights[i];
|
||||
float part = 0.0;
|
||||
|
||||
if (light.type == LIGHT_SPOT)
|
||||
part = calc_spot_light(light);
|
||||
else if (light.type == LIGHT_POINT)
|
||||
part = calc_point_light(light);
|
||||
else if (light.type == LIGHT_DIR)
|
||||
part = calc_dir_light(light);
|
||||
|
||||
result += light.color * part;
|
||||
}
|
||||
|
||||
vec4 tex_color = texture(tex1, f_coord);
|
||||
vec3 c = apply_fog(result * tex_color.xyz);
|
||||
gl_FragColor = vec4(c, tex_color.w);
|
||||
}
|
||||
8
shaders/mat_invalid.frag
Normal file
8
shaders/mat_invalid.frag
Normal file
@@ -0,0 +1,8 @@
|
||||
#version 330
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
15
shaders/mat_nolight.frag
Normal file
15
shaders/mat_nolight.frag
Normal file
@@ -0,0 +1,15 @@
|
||||
#version 330
|
||||
|
||||
in vec3 f_normal;
|
||||
in vec2 f_coord;
|
||||
in vec3 f_pos;
|
||||
|
||||
uniform sampler2D tex1;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = texture(tex1, f_coord);
|
||||
gl_FragColor = vec4(tex_color.xyz * ambient, tex_color.a);
|
||||
}
|
||||
91
shaders/mat_normal.frag
Normal file
91
shaders/mat_normal.frag
Normal file
@@ -0,0 +1,91 @@
|
||||
#version 330
|
||||
|
||||
in vec3 f_normal;
|
||||
in vec2 f_coord;
|
||||
in vec3 f_pos;
|
||||
in mat3 f_tbn;
|
||||
in vec4 f_tangent;
|
||||
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
|
||||
#include <common>
|
||||
|
||||
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 normal = f_tbn * normalize(texture(tex2, f_coord).rgb * 2.0 - 1.0);
|
||||
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) * 0.2;
|
||||
|
||||
return specular_v + diffuse_v;
|
||||
}
|
||||
|
||||
float calc_point_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(light.pos - f_pos);
|
||||
float val = calc_light(light_dir);
|
||||
|
||||
float distance = length(light.pos - f_pos);
|
||||
float atten = 1.0f / (1.0f + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
return val * atten;
|
||||
}
|
||||
|
||||
float calc_spot_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(light.pos - f_pos);
|
||||
|
||||
float theta = dot(light_dir, normalize(-light.dir));
|
||||
float epsilon = light.in_cutoff - light.out_cutoff;
|
||||
float intensity = clamp((theta - light.out_cutoff) / epsilon, 0.0, 1.0);
|
||||
|
||||
float point = calc_point_light(light);
|
||||
return point * intensity;
|
||||
}
|
||||
|
||||
float calc_dir_light(light_s light)
|
||||
{
|
||||
vec3 light_dir = normalize(-light.dir);
|
||||
return calc_light(light_dir);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 result = ambient * 0.3 + param[0].rgb * emission;
|
||||
for (uint i = 0U; i < lights_count; i++)
|
||||
{
|
||||
light_s light = lights[i];
|
||||
float part = 0.0;
|
||||
|
||||
if (light.type == LIGHT_SPOT)
|
||||
part = calc_spot_light(light);
|
||||
else if (light.type == LIGHT_POINT)
|
||||
part = calc_point_light(light);
|
||||
else if (light.type == LIGHT_DIR)
|
||||
part = calc_dir_light(light);
|
||||
|
||||
result += light.color * part;
|
||||
}
|
||||
|
||||
|
||||
vec4 tex_color = texture(tex1, f_coord);
|
||||
vec3 c = apply_fog(result * tex_color.xyz);
|
||||
gl_FragColor = vec4(c, tex_color.w);
|
||||
|
||||
|
||||
// gl_FragColor = vec4(f_tangent.xyz, 1.0f);
|
||||
}
|
||||
8
shaders/mat_notex.frag
Normal file
8
shaders/mat_notex.frag
Normal file
@@ -0,0 +1,8 @@
|
||||
#version 330
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = param[0];
|
||||
}
|
||||
28
shaders/simple.vert
Normal file
28
shaders/simple.vert
Normal file
@@ -0,0 +1,28 @@
|
||||
#version 330
|
||||
|
||||
in vec3 v_vert;
|
||||
in vec3 v_normal;
|
||||
in vec2 v_coord;
|
||||
in vec4 v_tangent;
|
||||
|
||||
out vec3 f_normal;
|
||||
out vec2 f_coord;
|
||||
out vec3 f_pos;
|
||||
out mat3 f_tbn;
|
||||
out vec4 f_tangent;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
|
||||
f_normal = modelviewnormal * v_normal;
|
||||
f_coord = v_coord;
|
||||
f_tangent = v_tangent;
|
||||
f_pos = vec3(modelview * vec4(v_vert, 1.0f));
|
||||
|
||||
vec3 T = normalize(modelviewnormal * v_tangent.xyz);
|
||||
vec3 B = normalize(modelviewnormal * cross(v_normal, v_tangent.xyz) * v_tangent.w);
|
||||
vec3 N = normalize(modelviewnormal * v_normal);
|
||||
f_tbn = mat3(T, B, N);
|
||||
}
|
||||
8
shaders/traction.frag
Normal file
8
shaders/traction.frag
Normal file
@@ -0,0 +1,8 @@
|
||||
#version 330
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = param[0];
|
||||
}
|
||||
12
shaders/traction.vert
Normal file
12
shaders/traction.vert
Normal file
@@ -0,0 +1,12 @@
|
||||
#version 330
|
||||
|
||||
in vec3 v_vert;
|
||||
in vec3 v_normal;
|
||||
in vec2 v_coord;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
|
||||
}
|
||||
@@ -5,8 +5,7 @@ in vec3 v_color;
|
||||
|
||||
out vec3 f_color;
|
||||
|
||||
uniform mat4 modelview;
|
||||
uniform mat4 projection;
|
||||
#include <common>
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -370,7 +370,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
// 3d terrain
|
||||
if( false == Scratchpad.binary.terrain ) {
|
||||
// if we're loading data from text .scn file convert and import
|
||||
auto *instance { deserialize_model( Input, Scratchpad, nodedata ) };
|
||||
auto *instance = deserialize_model( Input, Scratchpad, nodedata );
|
||||
// model import can potentially fail
|
||||
if( instance == nullptr ) { return; }
|
||||
// go through submodels, and import them as shapes
|
||||
|
||||
@@ -119,8 +119,8 @@ void CSkyDome::Render() {
|
||||
|
||||
if (!m_shader)
|
||||
{
|
||||
gl::shader vert("shaders/vbocolor.vert");
|
||||
gl::shader frag("shaders/color.frag");
|
||||
gl::shader vert("vbocolor.vert");
|
||||
gl::shader frag("color.frag");
|
||||
m_shader = std::make_unique<gl::program_mvp>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||
m_shader->init();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user