mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
merge, fixed, sort of works (todo: fix cabin light, stars and fog)
This commit is contained in:
20
DynObj.cpp
20
DynObj.cpp
@@ -539,11 +539,10 @@ TDynamicObject::toggle_lights() {
|
||||
SectionLightsActive = false;
|
||||
}
|
||||
else {
|
||||
std::string compartmentname;
|
||||
// set lights with probability depending on the compartment type. TODO: expose this in .mmd file
|
||||
for( auto §ionlight : SectionLightLevels ) {
|
||||
|
||||
compartmentname = sectionlight.compartment->pName;
|
||||
std::string const &compartmentname = sectionlight.compartment->pName;
|
||||
if( ( compartmentname.find( "corridor" ) != std::string::npos )
|
||||
|| ( compartmentname.find( "korytarz" ) != std::string::npos ) ) {
|
||||
// corridors are lit 100% of time
|
||||
@@ -584,8 +583,9 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
pAnimations[i].yUpdate(pAnimations +
|
||||
i); // aktualizacja animacji (położenia submodeli
|
||||
*/
|
||||
if( ObjSqrDist < 2500 ) // gdy bliżej niż 50m
|
||||
{
|
||||
if( ( mdModel != nullptr )
|
||||
&& ( ObjSqrDist < 2500 ) ) {
|
||||
// gdy bliżej niż 50m
|
||||
// ABu290105: rzucanie pudlem
|
||||
// te animacje wymagają bananów w modelach!
|
||||
mdModel->GetSMRoot()->SetTranslate(modelShake);
|
||||
@@ -4033,12 +4033,17 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
bool Stop_InternalData = false;
|
||||
pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów
|
||||
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, BaseDir );
|
||||
if( false == parser.ok() ) {
|
||||
ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name );
|
||||
return;
|
||||
}
|
||||
std::string token;
|
||||
do {
|
||||
token = "";
|
||||
parser.getTokens(); parser >> token;
|
||||
|
||||
if( token == "models:") {
|
||||
if( ( token == "models:" )
|
||||
|| ( token == "\xef\xbb\xbfmodels:" ) ) { // crude way to handle utf8 bom potentially appearing before the first token
|
||||
// modele i podmodele
|
||||
m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych?
|
||||
parser.getTokens();
|
||||
@@ -5024,13 +5029,12 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
|
||||
if (mdModel)
|
||||
mdModel->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie
|
||||
// binarnego
|
||||
mdModel->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego
|
||||
if (mdLoad)
|
||||
mdLoad->Init();
|
||||
if (mdLowPolyInt)
|
||||
mdLowPolyInt->Init();
|
||||
// sHorn2.CopyIfEmpty(sHorn1); ///żeby jednak trąbił też drugim
|
||||
|
||||
Global::asCurrentTexturePath = szTexturePath; // kiedyś uproszczone wnętrze mieszało tekstury nieba
|
||||
}
|
||||
|
||||
|
||||
22
Globals.cpp
22
Globals.cpp
@@ -83,10 +83,12 @@ double Global::fFogStart = 1700;
|
||||
double Global::fFogEnd = 2000;
|
||||
float Global::Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||
int Global::DynamicLightCount = 7;
|
||||
GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f};
|
||||
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::ScaleSpecularValues = false;
|
||||
//m7todo: po co to?
|
||||
//GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f};
|
||||
//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::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
||||
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
||||
@@ -223,13 +225,6 @@ std::string Global::GetNextSymbol()
|
||||
|
||||
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 );
|
||||
FreeCameraInitAngle.resize( 10 );
|
||||
cParser parser(asFileName, cParser::buffer_FILE);
|
||||
@@ -536,6 +531,11 @@ void Global::ConfigParse(cParser &Parser)
|
||||
// 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 );
|
||||
}
|
||||
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")
|
||||
{
|
||||
// podwójna jasność ambient
|
||||
|
||||
@@ -224,11 +224,8 @@ class Global
|
||||
|
||||
// TODO: put these things in the renderer
|
||||
static int DynamicLightCount;
|
||||
static bool ScaleSpecularValues;
|
||||
|
||||
static GLfloat whiteLight[];
|
||||
static GLfloat noLight[];
|
||||
static GLfloat darkLight[];
|
||||
static GLfloat lightPos[4];
|
||||
static int iSlowMotion;
|
||||
static TDynamicObject *changeDynObj;
|
||||
static double ABuDebug;
|
||||
|
||||
@@ -1937,7 +1937,7 @@ bool TGround::Init(std::string File)
|
||||
>> Global::daylight.direction.x
|
||||
>> Global::daylight.direction.y
|
||||
>> Global::daylight.direction.z;
|
||||
|
||||
Global::daylight.direction = glm::normalize(Global::daylight.direction);
|
||||
parser.getTokens(9, false);
|
||||
|
||||
do {
|
||||
|
||||
76
Model3d.cpp
76
Model3d.cpp
@@ -244,8 +244,13 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
if (eType < TP_ROTATOR)
|
||||
readColor(parser, f4Ambient); // ignoruje token przed
|
||||
readColor(parser, f4Diffuse);
|
||||
if (eType < TP_ROTATOR)
|
||||
readColor(parser, f4Specular);
|
||||
if( eType < TP_ROTATOR ) {
|
||||
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:"
|
||||
{
|
||||
std::string light = parser.getToken<std::string>();
|
||||
@@ -371,6 +376,10 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
readMatrix(parser, *fMatrix); // wczytanie transform
|
||||
if (!fMatrix->IdentityIs())
|
||||
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)
|
||||
{ // wczytywanie wierzchołków
|
||||
parser.getTokens(2, false);
|
||||
@@ -450,7 +459,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
--facecount; // o jeden trójkąt mniej
|
||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||
i -= 3; // wczytanie kolejnego w to miejsce
|
||||
WriteLog("Degenerated triangle ignored in: \"" + pName + "\", vertice " + std::to_string(i));
|
||||
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(i) + "-" + std::to_string(i+2));
|
||||
}
|
||||
if (i > 0) {
|
||||
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
||||
@@ -462,7 +471,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
--facecount; // o jeden trójkąt mniej
|
||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||
i -= 3; // wczytanie kolejnego w to miejsce
|
||||
WriteLog( "Too large triangle ignored in: \"" + pName + "\"" );
|
||||
WriteLog( "Bad model: too large triangle ignored in: \"" + pName + "\"" );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,7 +487,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 + 2 ].position );
|
||||
facenormals.emplace_back(
|
||||
glm::length( facenormal ) > 0.0f ?
|
||||
glm::length2( facenormal ) > 0.0f ?
|
||||
glm::normalize( facenormal ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
@@ -496,16 +505,24 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
auto adjacenvertextidx = vertexidx; // zaczynamy dodawanie wektorów normalnych od własnego
|
||||
while (adjacenvertextidx >= 0) {
|
||||
// sumowanie z wektorem normalnym sąsiada (włącznie ze sobą)
|
||||
wsp[adjacenvertextidx] = vertexidx; // informacja, że w tym wierzchołku jest już policzony wektor normalny
|
||||
vertexnormal += facenormals[adjacenvertextidx / 3];
|
||||
if( glm::dot( vertexnormal, facenormals[ adjacenvertextidx / 3 ] ) > -0.99f ) {
|
||||
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
|
||||
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
|
||||
if( glm::length2( vertexnormal ) == 0.0f ) {
|
||||
WriteLog( "Bad model: zero lenght normal vector generated for sub-model \"" + pName + "\"" );
|
||||
}
|
||||
Vertices[ vertexidx ].normal = (
|
||||
glm::length( vertexnormal ) > 0.0f ?
|
||||
glm::length2( vertexnormal ) > 0.0f ?
|
||||
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
|
||||
@@ -1517,6 +1534,15 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||
iNumVerts += submodel.iNumVerts;
|
||||
for( auto &vertex : vertices ) {
|
||||
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
|
||||
int type;
|
||||
@@ -1600,6 +1626,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
|
||||
Next = (iNext > 0) ? s + iNext : nullptr; // zerowy nie może być następnym
|
||||
fMatrix = ((iMatrix >= 0) && m) ? m + iMatrix : nullptr;
|
||||
|
||||
if (n->size() && (iName >= 0))
|
||||
{
|
||||
pName = n->at(iName);
|
||||
@@ -1613,12 +1640,16 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
// obiektem "Light_Off"
|
||||
else if (dynamic)
|
||||
{ // inaczej wyłączało smugę w latarniach
|
||||
if ((pName.size() >= 3) && (pName.substr(pName.size() - 3, 3) == "_on"))
|
||||
{ // jeśli jest kontrolką w stanie zapalonym
|
||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z
|
||||
if ((pName.size() >= 3) && (pName.substr(pName.size() - 3, 3) == "_on")) {
|
||||
// jeśli jest kontrolką w stanie zapalonym to domyślnie wyłączyć,
|
||||
// ż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
|
||||
@@ -1655,11 +1686,22 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
if( fCosHotspotAngle > 1.0f ) {
|
||||
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)
|
||||
/*
|
||||
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)
|
||||
|
||||
@@ -96,6 +96,7 @@ private:
|
||||
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
||||
f4Specular { 0.0f,0.0f,0.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 fSquareMaxDist { 10000.0f * 10000.0f };
|
||||
float fSquareMinDist { 0.0f };
|
||||
|
||||
16
World.cpp
16
World.cpp
@@ -2271,34 +2271,32 @@ world_environment::update() {
|
||||
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
||||
float keylightintensity;
|
||||
float twilightfactor;
|
||||
float3 keylightcolor;
|
||||
glm::vec3 keylightcolor;
|
||||
if( moonlightlevel > sunlightlevel ) {
|
||||
// rare situations when the moon is brighter than the sun, typically at night
|
||||
Global::SunAngle = m_moon.getAngle();
|
||||
Math3D::vector3 moon_dir = -1.0 * m_moon.getDirection();
|
||||
Global::daylight.direction = glm::vec3(moon_dir.x, moon_dir.y, moon_dir.z);
|
||||
Global::daylight.direction = -1.0f * m_moon.getDirection();
|
||||
keylightintensity = moonlightlevel;
|
||||
// if the moon is up, it overrides the twilight
|
||||
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 {
|
||||
// regular situation with sun as the key light
|
||||
Global::SunAngle = m_sun.getAngle();
|
||||
Math3D::vector3 sun_dir = -1.0 * m_sun.getDirection();
|
||||
Global::daylight.direction = glm::vec3(sun_dir.x, sun_dir.y, sun_dir.z);
|
||||
Global::daylight.direction = -1.0f * m_sun.getDirection();
|
||||
keylightintensity = sunlightlevel;
|
||||
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
||||
twilightfactor = 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(
|
||||
float3( 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( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||
glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
||||
duskfactor );
|
||||
}
|
||||
// ...update skydome to match the current sun position as well...
|
||||
m_skydome.SetOvercastFactor( Global::Overcast );
|
||||
m_skydome.Update( m_sun.getPosition() );
|
||||
m_skydome.Update( m_sun.getDirection() );
|
||||
// ...retrieve current sky colour and brightness...
|
||||
auto const skydomecolour = m_skydome.GetAverageColor();
|
||||
auto const skydomehsv = RGBtoHSV( skydomecolour );
|
||||
|
||||
74
color.h
74
color.h
@@ -3,28 +3,28 @@
|
||||
#include "float3d.h"
|
||||
|
||||
inline
|
||||
float3
|
||||
XYZtoRGB( float3 const &XYZ ) {
|
||||
glm::vec3
|
||||
XYZtoRGB( glm::vec3 const &XYZ ) {
|
||||
|
||||
// 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 };
|
||||
// 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 };
|
||||
|
||||
return float3{
|
||||
return glm::vec3{
|
||||
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 ][ 2 ] + XYZ.y*mi[ 1 ][ 2 ] + XYZ.z*mi[ 2 ][ 2 ] };
|
||||
}
|
||||
|
||||
inline
|
||||
float3
|
||||
RGBtoHSV( float3 const &RGB ) {
|
||||
glm::vec3
|
||||
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 min = std::min( std::min( 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.r, RGB.g ), RGB.b );
|
||||
float const delta = max - min;
|
||||
|
||||
hsv.z = max; // v
|
||||
@@ -43,13 +43,13 @@ RGBtoHSV( float3 const &RGB ) {
|
||||
hsv.x = NAN; // its now undefined
|
||||
return hsv;
|
||||
}
|
||||
if( RGB.x >= max ) // > is bogus, just keeps compilor happy
|
||||
hsv.x = ( RGB.y - RGB.z ) / delta; // between yellow & magenta
|
||||
if( RGB.r >= max ) // > is bogus, just keeps compilor happy
|
||||
hsv.x = ( RGB.g - RGB.b ) / delta; // between yellow & magenta
|
||||
else
|
||||
if( RGB.y >= max )
|
||||
hsv.x = 2.0 + ( RGB.y - RGB.x ) / delta; // between cyan & yellow
|
||||
if( RGB.g >= max )
|
||||
hsv.x = 2.0 + ( RGB.g - RGB.r ) / delta; // between cyan & yellow
|
||||
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
|
||||
|
||||
@@ -60,15 +60,15 @@ RGBtoHSV( float3 const &RGB ) {
|
||||
}
|
||||
|
||||
inline
|
||||
float3
|
||||
HSVtoRGB( float3 const &HSV ) {
|
||||
glm::vec3
|
||||
HSVtoRGB( glm::vec3 const &HSV ) {
|
||||
|
||||
float3 rgb;
|
||||
glm::vec3 rgb;
|
||||
|
||||
if( HSV.y <= 0.0 ) { // < is bogus, just shuts up warnings
|
||||
rgb.x = HSV.z;
|
||||
rgb.y = HSV.z;
|
||||
rgb.z = HSV.z;
|
||||
rgb.r = HSV.z;
|
||||
rgb.g = HSV.z;
|
||||
rgb.b = HSV.z;
|
||||
return rgb;
|
||||
}
|
||||
float hh = HSV.x;
|
||||
@@ -82,36 +82,36 @@ HSVtoRGB( float3 const &HSV ) {
|
||||
|
||||
switch( i ) {
|
||||
case 0:
|
||||
rgb.x = HSV.z;
|
||||
rgb.y = t;
|
||||
rgb.z = p;
|
||||
rgb.r = HSV.z;
|
||||
rgb.g = t;
|
||||
rgb.b = p;
|
||||
break;
|
||||
case 1:
|
||||
rgb.x = q;
|
||||
rgb.y = HSV.z;
|
||||
rgb.z = p;
|
||||
rgb.r = q;
|
||||
rgb.g = HSV.z;
|
||||
rgb.b = p;
|
||||
break;
|
||||
case 2:
|
||||
rgb.x = p;
|
||||
rgb.y = HSV.z;
|
||||
rgb.z = t;
|
||||
rgb.r = p;
|
||||
rgb.g = HSV.z;
|
||||
rgb.b = t;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
rgb.x = p;
|
||||
rgb.y = q;
|
||||
rgb.z = HSV.z;
|
||||
rgb.r = p;
|
||||
rgb.g = q;
|
||||
rgb.b = HSV.z;
|
||||
break;
|
||||
case 4:
|
||||
rgb.x = t;
|
||||
rgb.y = p;
|
||||
rgb.z = HSV.z;
|
||||
rgb.r = t;
|
||||
rgb.g = p;
|
||||
rgb.b = HSV.z;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
rgb.x = HSV.z;
|
||||
rgb.y = p;
|
||||
rgb.z = q;
|
||||
rgb.r = HSV.z;
|
||||
rgb.g = p;
|
||||
rgb.b = q;
|
||||
break;
|
||||
}
|
||||
return rgb;
|
||||
|
||||
@@ -47,12 +47,12 @@ light_array::update() {
|
||||
if( light.index == 0 ) {
|
||||
// front light set
|
||||
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 {
|
||||
// rear light set
|
||||
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.z = -light.direction.z;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
TDynamicObject const *owner; // the object in world which 'carries' the light
|
||||
int index{ -1 }; // 0: front lights, 1: rear lights
|
||||
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
|
||||
float intensity{ 0.0f }; // (combined) intensity of the 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() {
|
||||
|
||||
move();
|
||||
Math3D::vector3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position.RotateY( (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||
|
||||
m_position = position;
|
||||
}
|
||||
@@ -59,14 +59,10 @@ cMoon::render() {
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
Math3D::vector3
|
||||
glm::vec3
|
||||
cMoon::getDirection() {
|
||||
|
||||
Math3D::vector3 position( 0.f, 0.f, -1.f );
|
||||
position.RotateX( (float)( m_body.elevref * (M_PI/180.0)) );
|
||||
position.RotateY( (float)( -m_body.hrang * (M_PI/180.0)) );
|
||||
position.Normalize();
|
||||
return position;
|
||||
return glm::normalize( m_position );
|
||||
}
|
||||
|
||||
float
|
||||
|
||||
7
moon.h
7
moon.h
@@ -3,7 +3,6 @@
|
||||
#include "windows.h"
|
||||
#include "GL/glew.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
|
||||
@@ -18,9 +17,9 @@ public:
|
||||
void update();
|
||||
void render();
|
||||
// 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
|
||||
Math3D::vector3 getDirection();
|
||||
glm::vec3 getDirection();
|
||||
// returns current elevation above horizon
|
||||
float getAngle() const;
|
||||
// returns current intensity of the sun
|
||||
@@ -101,6 +100,6 @@ protected:
|
||||
|
||||
celestialbody m_body;
|
||||
observer m_observer;
|
||||
Math3D::vector3 m_position;
|
||||
glm::vec3 m_position;
|
||||
float m_phase;
|
||||
};
|
||||
|
||||
@@ -50,8 +50,13 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
|
||||
// calculate stream size
|
||||
if (mStream)
|
||||
{
|
||||
mSize = mStream->rdbuf()->pubseekoff(0, std::ios_base::end);
|
||||
mStream->rdbuf()->pubseekoff(0, std::ios_base::beg);
|
||||
if( true == mStream->fail() ) {
|
||||
ErrorLog( "Failed to open file \"" + Path + "\"" );
|
||||
}
|
||||
else {
|
||||
mSize = mStream->rdbuf()->pubseekoff( 0, std::ios_base::end );
|
||||
mStream->rdbuf()->pubseekoff( 0, std::ios_base::beg );
|
||||
}
|
||||
}
|
||||
else
|
||||
mSize = 0;
|
||||
|
||||
84
renderer.cpp
84
renderer.cpp
@@ -25,6 +25,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
opengl_renderer GfxRenderer;
|
||||
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
|
||||
bool
|
||||
opengl_camera::visible( bounding_area const &Area ) const {
|
||||
@@ -75,14 +81,19 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
glPointSize( 3.0f );
|
||||
glEnable( GL_POINT_SMOOTH );
|
||||
|
||||
glEnable( GL_COLOR_MATERIAL );
|
||||
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
||||
::glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR );
|
||||
::glMaterialf( GL_FRONT, GL_SHININESS, 15.0f );
|
||||
if( true == Global::ScaleSpecularValues ) {
|
||||
m_specularopaquescalefactor = 0.25f;
|
||||
m_speculartranslucentscalefactor = 1.5f;
|
||||
}
|
||||
::glEnable( GL_COLOR_MATERIAL );
|
||||
::glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
||||
|
||||
// setup lighting
|
||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
||||
glEnable( GL_LIGHTING );
|
||||
glEnable( GL_LIGHT0 );
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
||||
::glEnable( GL_LIGHTING );
|
||||
::glEnable( GL_LIGHT0 );
|
||||
|
||||
// directional light
|
||||
// TODO, TBD: test omni-directional variant
|
||||
@@ -207,9 +218,9 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
Environment->m_stars.render();
|
||||
|
||||
float const duskfactor = 1.0f - clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
|
||||
float3 suncolor = interpolate(
|
||||
float3( 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 suncolor = interpolate(
|
||||
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||
glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
|
||||
duskfactor );
|
||||
|
||||
if( DebugModeFlag == true ) {
|
||||
@@ -250,11 +261,10 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
// moon
|
||||
{
|
||||
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 ) );
|
||||
|
||||
auto const moonvector = Environment->m_moon.getDirection();
|
||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
||||
auto const moonposition = modelview * glm::vec4( Environment->m_moon.getDirection(), 1.0f );
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity(); // macierz jedynkowa
|
||||
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
||||
@@ -621,6 +631,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::daylight.intensity = Dynamic->fShade;
|
||||
}
|
||||
m_renderspecular = true; // vehicles are rendered with specular component. static models without, at least for the time being
|
||||
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
@@ -638,18 +649,19 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
// reset the overall ambient
|
||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
if( Dynamic->mdModel )
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||
|
||||
// post-render cleanup
|
||||
m_renderspecular = false;
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
// restore regular light level
|
||||
Global::daylight.intensity = 1.0f;
|
||||
@@ -760,18 +772,14 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
}
|
||||
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
||||
// ...luminance
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
World.shader.set_material(glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a);
|
||||
}
|
||||
|
||||
World.shader.set_material(Submodel->f4Specular.x * m_speculartranslucentscalefactor,
|
||||
Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f));
|
||||
|
||||
// main draw call
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
|
||||
if (Global::fLuminance < Submodel->fLight)
|
||||
World.shader.set_material(glm::vec3(0.0f));
|
||||
World.shader.set_material(0.0f, glm::vec3(0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,6 +1090,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::daylight.intensity = Dynamic->fShade;
|
||||
}
|
||||
m_renderspecular = true;
|
||||
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
@@ -1099,18 +1108,19 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
// reset the overall ambient
|
||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Render_Alpha( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
if( Dynamic->mdModel )
|
||||
Render_Alpha( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||
|
||||
// post-render cleanup
|
||||
m_renderspecular = false;
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
// restore regular light level
|
||||
Global::daylight.intensity = 1.0f;
|
||||
@@ -1204,21 +1214,16 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
}
|
||||
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
||||
// ...luminance
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
World.shader.set_material(glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a);
|
||||
}
|
||||
|
||||
World.shader.set_material(Submodel->f4Specular.x * m_speculartranslucentscalefactor,
|
||||
Global::fLuminance < Submodel->fLight ? glm::vec3(Submodel->f4Diffuse) * Submodel->f4Emision.a : glm::vec3(0.0f));
|
||||
|
||||
// main draw call
|
||||
m_geometry.draw(Submodel->m_geometry);
|
||||
|
||||
if (Global::fLuminance < Submodel->fLight)
|
||||
World.shader.set_material(glm::vec3(0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
World.shader.set_material(0.0f, glm::vec3(0.0f));
|
||||
}
|
||||
}
|
||||
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
|
||||
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
@@ -1381,11 +1386,12 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
// but there could still be weaker lights which are closer, so keep looking
|
||||
continue;
|
||||
}
|
||||
// if the light passed tests so far, it's good enough
|
||||
|
||||
// if the light passed tests so far, it's good enough
|
||||
Math3D::vector3 pos = scenelight.position - Global::pCameraPosition;
|
||||
|
||||
auto const luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||
glm::vec3 position(scenelight.position.x, scenelight.position.y, scenelight.position.z);
|
||||
glm::vec3 position(pos.x, pos.y, pos.z);
|
||||
glm::vec3 direction(scenelight.direction.x, scenelight.direction.y, scenelight.direction.z);
|
||||
glm::vec3 color(scenelight.color.x,
|
||||
scenelight.color.y,
|
||||
|
||||
@@ -178,6 +178,10 @@ private:
|
||||
geometry_handle m_billboardgeometry { 0, 0 };
|
||||
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
|
||||
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 };
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
|
||||
{
|
||||
ambient_uniform = glGetUniformLocation(id, "ambient");
|
||||
emission_uniform = glGetUniformLocation(id, "emission");
|
||||
specular_uniform = glGetUniformLocation(id, "specular");
|
||||
lcount_uniform = glGetUniformLocation(id, "lights_count");
|
||||
|
||||
for (size_t i = 0; i < MAX_LIGHTS; i++)
|
||||
@@ -131,6 +132,7 @@ gl_program_light::gl_program_light(std::vector<gl_shader> v) : gl_program_mvp(v)
|
||||
glUseProgram(id);
|
||||
glUniform3f(ambient_uniform, 0.0f, 0.0f, 0.0f);
|
||||
glUniform3f(emission_uniform, 0.0f, 0.0f, 0.0f);
|
||||
glUniform1f(specular_uniform, 0.0f);
|
||||
glUniform1ui(lcount_uniform, 0);
|
||||
}
|
||||
|
||||
@@ -166,8 +168,9 @@ void gl_program_light::set_light(GLuint i, type t, glm::vec3 &pos, glm::vec3 &di
|
||||
glUniform1f(lights_uniform[i].quadratic, quadratic);
|
||||
}
|
||||
|
||||
void gl_program_light::set_material(glm::vec3 &emission)
|
||||
void gl_program_light::set_material(float specular, glm::vec3 &emission)
|
||||
{
|
||||
glUseProgram(id);
|
||||
glUniform1f(specular_uniform, specular);
|
||||
glUniform3fv(emission_uniform, 1, glm::value_ptr(emission));
|
||||
}
|
||||
3
shader.h
3
shader.h
@@ -56,13 +56,14 @@ public:
|
||||
gl_program_light(std::vector<gl_shader>);
|
||||
|
||||
void set_ambient(glm::vec3 &ambient);
|
||||
void set_material(glm::vec3 &emission);
|
||||
void set_material(float specular, glm::vec3 &emission);
|
||||
void set_light_count(GLuint count);
|
||||
void set_light(GLuint id, type t, glm::vec3 &pos, glm::vec3 &dir, float in_cutoff, float out_cutoff,
|
||||
glm::vec3 &color, float linear, float quadratic);
|
||||
|
||||
private:
|
||||
GLuint ambient_uniform;
|
||||
GLuint specular_uniform;
|
||||
GLuint emission_uniform;
|
||||
GLuint lcount_uniform;
|
||||
struct light_s
|
||||
|
||||
4
sky.cpp
4
sky.cpp
@@ -27,14 +27,14 @@ void TSky::Init()
|
||||
mdCloud = TModelsManager::GetModel( Global::asSky );
|
||||
};
|
||||
|
||||
void TSky::Render( float3 const &Tint )
|
||||
void TSky::Render( glm::vec3 const &Tint )
|
||||
{
|
||||
if (mdCloud)
|
||||
{ // jeśli jest model nieba
|
||||
// setup
|
||||
::glEnable( GL_LIGHTING );
|
||||
GfxRenderer.Disable_Lights();
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x );
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(Tint) );
|
||||
// render
|
||||
GfxRenderer.Render( 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
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "Float3d.h"
|
||||
|
||||
class TSky
|
||||
{
|
||||
@@ -22,7 +21,7 @@ class TSky
|
||||
TSky();
|
||||
~TSky();
|
||||
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
@@ -101,8 +101,8 @@ void CSkyDome::Generate() {
|
||||
// m_normals.emplace_back( float3( x * zr, -y * zr, -z ) );
|
||||
*/
|
||||
// cartesian to opengl swap: -x, -z, -y
|
||||
m_vertices.emplace_back( float3( -x * zr, -z - offset, -y * zr ) * radius );
|
||||
m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) ); // placeholder
|
||||
m_vertices.emplace_back( glm::vec3( -x * zr, -z - offset, -y * zr ) * radius );
|
||||
m_colours.emplace_back( glm::vec3( 0.75f, 0.75f, 0.75f ) ); // placeholder
|
||||
|
||||
if( (i == 0) || (j == 0) ) {
|
||||
// initial edge of the dome, don't start indices yet
|
||||
@@ -122,7 +122,7 @@ void CSkyDome::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
void CSkyDome::Update( Math3D::vector3 const &Sun ) {
|
||||
void CSkyDome::Update( glm::vec3 const &Sun ) {
|
||||
|
||||
if( true == SetSunPosition( Sun ) ) {
|
||||
// build colors if there's a change in sun position
|
||||
@@ -173,15 +173,14 @@ void CSkyDome::Render() {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
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( sundirection == m_sundirection ) {
|
||||
if( Direction == m_sundirection ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sundirection = sundirection;
|
||||
m_sundirection = Direction;
|
||||
m_thetasun = std::acosf( m_sundirection.y );
|
||||
m_phisun = std::atan2( m_sundirection.z, m_sundirection.x );
|
||||
|
||||
@@ -267,18 +266,18 @@ void CSkyDome::RebuildColors() {
|
||||
zenithluminance = PerezFunctionO1( perezluminance, m_thetasun, zenithluminance );
|
||||
|
||||
// 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
|
||||
float3 vertex;
|
||||
float3 color, colorconverter, shiftedcolor;
|
||||
glm::vec3 vertex;
|
||||
glm::vec3 color, colorconverter, shiftedcolor;
|
||||
|
||||
for ( unsigned int i = 0; i < m_vertices.size(); ++i ) {
|
||||
// grab it
|
||||
vertex = SafeNormalize( m_vertices[ i ] );
|
||||
vertex = glm::normalize( m_vertices[ i ] );
|
||||
|
||||
// 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
|
||||
//vertex.y = Clamp<float>( vertex.y, 0.05f, 1.0f );
|
||||
@@ -306,7 +305,7 @@ void CSkyDome::RebuildColors() {
|
||||
float const X = (x / 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 );
|
||||
|
||||
colorconverter = RGBtoHSV(color);
|
||||
@@ -315,7 +314,7 @@ void CSkyDome::RebuildColors() {
|
||||
colorconverter.z *= m_expfactor;
|
||||
} else {
|
||||
// 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
|
||||
@@ -332,12 +331,12 @@ void CSkyDome::RebuildColors() {
|
||||
// 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 );
|
||||
// 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 );
|
||||
|
||||
color = HSVtoRGB(colorconverter);
|
||||
|
||||
color = Interpolate( color, shiftedcolor, shiftfactor );
|
||||
color = interpolate( color, shiftedcolor, shiftfactor );
|
||||
/*
|
||||
// gamma control
|
||||
color.x = std::pow( color.x, m_gammacorrection );
|
||||
@@ -361,10 +360,10 @@ void CSkyDome::RebuildColors() {
|
||||
}
|
||||
// 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
|
||||
m_averagecolour = averagecolor / m_indices.size();
|
||||
m_averagecolour.x = std::max( m_averagecolour.x, 0.0f );
|
||||
m_averagecolour.y = std::max( m_averagecolour.y, 0.0f );
|
||||
m_averagecolour.z = std::max( m_averagecolour.z, 0.0f );
|
||||
m_averagecolour = averagecolor / static_cast<float>( m_indices.size() );
|
||||
m_averagecolour.r = std::max( m_averagecolour.r, 0.0f );
|
||||
m_averagecolour.g = std::max( m_averagecolour.g, 0.0f );
|
||||
m_averagecolour.b = std::max( m_averagecolour.b, 0.0f );
|
||||
|
||||
if( m_coloursbuffer != -1 ) {
|
||||
// the colour buffer was already initialized, so on this run we update its content
|
||||
|
||||
14
skydome.h
14
skydome.h
@@ -14,7 +14,7 @@ public:
|
||||
void Generate();
|
||||
void RebuildColors();
|
||||
|
||||
bool SetSunPosition( Math3D::vector3 const &Direction );
|
||||
bool SetSunPosition( glm::vec3 const &Direction );
|
||||
|
||||
void SetTurbidity( const float Turbidity = 5.0f );
|
||||
void SetExposure( const bool Linearexposure, const float Expfactor );
|
||||
@@ -22,32 +22,32 @@ public:
|
||||
void SetGammaCorrection( const float Gamma = 2.2f );
|
||||
|
||||
// update skydome
|
||||
void Update( Math3D::vector3 const &Sun );
|
||||
void Update( glm::vec3 const &Sun );
|
||||
// render skydome to screen
|
||||
void Render();
|
||||
|
||||
// retrieves average colour of the sky dome
|
||||
float3 GetAverageColor() { return m_averagecolour; }
|
||||
glm::vec3 GetAverageColor() { return m_averagecolour; }
|
||||
|
||||
private:
|
||||
// shading parametrs
|
||||
float3 m_sundirection;
|
||||
glm::vec3 m_sundirection;
|
||||
float m_thetasun, m_phisun;
|
||||
float m_turbidity;
|
||||
bool m_linearexpcontrol;
|
||||
float m_expfactor;
|
||||
float m_overcast;
|
||||
float m_gammacorrection;
|
||||
float3 m_averagecolour;
|
||||
glm::vec3 m_averagecolour;
|
||||
|
||||
gl_program_mvp m_shader;
|
||||
|
||||
// data
|
||||
int m_tesselation;
|
||||
std::vector<float3> m_vertices;
|
||||
std::vector<glm::vec3> m_vertices;
|
||||
std::vector<std::uint16_t> m_indices;
|
||||
// std::vector<float3> m_normals;
|
||||
std::vector<float3> m_colours;
|
||||
std::vector<glm::vec3> m_colours;
|
||||
GLuint m_vertexbuffer{ (GLuint)-1 };
|
||||
GLuint m_indexbuffer{ (GLuint)-1 };
|
||||
GLuint m_coloursbuffer{ (GLuint)-1 };
|
||||
|
||||
14
sun.cpp
14
sun.cpp
@@ -33,9 +33,9 @@ void
|
||||
cSun::update() {
|
||||
|
||||
move();
|
||||
Math3D::vector3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position.RotateY( (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
||||
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||
|
||||
m_position = position;
|
||||
}
|
||||
@@ -63,14 +63,10 @@ cSun::render() {
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
Math3D::vector3
|
||||
glm::vec3
|
||||
cSun::getDirection() {
|
||||
|
||||
Math3D::vector3 position( 0.f, 0.f, -1.f );
|
||||
position.RotateX( (float)( m_body.elevref * (M_PI/180.0)) );
|
||||
position.RotateY( (float)( -m_body.hrang * (M_PI/180.0)) );
|
||||
position.Normalize();
|
||||
return position;
|
||||
return glm::normalize( m_position );
|
||||
}
|
||||
|
||||
float
|
||||
|
||||
7
sun.h
7
sun.h
@@ -3,7 +3,6 @@
|
||||
#include "windows.h"
|
||||
#include "GL/glew.h"
|
||||
#include "GL/wglew.h"
|
||||
#include "dumb3d.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -20,9 +19,9 @@ public:
|
||||
void update();
|
||||
void render();
|
||||
// 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
|
||||
Math3D::vector3 getDirection();
|
||||
glm::vec3 getDirection();
|
||||
// returns current elevation above horizon
|
||||
float getAngle();
|
||||
// returns current intensity of the sun
|
||||
@@ -98,5 +97,5 @@ protected:
|
||||
|
||||
celestialbody m_body;
|
||||
observer m_observer;
|
||||
Math3D::vector3 m_position;
|
||||
glm::vec3 m_position;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user