mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 23:19:19 +02:00
build 170628. enabled support for specular component in lighting calculations
This commit is contained in:
21
Globals.cpp
21
Globals.cpp
@@ -82,13 +82,10 @@ GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f};
|
|||||||
GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
|
GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
|
||||||
double Global::fFogStart = 1700;
|
double Global::fFogStart = 1700;
|
||||||
double Global::fFogEnd = 2000;
|
double Global::fFogEnd = 2000;
|
||||||
float Global::Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||||
opengl_light Global::DayLight;
|
opengl_light Global::DayLight;
|
||||||
int Global::DynamicLightCount{ 3 };
|
int Global::DynamicLightCount { 3 };
|
||||||
GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f};
|
bool Global::ScaleSpecularValues { true };
|
||||||
GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f};
|
|
||||||
GLfloat Global::darkLight[] = {0.03f, 0.03f, 0.03f, 1.0f}; //śladowe
|
|
||||||
GLfloat Global::lightPos[4];
|
|
||||||
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
|
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
|
||||||
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
||||||
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
||||||
@@ -224,13 +221,6 @@ std::string Global::GetNextSymbol()
|
|||||||
|
|
||||||
void Global::LoadIniFile(std::string asFileName)
|
void Global::LoadIniFile(std::string asFileName)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
{ // zerowanie pozycji kamer
|
|
||||||
pFreeCameraInit[i] = vector3(0, 0, 0); // współrzędne w scenerii
|
|
||||||
pFreeCameraInitAngle[i] = vector3(0, 0, 0); // kąty obrotu w radianach
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
FreeCameraInit.resize( 10 );
|
FreeCameraInit.resize( 10 );
|
||||||
FreeCameraInitAngle.resize( 10 );
|
FreeCameraInitAngle.resize( 10 );
|
||||||
cParser parser(asFileName, cParser::buffer_FILE);
|
cParser parser(asFileName, cParser::buffer_FILE);
|
||||||
@@ -543,6 +533,11 @@ void Global::ConfigParse(cParser &Parser)
|
|||||||
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
|
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
|
||||||
Global::DynamicLightCount = clamp( Global::DynamicLightCount, 1, 7 );
|
Global::DynamicLightCount = clamp( Global::DynamicLightCount, 1, 7 );
|
||||||
}
|
}
|
||||||
|
else if( token == "scalespeculars" ) {
|
||||||
|
// whether strength of specular highlights should be adjusted (generally needed for legacy 3d models)
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> Global::ScaleSpecularValues;
|
||||||
|
}
|
||||||
else if (token == "smoothtraction")
|
else if (token == "smoothtraction")
|
||||||
{
|
{
|
||||||
// podwójna jasność ambient
|
// podwójna jasność ambient
|
||||||
|
|||||||
@@ -225,11 +225,8 @@ class Global
|
|||||||
// TODO: put these things in the renderer
|
// TODO: put these things in the renderer
|
||||||
static opengl_light DayLight;
|
static opengl_light DayLight;
|
||||||
static int DynamicLightCount;
|
static int DynamicLightCount;
|
||||||
|
static bool ScaleSpecularValues;
|
||||||
|
|
||||||
static GLfloat whiteLight[];
|
|
||||||
static GLfloat noLight[];
|
|
||||||
static GLfloat darkLight[];
|
|
||||||
static GLfloat lightPos[4];
|
|
||||||
static int iSlowMotion;
|
static int iSlowMotion;
|
||||||
static TDynamicObject *changeDynObj;
|
static TDynamicObject *changeDynObj;
|
||||||
static double ABuDebug;
|
static double ABuDebug;
|
||||||
|
|||||||
@@ -1937,7 +1937,7 @@ bool TGround::Init(std::string File)
|
|||||||
>> Global::DayLight.direction.x
|
>> Global::DayLight.direction.x
|
||||||
>> Global::DayLight.direction.y
|
>> Global::DayLight.direction.y
|
||||||
>> Global::DayLight.direction.z;;
|
>> Global::DayLight.direction.z;;
|
||||||
Global::DayLight.direction.Normalize();
|
Global::DayLight.direction = glm::normalize( Global::DayLight.direction );
|
||||||
parser.getTokens(9, false);
|
parser.getTokens(9, false);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|||||||
76
Model3d.cpp
76
Model3d.cpp
@@ -240,8 +240,13 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
if (eType < TP_ROTATOR)
|
if (eType < TP_ROTATOR)
|
||||||
readColor(parser, f4Ambient); // ignoruje token przed
|
readColor(parser, f4Ambient); // ignoruje token przed
|
||||||
readColor(parser, f4Diffuse);
|
readColor(parser, f4Diffuse);
|
||||||
if (eType < TP_ROTATOR)
|
if( eType < TP_ROTATOR ) {
|
||||||
readColor(parser, f4Specular);
|
readColor( parser, f4Specular );
|
||||||
|
if( pName == "cien" ) {
|
||||||
|
// crude workaround to kill specular on shadow geometry of legacy models
|
||||||
|
f4Specular = glm::vec4{ 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
}
|
||||||
|
}
|
||||||
parser.ignoreTokens(1); // zignorowanie nazwy "SelfIllum:"
|
parser.ignoreTokens(1); // zignorowanie nazwy "SelfIllum:"
|
||||||
{
|
{
|
||||||
std::string light = parser.getToken<std::string>();
|
std::string light = parser.getToken<std::string>();
|
||||||
@@ -367,6 +372,10 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
readMatrix(parser, *fMatrix); // wczytanie transform
|
readMatrix(parser, *fMatrix); // wczytanie transform
|
||||||
if (!fMatrix->IdentityIs())
|
if (!fMatrix->IdentityIs())
|
||||||
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
||||||
|
if( std::abs( Det( *fMatrix ) - 1.0f ) > 0.01f ) {
|
||||||
|
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factor: " + to_string( Det( *fMatrix ), 2 ) + ")" );
|
||||||
|
m_normalizenormals = true;
|
||||||
|
}
|
||||||
if (eType < TP_ROTATOR)
|
if (eType < TP_ROTATOR)
|
||||||
{ // wczytywanie wierzchołków
|
{ // wczytywanie wierzchołków
|
||||||
parser.getTokens(2, false);
|
parser.getTokens(2, false);
|
||||||
@@ -446,7 +455,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
--facecount; // o jeden trójkąt mniej
|
--facecount; // o jeden trójkąt mniej
|
||||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||||
i -= 3; // wczytanie kolejnego w to miejsce
|
i -= 3; // wczytanie kolejnego w to miejsce
|
||||||
WriteLog("Degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(i) + "-" + std::to_string(i+2));
|
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(i) + "-" + std::to_string(i+2));
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
||||||
@@ -458,7 +467,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
--facecount; // o jeden trójkąt mniej
|
--facecount; // o jeden trójkąt mniej
|
||||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||||
i -= 3; // wczytanie kolejnego w to miejsce
|
i -= 3; // wczytanie kolejnego w to miejsce
|
||||||
WriteLog( "Too large triangle ignored in: \"" + pName + "\"" );
|
WriteLog( "Bad model: too large triangle ignored in: \"" + pName + "\"" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,7 +483,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 1 ].position,
|
||||||
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position );
|
Vertices[ i * 3 ].position - Vertices[ i * 3 + 2 ].position );
|
||||||
facenormals.emplace_back(
|
facenormals.emplace_back(
|
||||||
glm::length( facenormal ) > 0.0f ?
|
glm::length2( facenormal ) > 0.0f ?
|
||||||
glm::normalize( facenormal ) :
|
glm::normalize( facenormal ) :
|
||||||
glm::vec3() );
|
glm::vec3() );
|
||||||
}
|
}
|
||||||
@@ -492,16 +501,24 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
auto adjacenvertextidx = vertexidx; // zaczynamy dodawanie wektorów normalnych od własnego
|
auto adjacenvertextidx = vertexidx; // zaczynamy dodawanie wektorów normalnych od własnego
|
||||||
while (adjacenvertextidx >= 0) {
|
while (adjacenvertextidx >= 0) {
|
||||||
// sumowanie z wektorem normalnym sąsiada (włącznie ze sobą)
|
// sumowanie z wektorem normalnym sąsiada (włącznie ze sobą)
|
||||||
wsp[adjacenvertextidx] = vertexidx; // informacja, że w tym wierzchołku jest już policzony wektor normalny
|
if( glm::dot( vertexnormal, facenormals[ adjacenvertextidx / 3 ] ) > -0.99f ) {
|
||||||
vertexnormal += facenormals[adjacenvertextidx / 3];
|
wsp[ adjacenvertextidx ] = vertexidx; // informacja, że w tym wierzchołku jest już policzony wektor normalny
|
||||||
|
vertexnormal += facenormals[ adjacenvertextidx / 3 ];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad model: opposite normals in the same smoothing group, check sub-model \"" + pName + "\" for two-sided faces and/or scaling" );
|
||||||
|
}
|
||||||
// i szukanie od kolejnego trójkąta
|
// i szukanie od kolejnego trójkąta
|
||||||
adjacenvertextidx = SeekFaceNormal(sg, adjacenvertextidx / 3 + 1, sg[faceidx], Vertices[vertexidx].position, Vertices);
|
adjacenvertextidx = SeekFaceNormal(sg, adjacenvertextidx / 3 + 1, sg[faceidx], Vertices[vertexidx].position, Vertices);
|
||||||
}
|
}
|
||||||
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez transformy, aby normalne po przeskalowaniu były jednostkowe
|
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez transformy, aby normalne po przeskalowaniu były jednostkowe
|
||||||
|
if( glm::length2( vertexnormal ) == 0.0f ) {
|
||||||
|
WriteLog( "Bad model: zero lenght normal vector generated for sub-model \"" + pName + "\"" );
|
||||||
|
}
|
||||||
Vertices[ vertexidx ].normal = (
|
Vertices[ vertexidx ].normal = (
|
||||||
glm::length( vertexnormal ) > 0.0f ?
|
glm::length2( vertexnormal ) > 0.0f ?
|
||||||
glm::normalize( vertexnormal ) :
|
glm::normalize( vertexnormal ) :
|
||||||
glm::vec3() ); // przepisanie do wierzchołka trójkąta
|
facenormals[ vertexidx / 3 ] ); // przepisanie do wierzchołka trójkąta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vertices.resize( iNumVerts ); // in case we had some degenerate triangles along the way
|
Vertices.resize( iNumVerts ); // in case we had some degenerate triangles along the way
|
||||||
@@ -1516,6 +1533,15 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
iNumVerts += submodel.iNumVerts;
|
iNumVerts += submodel.iNumVerts;
|
||||||
for( auto &vertex : vertices ) {
|
for( auto &vertex : vertices ) {
|
||||||
vertex.deserialize( s );
|
vertex.deserialize( s );
|
||||||
|
if( submodel.eType < TP_ROTATOR ) {
|
||||||
|
// normal vectors debug routine
|
||||||
|
auto normallength = glm::length2( vertex.normal );
|
||||||
|
if( ( false == submodel.m_normalizenormals )
|
||||||
|
&& ( std::abs( normallength - 1.0f ) > 0.01f ) ) {
|
||||||
|
submodel.m_normalizenormals = true;
|
||||||
|
WriteLog( "Bad model: non-unit normal vector(s) encountered during sub-model geometry deserialization" );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// remap geometry type for custom type submodels
|
// remap geometry type for custom type submodels
|
||||||
int type;
|
int type;
|
||||||
@@ -1599,6 +1625,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
Child = (iChild > 0) ? s + iChild : nullptr; // zerowy nie może być potomnym
|
Child = (iChild > 0) ? s + iChild : nullptr; // zerowy nie może być potomnym
|
||||||
Next = (iNext > 0) ? s + iNext : nullptr; // zerowy nie może być następnym
|
Next = (iNext > 0) ? s + iNext : nullptr; // zerowy nie może być następnym
|
||||||
fMatrix = ((iMatrix >= 0) && m) ? m + iMatrix : nullptr;
|
fMatrix = ((iMatrix >= 0) && m) ? m + iMatrix : nullptr;
|
||||||
|
|
||||||
if (n->size() && (iName >= 0))
|
if (n->size() && (iName >= 0))
|
||||||
{
|
{
|
||||||
pName = n->at(iName);
|
pName = n->at(iName);
|
||||||
@@ -1612,12 +1639,16 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
// obiektem "Light_Off"
|
// obiektem "Light_Off"
|
||||||
else if (dynamic)
|
else if (dynamic)
|
||||||
{ // inaczej wyłączało smugę w latarniach
|
{ // inaczej wyłączało smugę w latarniach
|
||||||
if ((pName.size() >= 3) && (pName.substr(pName.size() - 3, 3) == "_on"))
|
if ((pName.size() >= 3) && (pName.substr(pName.size() - 3, 3) == "_on")) {
|
||||||
{ // jeśli jest kontrolką w stanie zapalonym
|
// jeśli jest kontrolką w stanie zapalonym to domyślnie wyłączyć,
|
||||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z
|
// żeby się nie nakładało z obiektem "_off"
|
||||||
|
iVisible = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// obiektem "_off"
|
// hack: reset specular light value for shadow submodels
|
||||||
|
if( pName == "cien" ) {
|
||||||
|
f4Specular = glm::vec4 { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1654,11 +1685,22 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
if( fCosHotspotAngle > 1.0f ) {
|
if( fCosHotspotAngle > 1.0f ) {
|
||||||
fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) );
|
fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) );
|
||||||
}
|
}
|
||||||
|
// cap specular values for legacy models
|
||||||
|
f4Specular = glm::vec4{
|
||||||
|
clamp( f4Specular.r, 0.0f, 1.0f ),
|
||||||
|
clamp( f4Specular.g, 0.0f, 1.0f ),
|
||||||
|
clamp( f4Specular.b, 0.0f, 1.0f ),
|
||||||
|
clamp( f4Specular.a, 0.0f, 1.0f ) };
|
||||||
|
|
||||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||||
/*
|
|
||||||
iVboPtr = tVboPtr;
|
if( ( fMatrix != nullptr )
|
||||||
*/
|
&& ( std::abs( Det( *fMatrix ) - 1.0f ) > 0.01f ) ) {
|
||||||
|
// check whether we need to enable normal vectors normalization for this submodel
|
||||||
|
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factor: " + to_string( Det( *fMatrix ), 2 ) + ")" );
|
||||||
|
m_normalizenormals = true;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ private:
|
|||||||
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
||||||
f4Specular { 0.0f,0.0f,0.0f,1.0f },
|
f4Specular { 0.0f,0.0f,0.0f,1.0f },
|
||||||
f4Emision { 1.0f,1.0f,1.0f,1.0f };
|
f4Emision { 1.0f,1.0f,1.0f,1.0f };
|
||||||
|
bool m_normalizenormals { false }; // indicates vectors need to be normalized due to scaling etc
|
||||||
float fWireSize { 0.0f }; // nie używane, ale wczytywane
|
float fWireSize { 0.0f }; // nie używane, ale wczytywane
|
||||||
float fSquareMaxDist { 10000.0f * 10000.0f };
|
float fSquareMaxDist { 10000.0f * 10000.0f };
|
||||||
float fSquareMinDist { 0.0f };
|
float fSquareMinDist { 0.0f };
|
||||||
|
|||||||
19
World.cpp
19
World.cpp
@@ -2277,34 +2277,34 @@ world_environment::update() {
|
|||||||
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
||||||
float keylightintensity;
|
float keylightintensity;
|
||||||
float twilightfactor;
|
float twilightfactor;
|
||||||
float3 keylightcolor;
|
glm::vec3 keylightcolor;
|
||||||
if( moonlightlevel > sunlightlevel ) {
|
if( moonlightlevel > sunlightlevel ) {
|
||||||
// rare situations when the moon is brighter than the sun, typically at night
|
// rare situations when the moon is brighter than the sun, typically at night
|
||||||
Global::SunAngle = m_moon.getAngle();
|
Global::SunAngle = m_moon.getAngle();
|
||||||
Global::DayLight.set_position( m_moon.getPosition() );
|
Global::DayLight.set_position( m_moon.getPosition() );
|
||||||
Global::DayLight.direction = -1.0 * m_moon.getDirection();
|
Global::DayLight.direction = -1.0f * m_moon.getDirection();
|
||||||
keylightintensity = moonlightlevel;
|
keylightintensity = moonlightlevel;
|
||||||
// if the moon is up, it overrides the twilight
|
// if the moon is up, it overrides the twilight
|
||||||
twilightfactor = 0.0f;
|
twilightfactor = 0.0f;
|
||||||
keylightcolor = float3( 255.0f / 255.0f, 242.0f / 255.0f, 202.0f / 255.0f );
|
keylightcolor = glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 202.0f / 255.0f );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// regular situation with sun as the key light
|
// regular situation with sun as the key light
|
||||||
Global::SunAngle = m_sun.getAngle();
|
Global::SunAngle = m_sun.getAngle();
|
||||||
Global::DayLight.set_position( m_sun.getPosition() );
|
Global::DayLight.set_position( m_sun.getPosition() );
|
||||||
Global::DayLight.direction = -1.0 * m_sun.getDirection();
|
Global::DayLight.direction = -1.0f * m_sun.getDirection();
|
||||||
keylightintensity = sunlightlevel;
|
keylightintensity = sunlightlevel;
|
||||||
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
||||||
twilightfactor = clamp( -Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
twilightfactor = clamp( -Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
||||||
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
||||||
keylightcolor = interpolate(
|
keylightcolor = interpolate(
|
||||||
float3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||||
float3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
||||||
duskfactor );
|
duskfactor );
|
||||||
}
|
}
|
||||||
// ...update skydome to match the current sun position as well...
|
// ...update skydome to match the current sun position as well...
|
||||||
m_skydome.SetOvercastFactor( Global::Overcast );
|
m_skydome.SetOvercastFactor( Global::Overcast );
|
||||||
m_skydome.Update( m_sun.getPosition() );
|
m_skydome.Update( m_sun.getDirection() );
|
||||||
// ...retrieve current sky colour and brightness...
|
// ...retrieve current sky colour and brightness...
|
||||||
auto const skydomecolour = m_skydome.GetAverageColor();
|
auto const skydomecolour = m_skydome.GetAverageColor();
|
||||||
auto const skydomehsv = RGBtoHSV( skydomecolour );
|
auto const skydomehsv = RGBtoHSV( skydomecolour );
|
||||||
@@ -2319,9 +2319,8 @@ world_environment::update() {
|
|||||||
auto const diffuselevel = interpolate( keylightintensity, intensity * ( 1.0f - twilightfactor ), 1.0f - Global::Overcast * 0.75f );
|
auto const diffuselevel = interpolate( keylightintensity, intensity * ( 1.0f - twilightfactor ), 1.0f - Global::Overcast * 0.75f );
|
||||||
// ...update light colours and intensity.
|
// ...update light colours and intensity.
|
||||||
keylightcolor = keylightcolor * diffuselevel;
|
keylightcolor = keylightcolor * diffuselevel;
|
||||||
Global::DayLight.diffuse[ 0 ] = keylightcolor.x;
|
Global::DayLight.diffuse = glm::vec4( keylightcolor, Global::DayLight.diffuse.a );
|
||||||
Global::DayLight.diffuse[ 1 ] = keylightcolor.y;
|
Global::DayLight.specular = glm::vec4( keylightcolor * 0.85f, diffuselevel );
|
||||||
Global::DayLight.diffuse[ 2 ] = keylightcolor.z;
|
|
||||||
|
|
||||||
// tonal impact of skydome color is inversely proportional to how high the sun is above the horizon
|
// tonal impact of skydome color is inversely proportional to how high the sun is above the horizon
|
||||||
// (this is pure conjecture, aimed more to 'look right' than be accurate)
|
// (this is pure conjecture, aimed more to 'look right' than be accurate)
|
||||||
|
|||||||
74
color.h
74
color.h
@@ -3,28 +3,28 @@
|
|||||||
#include "float3d.h"
|
#include "float3d.h"
|
||||||
|
|
||||||
inline
|
inline
|
||||||
float3
|
glm::vec3
|
||||||
XYZtoRGB( float3 const &XYZ ) {
|
XYZtoRGB( glm::vec3 const &XYZ ) {
|
||||||
|
|
||||||
// M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
|
// M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
|
||||||
float const mi[ 3 ][ 3 ] = { 2.041369f, -0.969266f, 0.0134474f, -0.5649464f, 1.8760108f, -0.1183897f, -0.3446944f, 0.041556f, 1.0154096f };
|
float const mi[ 3 ][ 3 ] = { 2.041369f, -0.969266f, 0.0134474f, -0.5649464f, 1.8760108f, -0.1183897f, -0.3446944f, 0.041556f, 1.0154096f };
|
||||||
// m^-1 for sRGB:
|
// m^-1 for sRGB:
|
||||||
// float const mi[ 3 ][ 3 ] = { 3.240479f, -0.969256f, 0.055648f, -1.53715f, 1.875991f, -0.204043f, -0.49853f, 0.041556f, 1.057311f };
|
// float const mi[ 3 ][ 3 ] = { 3.240479f, -0.969256f, 0.055648f, -1.53715f, 1.875991f, -0.204043f, -0.49853f, 0.041556f, 1.057311f };
|
||||||
|
|
||||||
return float3{
|
return glm::vec3{
|
||||||
XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ],
|
XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ],
|
||||||
XYZ.x*mi[ 0 ][ 1 ] + XYZ.y*mi[ 1 ][ 1 ] + XYZ.z*mi[ 2 ][ 1 ],
|
XYZ.x*mi[ 0 ][ 1 ] + XYZ.y*mi[ 1 ][ 1 ] + XYZ.z*mi[ 2 ][ 1 ],
|
||||||
XYZ.x*mi[ 0 ][ 2 ] + XYZ.y*mi[ 1 ][ 2 ] + XYZ.z*mi[ 2 ][ 2 ] };
|
XYZ.x*mi[ 0 ][ 2 ] + XYZ.y*mi[ 1 ][ 2 ] + XYZ.z*mi[ 2 ][ 2 ] };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
float3
|
glm::vec3
|
||||||
RGBtoHSV( float3 const &RGB ) {
|
RGBtoHSV( glm::vec3 const &RGB ) {
|
||||||
|
|
||||||
float3 hsv;
|
glm::vec3 hsv;
|
||||||
|
|
||||||
float const max = std::max( std::max( RGB.x, RGB.y ), RGB.z );
|
float const max = std::max( std::max( RGB.r, RGB.g ), RGB.b );
|
||||||
float const min = std::min( std::min( RGB.x, RGB.y ), RGB.z );
|
float const min = std::min( std::min( RGB.r, RGB.g ), RGB.b );
|
||||||
float const delta = max - min;
|
float const delta = max - min;
|
||||||
|
|
||||||
hsv.z = max; // v
|
hsv.z = max; // v
|
||||||
@@ -43,13 +43,13 @@ RGBtoHSV( float3 const &RGB ) {
|
|||||||
hsv.x = NAN; // its now undefined
|
hsv.x = NAN; // its now undefined
|
||||||
return hsv;
|
return hsv;
|
||||||
}
|
}
|
||||||
if( RGB.x >= max ) // > is bogus, just keeps compilor happy
|
if( RGB.r >= max ) // > is bogus, just keeps compilor happy
|
||||||
hsv.x = ( RGB.y - RGB.z ) / delta; // between yellow & magenta
|
hsv.x = ( RGB.g - RGB.b ) / delta; // between yellow & magenta
|
||||||
else
|
else
|
||||||
if( RGB.y >= max )
|
if( RGB.g >= max )
|
||||||
hsv.x = 2.0 + ( RGB.y - RGB.x ) / delta; // between cyan & yellow
|
hsv.x = 2.0 + ( RGB.g - RGB.r ) / delta; // between cyan & yellow
|
||||||
else
|
else
|
||||||
hsv.x = 4.0 + ( RGB.x - RGB.y ) / delta; // between magenta & cyan
|
hsv.x = 4.0 + ( RGB.r - RGB.g ) / delta; // between magenta & cyan
|
||||||
|
|
||||||
hsv.x *= 60.0; // degrees
|
hsv.x *= 60.0; // degrees
|
||||||
|
|
||||||
@@ -60,15 +60,15 @@ RGBtoHSV( float3 const &RGB ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
float3
|
glm::vec3
|
||||||
HSVtoRGB( float3 const &HSV ) {
|
HSVtoRGB( glm::vec3 const &HSV ) {
|
||||||
|
|
||||||
float3 rgb;
|
glm::vec3 rgb;
|
||||||
|
|
||||||
if( HSV.y <= 0.0 ) { // < is bogus, just shuts up warnings
|
if( HSV.y <= 0.0 ) { // < is bogus, just shuts up warnings
|
||||||
rgb.x = HSV.z;
|
rgb.r = HSV.z;
|
||||||
rgb.y = HSV.z;
|
rgb.g = HSV.z;
|
||||||
rgb.z = HSV.z;
|
rgb.b = HSV.z;
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
float hh = HSV.x;
|
float hh = HSV.x;
|
||||||
@@ -82,36 +82,36 @@ HSVtoRGB( float3 const &HSV ) {
|
|||||||
|
|
||||||
switch( i ) {
|
switch( i ) {
|
||||||
case 0:
|
case 0:
|
||||||
rgb.x = HSV.z;
|
rgb.r = HSV.z;
|
||||||
rgb.y = t;
|
rgb.g = t;
|
||||||
rgb.z = p;
|
rgb.b = p;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
rgb.x = q;
|
rgb.r = q;
|
||||||
rgb.y = HSV.z;
|
rgb.g = HSV.z;
|
||||||
rgb.z = p;
|
rgb.b = p;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rgb.x = p;
|
rgb.r = p;
|
||||||
rgb.y = HSV.z;
|
rgb.g = HSV.z;
|
||||||
rgb.z = t;
|
rgb.b = t;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
rgb.x = p;
|
rgb.r = p;
|
||||||
rgb.y = q;
|
rgb.g = q;
|
||||||
rgb.z = HSV.z;
|
rgb.b = HSV.z;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
rgb.x = t;
|
rgb.r = t;
|
||||||
rgb.y = p;
|
rgb.g = p;
|
||||||
rgb.z = HSV.z;
|
rgb.b = HSV.z;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
default:
|
default:
|
||||||
rgb.x = HSV.z;
|
rgb.r = HSV.z;
|
||||||
rgb.y = p;
|
rgb.g = p;
|
||||||
rgb.z = q;
|
rgb.b = q;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return rgb;
|
return rgb;
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ light_array::update() {
|
|||||||
if( light.index == 0 ) {
|
if( light.index == 0 ) {
|
||||||
// front light set
|
// front light set
|
||||||
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
|
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
|
||||||
light.direction = light.owner->VectorFront();
|
light.direction = glm::make_vec3( light.owner->VectorFront().getArray() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// rear light set
|
// rear light set
|
||||||
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
|
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
|
||||||
light.direction = light.owner->VectorFront();
|
light.direction = glm::make_vec3( light.owner->VectorFront().getArray() );
|
||||||
light.direction.x = -light.direction.x;
|
light.direction.x = -light.direction.x;
|
||||||
light.direction.z = -light.direction.z;
|
light.direction.z = -light.direction.z;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
TDynamicObject const *owner; // the object in world which 'carries' the light
|
TDynamicObject const *owner; // the object in world which 'carries' the light
|
||||||
int index{ -1 }; // 0: front lights, 1: rear lights
|
int index{ -1 }; // 0: front lights, 1: rear lights
|
||||||
Math3D::vector3 position; // position of the light in 3d scene
|
Math3D::vector3 position; // position of the light in 3d scene
|
||||||
Math3D::vector3 direction; // direction of the light in 3d scene
|
glm::vec3 direction; // direction of the light in 3d scene
|
||||||
float3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
float3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
||||||
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
||||||
int count{ 0 }; // number (or pattern) of active light(s)
|
int count{ 0 }; // number (or pattern) of active light(s)
|
||||||
|
|||||||
14
moon.cpp
14
moon.cpp
@@ -36,9 +36,9 @@ void
|
|||||||
cMoon::update() {
|
cMoon::update() {
|
||||||
|
|
||||||
move();
|
move();
|
||||||
Math3D::vector3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||||
position.RotateY( (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = position;
|
||||||
}
|
}
|
||||||
@@ -59,14 +59,10 @@ cMoon::render() {
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
Math3D::vector3
|
glm::vec3
|
||||||
cMoon::getDirection() {
|
cMoon::getDirection() {
|
||||||
|
|
||||||
Math3D::vector3 position( 0.f, 0.f, -1.f );
|
return glm::normalize( m_position );
|
||||||
position.RotateX( (float)( m_body.elevref * (M_PI/180.0)) );
|
|
||||||
position.RotateY( (float)( -m_body.hrang * (M_PI/180.0)) );
|
|
||||||
position.Normalize();
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
|
|||||||
7
moon.h
7
moon.h
@@ -3,7 +3,6 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
#include "GL/wglew.h"
|
#include "GL/wglew.h"
|
||||||
#include "dumb3d.h"
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: sun and moon share code as celestial bodies, we could make a base class out of it
|
// TODO: sun and moon share code as celestial bodies, we could make a base class out of it
|
||||||
@@ -18,9 +17,9 @@ public:
|
|||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
// returns location of the sun in the 3d scene
|
// returns location of the sun in the 3d scene
|
||||||
Math3D::vector3 getPosition() { return m_position; }
|
glm::vec3 getPosition() { return m_position; }
|
||||||
// returns vector pointing at the sun
|
// returns vector pointing at the sun
|
||||||
Math3D::vector3 getDirection();
|
glm::vec3 getDirection();
|
||||||
// returns current elevation above horizon
|
// returns current elevation above horizon
|
||||||
float getAngle() const;
|
float getAngle() const;
|
||||||
// returns current intensity of the sun
|
// returns current intensity of the sun
|
||||||
@@ -101,6 +100,6 @@ protected:
|
|||||||
|
|
||||||
celestialbody m_body;
|
celestialbody m_body;
|
||||||
observer m_observer;
|
observer m_observer;
|
||||||
Math3D::vector3 m_position;
|
glm::vec3 m_position;
|
||||||
float m_phase;
|
float m_phase;
|
||||||
};
|
};
|
||||||
|
|||||||
83
renderer.cpp
83
renderer.cpp
@@ -24,6 +24,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
opengl_renderer GfxRenderer;
|
opengl_renderer GfxRenderer;
|
||||||
extern TWorld World;
|
extern TWorld World;
|
||||||
|
|
||||||
|
namespace colors {
|
||||||
|
|
||||||
|
glm::vec4 const none { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
|
} // namespace colors
|
||||||
|
|
||||||
// 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( bounding_area const &Area ) const {
|
opengl_camera::visible( bounding_area const &Area ) const {
|
||||||
@@ -74,14 +80,19 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
glPointSize( 3.0f );
|
glPointSize( 3.0f );
|
||||||
glEnable( GL_POINT_SMOOTH );
|
glEnable( GL_POINT_SMOOTH );
|
||||||
|
|
||||||
glEnable( GL_COLOR_MATERIAL );
|
::glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR );
|
||||||
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
::glMaterialf( GL_FRONT, GL_SHININESS, 15.0f );
|
||||||
|
if( true == Global::ScaleSpecularValues ) {
|
||||||
|
m_specularopaquescalefactor = 0.25f;
|
||||||
|
m_speculartranslucentscalefactor = 1.5f;
|
||||||
|
}
|
||||||
|
::glEnable( GL_COLOR_MATERIAL );
|
||||||
|
::glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
||||||
|
|
||||||
// setup lighting
|
// setup lighting
|
||||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
::glEnable( GL_LIGHTING );
|
||||||
glEnable( GL_LIGHTING );
|
::glEnable( GL_LIGHT0 );
|
||||||
glEnable( GL_LIGHT0 );
|
|
||||||
|
|
||||||
Global::DayLight.id = opengl_renderer::sunlight;
|
Global::DayLight.id = opengl_renderer::sunlight;
|
||||||
// directional light
|
// directional light
|
||||||
@@ -205,9 +216,9 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
Environment->m_stars.render();
|
Environment->m_stars.render();
|
||||||
|
|
||||||
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
|
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
|
||||||
float3 suncolor = interpolate(
|
glm::vec3 suncolor = interpolate(
|
||||||
float3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||||
float3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
||||||
duskfactor );
|
duskfactor );
|
||||||
|
|
||||||
if( DebugModeFlag == true ) {
|
if( DebugModeFlag == true ) {
|
||||||
@@ -248,11 +259,10 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
// moon
|
// moon
|
||||||
{
|
{
|
||||||
Bind( m_moontexture );
|
Bind( m_moontexture );
|
||||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
glm::vec3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||||
|
|
||||||
auto const moonvector = Environment->m_moon.getDirection();
|
auto const moonposition = modelview * glm::vec4( Environment->m_moon.getDirection(), 1.0f );
|
||||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glLoadIdentity(); // macierz jedynkowa
|
::glLoadIdentity(); // macierz jedynkowa
|
||||||
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
||||||
@@ -553,7 +563,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
::glColor4fv(
|
::glColor4fv(
|
||||||
glm::value_ptr(
|
glm::value_ptr(
|
||||||
glm::vec4(
|
glm::vec4(
|
||||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
Node->Diffuse * glm::vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
||||||
1.0 ) ) ); // if the thickness is defined negative, lines are always drawn opaque
|
1.0 ) ) ); // if the thickness is defined negative, lines are always drawn opaque
|
||||||
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 );
|
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 );
|
||||||
if( linewidth > 1.0 ) {
|
if( linewidth > 1.0 ) {
|
||||||
@@ -633,6 +643,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
// change light level based on light level of the occupied track
|
// change light level based on light level of the occupied track
|
||||||
Global::DayLight.apply_intensity( Dynamic->fShade );
|
Global::DayLight.apply_intensity( Dynamic->fShade );
|
||||||
}
|
}
|
||||||
|
m_renderspecular = true; // vehicles are rendered with specular component. static models without, at least for the time being
|
||||||
|
|
||||||
// render
|
// render
|
||||||
if( Dynamic->mdLowPolyInt ) {
|
if( Dynamic->mdLowPolyInt ) {
|
||||||
@@ -650,8 +661,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
|
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
// reset the overall ambient
|
// reset the overall ambient
|
||||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -663,6 +673,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
m_renderspecular = false;
|
||||||
if( Dynamic->fShade > 0.0f ) {
|
if( Dynamic->fShade > 0.0f ) {
|
||||||
// restore regular light level
|
// restore regular light level
|
||||||
Global::DayLight.apply_intensity();
|
Global::DayLight.apply_intensity();
|
||||||
@@ -747,6 +758,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
// renderowanie obiektów OpenGL
|
// renderowanie obiektów OpenGL
|
||||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
|
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
|
||||||
{
|
{
|
||||||
|
if( true == Submodel->m_normalizenormals ) {
|
||||||
|
::glEnable( GL_NORMALIZE );
|
||||||
|
}
|
||||||
// material configuration:
|
// material configuration:
|
||||||
// textures...
|
// textures...
|
||||||
if( Submodel->TextureID < 0 )
|
if( Submodel->TextureID < 0 )
|
||||||
@@ -757,7 +771,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
// również 0
|
// również 0
|
||||||
Bind( Submodel->TextureID );
|
Bind( Submodel->TextureID );
|
||||||
}
|
}
|
||||||
|
// ...colors...
|
||||||
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
||||||
|
if( ( true == m_renderspecular ) && ( Global::DayLight.specular.a > 0.01f ) ) {
|
||||||
|
// specular strength in legacy models is set uniformly to 150, 150, 150 so we scale it down for opaque elements
|
||||||
|
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * Global::DayLight.specular.a * m_specularopaquescalefactor ) );
|
||||||
|
}
|
||||||
// ...luminance
|
// ...luminance
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// zeby swiecilo na kolorowo
|
// zeby swiecilo na kolorowo
|
||||||
@@ -768,10 +787,15 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
|
if( ( true == m_renderspecular ) && ( Global::DayLight.specular.a > 0.01f ) ) {
|
||||||
|
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
|
||||||
|
}
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// restore default (lack of) brightness
|
// restore default (lack of) brightness
|
||||||
glm::vec4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( noemission ) );
|
}
|
||||||
|
if( true == Submodel->m_normalizenormals ) {
|
||||||
|
::glDisable( GL_NORMALIZE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1007,7 +1031,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
::glColor4fv(
|
::glColor4fv(
|
||||||
glm::value_ptr(
|
glm::value_ptr(
|
||||||
glm::vec4(
|
glm::vec4(
|
||||||
Node->Diffuse * glm::make_vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
Node->Diffuse * glm::vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla
|
||||||
std::min( 1.0, linealpha ) ) ) );
|
std::min( 1.0, linealpha ) ) ) );
|
||||||
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 );
|
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 );
|
||||||
if( linewidth > 1.0 ) {
|
if( linewidth > 1.0 ) {
|
||||||
@@ -1079,6 +1103,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
// change light level based on light level of the occupied track
|
// change light level based on light level of the occupied track
|
||||||
Global::DayLight.apply_intensity( Dynamic->fShade );
|
Global::DayLight.apply_intensity( Dynamic->fShade );
|
||||||
}
|
}
|
||||||
|
m_renderspecular = true;
|
||||||
|
|
||||||
// render
|
// render
|
||||||
if( Dynamic->mdLowPolyInt ) {
|
if( Dynamic->mdLowPolyInt ) {
|
||||||
@@ -1096,8 +1121,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
|
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||||
// reset the overall ambient
|
// reset the overall ambient
|
||||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1109,6 +1133,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
m_renderspecular = false;
|
||||||
if( Dynamic->fShade > 0.0f ) {
|
if( Dynamic->fShade > 0.0f ) {
|
||||||
// restore regular light level
|
// restore regular light level
|
||||||
Global::DayLight.apply_intensity();
|
Global::DayLight.apply_intensity();
|
||||||
@@ -1192,6 +1217,9 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
// renderowanie obiektów OpenGL
|
// renderowanie obiektów OpenGL
|
||||||
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
|
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
|
||||||
{
|
{
|
||||||
|
if( true == Submodel->m_normalizenormals ) {
|
||||||
|
::glEnable( GL_NORMALIZE );
|
||||||
|
}
|
||||||
// textures...
|
// textures...
|
||||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||||
@@ -1200,7 +1228,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
// również 0
|
// również 0
|
||||||
Bind( Submodel->TextureID );
|
Bind( Submodel->TextureID );
|
||||||
}
|
}
|
||||||
|
// ...colors...
|
||||||
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
||||||
|
if( ( true == m_renderspecular ) && ( Global::DayLight.specular.a > 0.01f ) ) {
|
||||||
|
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * Global::DayLight.specular.a * m_speculartranslucentscalefactor ) );
|
||||||
|
}
|
||||||
// ...luminance
|
// ...luminance
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// zeby swiecilo na kolorowo
|
// zeby swiecilo na kolorowo
|
||||||
@@ -1211,10 +1243,15 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
// post-draw reset
|
// post-draw reset
|
||||||
|
if( ( true == m_renderspecular ) && ( Global::DayLight.specular.a > 0.01f ) ) {
|
||||||
|
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
|
||||||
|
}
|
||||||
if( Global::fLuminance < Submodel->fLight ) {
|
if( Global::fLuminance < Submodel->fLight ) {
|
||||||
// restore default (lack of) brightness
|
// restore default (lack of) brightness
|
||||||
glm::vec4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( noemission ) );
|
}
|
||||||
|
if( true == Submodel->m_normalizenormals ) {
|
||||||
|
::glDisable( GL_NORMALIZE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1401,7 +1438,7 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if the light passed tests so far, it's good enough
|
// if the light passed tests so far, it's good enough
|
||||||
renderlight->set_position( scenelight.position - Global::pCameraPosition );
|
renderlight->set_position( glm::make_vec3( (scenelight.position - Global::pCameraPosition).readArray() ) );
|
||||||
renderlight->direction = scenelight.direction;
|
renderlight->direction = scenelight.direction;
|
||||||
|
|
||||||
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||||
|
|||||||
53
renderer.h
53
renderer.h
@@ -21,53 +21,44 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
struct opengl_light {
|
struct opengl_light {
|
||||||
|
|
||||||
GLuint id{ (GLuint)-1 };
|
GLuint id{ (GLuint)-1 };
|
||||||
Math3D::vector3 direction;
|
glm::vec3 direction;
|
||||||
GLfloat position[ 4 ]; // 4th parameter specifies directional(0) or omni-directional(1) light source
|
glm::vec4
|
||||||
GLfloat ambient[ 4 ];
|
position { 0.0f, 0.0f, 0.0f, 1.0f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
|
||||||
GLfloat diffuse[ 4 ];
|
ambient { 0.0f, 0.0f, 0.0f, 1.0f },
|
||||||
GLfloat specular[ 4 ];
|
diffuse { 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
specular { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
opengl_light() {
|
|
||||||
position[ 0 ] = position[ 1 ] = position[ 2 ] = 0.0f; position[ 3 ] = 1.0f; // 0,0,0,1
|
|
||||||
ambient[ 0 ] = ambient[ 1 ] = ambient[ 2 ] = 0.0f; ambient[ 3 ] = 1.0f; // 0,0,0,1
|
|
||||||
diffuse[ 0 ] = diffuse[ 1 ] = diffuse[ 2 ] = diffuse[ 3 ] = 1.0f; // 1,1,1,1
|
|
||||||
specular[ 0 ] = specular[ 1 ] = specular[ 2 ] = specular[ 3 ] = 1.0f; // 1,1,1,1
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void apply_intensity( float const Factor = 1.0f ) {
|
void apply_intensity( float const Factor = 1.0f ) {
|
||||||
|
|
||||||
if( Factor == 1.0 ) {
|
if( Factor == 1.0 ) {
|
||||||
|
|
||||||
glLightfv( id, GL_AMBIENT, ambient );
|
glLightfv( id, GL_AMBIENT, glm::value_ptr(ambient) );
|
||||||
glLightfv( id, GL_DIFFUSE, diffuse );
|
glLightfv( id, GL_DIFFUSE, glm::value_ptr(diffuse) );
|
||||||
glLightfv( id, GL_SPECULAR, specular );
|
glLightfv( id, GL_SPECULAR, glm::value_ptr(specular) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// temporary light scaling mechanics (ultimately this work will be left to the shaders
|
// temporary light scaling mechanics (ultimately this work will be left to the shaders
|
||||||
float4 scaledambient( ambient[ 0 ] * Factor, ambient[ 1 ] * Factor, ambient[ 2 ] * Factor, ambient[ 3 ] );
|
glm::vec4 scaledambient( ambient.r * Factor, ambient.g * Factor, ambient.b * Factor, ambient.a );
|
||||||
float4 scaleddiffuse( diffuse[ 0 ] * Factor, diffuse[ 1 ] * Factor, diffuse[ 2 ] * Factor, diffuse[ 3 ] );
|
glm::vec4 scaleddiffuse( diffuse.r * Factor, diffuse.g * Factor, diffuse.b * Factor, diffuse.a );
|
||||||
float4 scaledspecular( specular[ 0 ] * Factor, specular[ 1 ] * Factor, specular[ 2 ] * Factor, specular[ 3 ] );
|
glm::vec4 scaledspecular( specular.r * Factor, specular.g * Factor, specular.b * Factor, specular.a );
|
||||||
glLightfv( id, GL_AMBIENT, &scaledambient.x );
|
glLightfv( id, GL_AMBIENT, glm::value_ptr(scaledambient) );
|
||||||
glLightfv( id, GL_DIFFUSE, &scaleddiffuse.x );
|
glLightfv( id, GL_DIFFUSE, glm::value_ptr(scaleddiffuse) );
|
||||||
glLightfv( id, GL_SPECULAR, &scaledspecular.x );
|
glLightfv( id, GL_SPECULAR, glm::value_ptr(scaledspecular) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
inline
|
||||||
void apply_angle() {
|
void apply_angle() {
|
||||||
|
|
||||||
glLightfv( id, GL_POSITION, position );
|
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
|
||||||
if( position[ 3 ] == 1.0f ) {
|
if( position.w == 1.0f ) {
|
||||||
GLfloat directionarray[] = { (GLfloat)direction.x, (GLfloat)direction.y, (GLfloat)direction.z };
|
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
|
||||||
glLightfv( id, GL_SPOT_DIRECTION, directionarray );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
inline
|
||||||
void set_position( Math3D::vector3 const &Position ) {
|
void set_position( glm::vec3 const &Position ) {
|
||||||
|
|
||||||
position[ 0 ] = Position.x;
|
position = glm::vec4( Position, position.w );
|
||||||
position[ 1 ] = Position.y;
|
|
||||||
position[ 2 ] = Position.z;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -229,6 +220,10 @@ private:
|
|||||||
geometry_handle m_billboardgeometry { 0, 0 };
|
geometry_handle m_billboardgeometry { 0, 0 };
|
||||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||||
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
||||||
|
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
bool m_renderspecular{ false }; // controls whether to include specular component in the calculations
|
||||||
|
float m_specularopaquescalefactor { 1.0f };
|
||||||
|
float m_speculartranslucentscalefactor { 1.0f };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
4
sky.cpp
4
sky.cpp
@@ -27,14 +27,14 @@ void TSky::Init()
|
|||||||
mdCloud = TModelsManager::GetModel( Global::asSky );
|
mdCloud = TModelsManager::GetModel( Global::asSky );
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSky::Render( float3 const &Tint )
|
void TSky::Render( glm::vec3 const &Tint )
|
||||||
{
|
{
|
||||||
if (mdCloud)
|
if (mdCloud)
|
||||||
{ // jeśli jest model nieba
|
{ // jeśli jest model nieba
|
||||||
// setup
|
// setup
|
||||||
::glEnable( GL_LIGHTING );
|
::glEnable( GL_LIGHTING );
|
||||||
GfxRenderer.Disable_Lights();
|
GfxRenderer.Disable_Lights();
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x );
|
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(Tint) );
|
||||||
// render
|
// render
|
||||||
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
|
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
|
||||||
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
|
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
|
||||||
|
|||||||
3
sky.h
3
sky.h
@@ -11,7 +11,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Model3d.h"
|
#include "Model3d.h"
|
||||||
#include "Float3d.h"
|
|
||||||
|
|
||||||
class TSky
|
class TSky
|
||||||
{
|
{
|
||||||
@@ -22,7 +21,7 @@ class TSky
|
|||||||
TSky();
|
TSky();
|
||||||
~TSky();
|
~TSky();
|
||||||
void Init();
|
void Init();
|
||||||
void Render( float3 const &Tint = float3(1.0f, 1.0f, 1.0f) );
|
void Render( glm::vec3 const &Tint = glm::vec3(1.0f, 1.0f, 1.0f) );
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
39
skydome.cpp
39
skydome.cpp
@@ -86,8 +86,8 @@ void CSkyDome::Generate() {
|
|||||||
// m_normals.emplace_back( float3( x * zr, -y * zr, -z ) );
|
// m_normals.emplace_back( float3( x * zr, -y * zr, -z ) );
|
||||||
*/
|
*/
|
||||||
// cartesian to opengl swap: -x, -z, -y
|
// cartesian to opengl swap: -x, -z, -y
|
||||||
m_vertices.emplace_back( float3( -x * zr, -z - offset, -y * zr ) * radius );
|
m_vertices.emplace_back( glm::vec3( -x * zr, -z - offset, -y * zr ) * radius );
|
||||||
m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) ); // placeholder
|
m_colours.emplace_back( glm::vec3( 0.75f, 0.75f, 0.75f ) ); // placeholder
|
||||||
|
|
||||||
if( (i == 0) || (j == 0) ) {
|
if( (i == 0) || (j == 0) ) {
|
||||||
// initial edge of the dome, don't start indices yet
|
// initial edge of the dome, don't start indices yet
|
||||||
@@ -107,7 +107,7 @@ void CSkyDome::Generate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSkyDome::Update( Math3D::vector3 const &Sun ) {
|
void CSkyDome::Update( glm::vec3 const &Sun ) {
|
||||||
|
|
||||||
if( true == SetSunPosition( Sun ) ) {
|
if( true == SetSunPosition( Sun ) ) {
|
||||||
// build colors if there's a change in sun position
|
// build colors if there's a change in sun position
|
||||||
@@ -150,15 +150,14 @@ void CSkyDome::Render() {
|
|||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
::glDisableClientState( GL_VERTEX_ARRAY );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSkyDome::SetSunPosition( Math3D::vector3 const &Direction ) {
|
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {
|
||||||
|
|
||||||
auto sundirection = SafeNormalize( float3( Direction.x, Direction.y, Direction.z) );
|
if( Direction == m_sundirection ) {
|
||||||
if( sundirection == m_sundirection ) {
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sundirection = sundirection;
|
m_sundirection = Direction;
|
||||||
m_thetasun = std::acosf( m_sundirection.y );
|
m_thetasun = std::acosf( m_sundirection.y );
|
||||||
m_phisun = std::atan2( m_sundirection.z, m_sundirection.x );
|
m_phisun = std::atan2( m_sundirection.z, m_sundirection.x );
|
||||||
|
|
||||||
@@ -244,18 +243,18 @@ void CSkyDome::RebuildColors() {
|
|||||||
zenithluminance = PerezFunctionO1( perezluminance, m_thetasun, zenithluminance );
|
zenithluminance = PerezFunctionO1( perezluminance, m_thetasun, zenithluminance );
|
||||||
|
|
||||||
// start with fresh average for the new pass
|
// start with fresh average for the new pass
|
||||||
float3 averagecolor{ 0.0f, 0.0f, 0.0f };
|
glm::vec3 averagecolor { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
// trough all vertices
|
// trough all vertices
|
||||||
float3 vertex;
|
glm::vec3 vertex;
|
||||||
float3 color, colorconverter, shiftedcolor;
|
glm::vec3 color, colorconverter, shiftedcolor;
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < m_vertices.size(); ++i ) {
|
for ( unsigned int i = 0; i < m_vertices.size(); ++i ) {
|
||||||
// grab it
|
// grab it
|
||||||
vertex = SafeNormalize( m_vertices[ i ] );
|
vertex = glm::normalize( m_vertices[ i ] );
|
||||||
|
|
||||||
// angle between sun and vertex
|
// angle between sun and vertex
|
||||||
const float gamma = std::acos( DotProduct( vertex, m_sundirection ) );
|
const float gamma = std::acos( glm::dot( vertex, m_sundirection ) );
|
||||||
|
|
||||||
// warning : major hack!!! .. i had to do something with values under horizon
|
// warning : major hack!!! .. i had to do something with values under horizon
|
||||||
//vertex.y = Clamp<float>( vertex.y, 0.05f, 1.0f );
|
//vertex.y = Clamp<float>( vertex.y, 0.05f, 1.0f );
|
||||||
@@ -283,7 +282,7 @@ void CSkyDome::RebuildColors() {
|
|||||||
float const X = (x / y) * Y;
|
float const X = (x / y) * Y;
|
||||||
float const Z = ((1.0f - x - y) / y) * Y;
|
float const Z = ((1.0f - x - y) / y) * Y;
|
||||||
|
|
||||||
colorconverter = float3( X, Y, Z );
|
colorconverter = glm::vec3( X, Y, Z );
|
||||||
color = XYZtoRGB( colorconverter );
|
color = XYZtoRGB( colorconverter );
|
||||||
|
|
||||||
colorconverter = RGBtoHSV(color);
|
colorconverter = RGBtoHSV(color);
|
||||||
@@ -292,7 +291,7 @@ void CSkyDome::RebuildColors() {
|
|||||||
colorconverter.z *= m_expfactor;
|
colorconverter.z *= m_expfactor;
|
||||||
} else {
|
} else {
|
||||||
// exp scale
|
// exp scale
|
||||||
colorconverter.z = 1.0f - exp( -m_expfactor * colorconverter.z );
|
colorconverter.z = 1.0f - std::exp( -m_expfactor * colorconverter.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
// desaturate sky colour, based on overcast level
|
// desaturate sky colour, based on overcast level
|
||||||
@@ -309,12 +308,12 @@ void CSkyDome::RebuildColors() {
|
|||||||
// this height-based factor is reduced the farther the sky is up in the sky
|
// this height-based factor is reduced the farther the sky is up in the sky
|
||||||
float const shiftfactor = clamp( interpolate(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f );
|
float const shiftfactor = clamp( interpolate(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f );
|
||||||
// h = 210 makes for 'typical' sky tone
|
// h = 210 makes for 'typical' sky tone
|
||||||
shiftedcolor = float3( 210.0f, colorconverter.y, colorconverter.z );
|
shiftedcolor = glm::vec3( 210.0f, colorconverter.y, colorconverter.z );
|
||||||
shiftedcolor = HSVtoRGB( shiftedcolor );
|
shiftedcolor = HSVtoRGB( shiftedcolor );
|
||||||
|
|
||||||
color = HSVtoRGB(colorconverter);
|
color = HSVtoRGB(colorconverter);
|
||||||
|
|
||||||
color = Interpolate( color, shiftedcolor, shiftfactor );
|
color = interpolate( color, shiftedcolor, shiftfactor );
|
||||||
/*
|
/*
|
||||||
// gamma control
|
// gamma control
|
||||||
color.x = std::pow( color.x, m_gammacorrection );
|
color.x = std::pow( color.x, m_gammacorrection );
|
||||||
@@ -338,10 +337,10 @@ void CSkyDome::RebuildColors() {
|
|||||||
}
|
}
|
||||||
// NOTE: average reduced to 25% makes nice tint value for clouds lit from behind
|
// NOTE: average reduced to 25% makes nice tint value for clouds lit from behind
|
||||||
// down the road we could interpolate between it and full strength average, to improve accuracy of cloud appearance
|
// down the road we could interpolate between it and full strength average, to improve accuracy of cloud appearance
|
||||||
m_averagecolour = averagecolor / m_indices.size();
|
m_averagecolour = averagecolor / static_cast<float>( m_indices.size() );
|
||||||
m_averagecolour.x = std::max( m_averagecolour.x, 0.0f );
|
m_averagecolour.r = std::max( m_averagecolour.r, 0.0f );
|
||||||
m_averagecolour.y = std::max( m_averagecolour.y, 0.0f );
|
m_averagecolour.g = std::max( m_averagecolour.g, 0.0f );
|
||||||
m_averagecolour.z = std::max( m_averagecolour.z, 0.0f );
|
m_averagecolour.b = std::max( m_averagecolour.b, 0.0f );
|
||||||
|
|
||||||
if( m_coloursbuffer != -1 ) {
|
if( m_coloursbuffer != -1 ) {
|
||||||
// the colour buffer was already initialized, so on this run we update its content
|
// the colour buffer was already initialized, so on this run we update its content
|
||||||
|
|||||||
17
skydome.h
17
skydome.h
@@ -1,8 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dumb3d.h"
|
|
||||||
#include "float3d.h"
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
||||||
@@ -13,7 +10,7 @@ public:
|
|||||||
void Generate();
|
void Generate();
|
||||||
void RebuildColors();
|
void RebuildColors();
|
||||||
|
|
||||||
bool SetSunPosition( Math3D::vector3 const &Direction );
|
bool SetSunPosition( glm::vec3 const &Direction );
|
||||||
|
|
||||||
void SetTurbidity( const float Turbidity = 5.0f );
|
void SetTurbidity( const float Turbidity = 5.0f );
|
||||||
void SetExposure( const bool Linearexposure, const float Expfactor );
|
void SetExposure( const bool Linearexposure, const float Expfactor );
|
||||||
@@ -21,30 +18,30 @@ public:
|
|||||||
void SetGammaCorrection( const float Gamma = 2.2f );
|
void SetGammaCorrection( const float Gamma = 2.2f );
|
||||||
|
|
||||||
// update skydome
|
// update skydome
|
||||||
void Update( Math3D::vector3 const &Sun );
|
void Update( glm::vec3 const &Sun );
|
||||||
// render skydome to screen
|
// render skydome to screen
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
// retrieves average colour of the sky dome
|
// retrieves average colour of the sky dome
|
||||||
float3 GetAverageColor() { return m_averagecolour; }
|
glm::vec3 GetAverageColor() { return m_averagecolour; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// shading parametrs
|
// shading parametrs
|
||||||
float3 m_sundirection;
|
glm::vec3 m_sundirection;
|
||||||
float m_thetasun, m_phisun;
|
float m_thetasun, m_phisun;
|
||||||
float m_turbidity;
|
float m_turbidity;
|
||||||
bool m_linearexpcontrol;
|
bool m_linearexpcontrol;
|
||||||
float m_expfactor;
|
float m_expfactor;
|
||||||
float m_overcast;
|
float m_overcast;
|
||||||
float m_gammacorrection;
|
float m_gammacorrection;
|
||||||
float3 m_averagecolour;
|
glm::vec3 m_averagecolour;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
int const m_tesselation;
|
int const m_tesselation;
|
||||||
std::vector<float3> m_vertices;
|
std::vector<glm::vec3> m_vertices;
|
||||||
std::vector<std::uint16_t> m_indices;
|
std::vector<std::uint16_t> m_indices;
|
||||||
// std::vector<float3> m_normals;
|
// std::vector<float3> m_normals;
|
||||||
std::vector<float3> m_colours;
|
std::vector<glm::vec3> m_colours;
|
||||||
GLuint m_vertexbuffer{ (GLuint)-1 };
|
GLuint m_vertexbuffer{ (GLuint)-1 };
|
||||||
GLuint m_indexbuffer{ (GLuint)-1 };
|
GLuint m_indexbuffer{ (GLuint)-1 };
|
||||||
GLuint m_coloursbuffer{ (GLuint)-1 };
|
GLuint m_coloursbuffer{ (GLuint)-1 };
|
||||||
|
|||||||
14
sun.cpp
14
sun.cpp
@@ -33,9 +33,9 @@ void
|
|||||||
cSun::update() {
|
cSun::update() {
|
||||||
|
|
||||||
move();
|
move();
|
||||||
Math3D::vector3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||||
position.RotateY( (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = position;
|
||||||
}
|
}
|
||||||
@@ -63,14 +63,10 @@ cSun::render() {
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
Math3D::vector3
|
glm::vec3
|
||||||
cSun::getDirection() {
|
cSun::getDirection() {
|
||||||
|
|
||||||
Math3D::vector3 position( 0.f, 0.f, -1.f );
|
return glm::normalize( m_position );
|
||||||
position.RotateX( (float)( m_body.elevref * (M_PI/180.0)) );
|
|
||||||
position.RotateY( (float)( -m_body.hrang * (M_PI/180.0)) );
|
|
||||||
position.Normalize();
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
|
|||||||
7
sun.h
7
sun.h
@@ -3,7 +3,6 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
#include "GL/wglew.h"
|
#include "GL/wglew.h"
|
||||||
#include "dumb3d.h"
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -20,9 +19,9 @@ public:
|
|||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
// returns location of the sun in the 3d scene
|
// returns location of the sun in the 3d scene
|
||||||
Math3D::vector3 getPosition() { return m_position; }
|
glm::vec3 getPosition() { return m_position; }
|
||||||
// returns vector pointing at the sun
|
// returns vector pointing at the sun
|
||||||
Math3D::vector3 getDirection();
|
glm::vec3 getDirection();
|
||||||
// returns current elevation above horizon
|
// returns current elevation above horizon
|
||||||
float getAngle();
|
float getAngle();
|
||||||
// returns current intensity of the sun
|
// returns current intensity of the sun
|
||||||
@@ -98,5 +97,5 @@ protected:
|
|||||||
|
|
||||||
celestialbody m_body;
|
celestialbody m_body;
|
||||||
observer m_observer;
|
observer m_observer;
|
||||||
Math3D::vector3 m_position;
|
glm::vec3 m_position;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user