build 170628. enabled support for specular component in lighting calculations

This commit is contained in:
tmj-fstate
2017-06-28 21:02:54 +02:00
parent 8e37307ff5
commit 49aad85597
20 changed files with 249 additions and 198 deletions

View File

@@ -82,13 +82,10 @@ GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f};
GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
double Global::fFogStart = 1700;
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;
int Global::DynamicLightCount{ 3 };
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];
int Global::DynamicLightCount { 3 };
bool Global::ScaleSpecularValues { true };
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
@@ -224,13 +221,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);
@@ -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
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

View File

@@ -225,11 +225,8 @@ class Global
// TODO: put these things in the renderer
static opengl_light DayLight;
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;

View File

@@ -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.Normalize();
Global::DayLight.direction = glm::normalize( Global::DayLight.direction );
parser.getTokens(9, false);
do {

View File

@@ -240,8 +240,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>();
@@ -367,6 +372,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);
@@ -446,7 +455,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 + "\", 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) {
// 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
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 + "\"" );
}
}
}
@@ -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 + 2 ].position );
facenormals.emplace_back(
glm::length( facenormal ) > 0.0f ?
glm::length2( facenormal ) > 0.0f ?
glm::normalize( facenormal ) :
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
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
@@ -1516,6 +1533,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;
@@ -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
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);
@@ -1612,12 +1639,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
@@ -1654,11 +1685,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)

View File

@@ -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 };

View File

@@ -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
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();
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;
// 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();
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;
// 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 );
@@ -2319,9 +2319,8 @@ world_environment::update() {
auto const diffuselevel = interpolate( keylightintensity, intensity * ( 1.0f - twilightfactor ), 1.0f - Global::Overcast * 0.75f );
// ...update light colours and intensity.
keylightcolor = keylightcolor * diffuselevel;
Global::DayLight.diffuse[ 0 ] = keylightcolor.x;
Global::DayLight.diffuse[ 1 ] = keylightcolor.y;
Global::DayLight.diffuse[ 2 ] = keylightcolor.z;
Global::DayLight.diffuse = glm::vec4( keylightcolor, Global::DayLight.diffuse.a );
Global::DayLight.specular = glm::vec4( keylightcolor * 0.85f, diffuselevel );
// 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)

74
color.h
View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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
View File

@@ -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;
};

View File

@@ -24,6 +24,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 {
@@ -74,14 +80,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 );
Global::DayLight.id = opengl_renderer::sunlight;
// directional light
@@ -205,9 +216,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 ) {
@@ -248,11 +259,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 );
@@ -553,7 +563,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
::glColor4fv(
glm::value_ptr(
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
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.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
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
if( Dynamic->mdLowPolyInt ) {
@@ -650,8 +661,7 @@ 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) );
}
}
}
@@ -663,6 +673,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
// post-render cleanup
m_renderspecular = false;
if( Dynamic->fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
@@ -747,6 +758,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// renderowanie obiektów OpenGL
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
{
if( true == Submodel->m_normalizenormals ) {
::glEnable( GL_NORMALIZE );
}
// material configuration:
// textures...
if( Submodel->TextureID < 0 )
@@ -757,7 +771,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// również 0
Bind( Submodel->TextureID );
}
// ...colors...
::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
if( Global::fLuminance < Submodel->fLight ) {
// zeby swiecilo na kolorowo
@@ -768,10 +787,15 @@ opengl_renderer::Render( TSubModel *Submodel ) {
m_geometry.draw( Submodel->m_geometry );
// 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 ) {
// 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( noemission ) );
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
}
if( true == Submodel->m_normalizenormals ) {
::glDisable( GL_NORMALIZE );
}
}
}
@@ -1007,7 +1031,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
::glColor4fv(
glm::value_ptr(
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 ) ) ) );
auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.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
Global::DayLight.apply_intensity( Dynamic->fShade );
}
m_renderspecular = true;
// render
if( Dynamic->mdLowPolyInt ) {
@@ -1096,8 +1121,7 @@ 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 ) );
}
}
}
@@ -1109,6 +1133,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
// post-render cleanup
m_renderspecular = false;
if( Dynamic->fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
@@ -1192,6 +1217,9 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// renderowanie obiektów OpenGL
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
{
if( true == Submodel->m_normalizenormals ) {
::glEnable( GL_NORMALIZE );
}
// textures...
if( Submodel->TextureID < 0 ) { // zmienialne skóry
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
@@ -1200,7 +1228,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// również 0
Bind( Submodel->TextureID );
}
// ...colors...
::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
if( Global::fLuminance < Submodel->fLight ) {
// zeby swiecilo na kolorowo
@@ -1211,10 +1243,15 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
m_geometry.draw( Submodel->m_geometry );
// 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 ) {
// 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( noemission ) );
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
}
if( true == Submodel->m_normalizenormals ) {
::glDisable( GL_NORMALIZE );
}
}
}
@@ -1401,7 +1438,7 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
continue;
}
// 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;
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels

View File

@@ -21,53 +21,44 @@ http://mozilla.org/MPL/2.0/.
struct opengl_light {
GLuint id{ (GLuint)-1 };
Math3D::vector3 direction;
GLfloat position[ 4 ]; // 4th parameter specifies directional(0) or omni-directional(1) light source
GLfloat ambient[ 4 ];
GLfloat diffuse[ 4 ];
GLfloat specular[ 4 ];
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
}
glm::vec3 direction;
glm::vec4
position { 0.0f, 0.0f, 0.0f, 1.0f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
ambient { 0.0f, 0.0f, 0.0f, 1.0f },
diffuse { 1.0f, 1.0f, 1.0f, 1.0f },
specular { 1.0f, 1.0f, 1.0f, 1.0f };
inline
void apply_intensity( float const Factor = 1.0f ) {
if( Factor == 1.0 ) {
glLightfv( id, GL_AMBIENT, ambient );
glLightfv( id, GL_DIFFUSE, diffuse );
glLightfv( id, GL_SPECULAR, specular );
glLightfv( id, GL_AMBIENT, glm::value_ptr(ambient) );
glLightfv( id, GL_DIFFUSE, glm::value_ptr(diffuse) );
glLightfv( id, GL_SPECULAR, glm::value_ptr(specular) );
}
else {
// temporary light scaling mechanics (ultimately this work will be left to the shaders
float4 scaledambient( ambient[ 0 ] * Factor, ambient[ 1 ] * Factor, ambient[ 2 ] * Factor, ambient[ 3 ] );
float4 scaleddiffuse( diffuse[ 0 ] * Factor, diffuse[ 1 ] * Factor, diffuse[ 2 ] * Factor, diffuse[ 3 ] );
float4 scaledspecular( specular[ 0 ] * Factor, specular[ 1 ] * Factor, specular[ 2 ] * Factor, specular[ 3 ] );
glLightfv( id, GL_AMBIENT, &scaledambient.x );
glLightfv( id, GL_DIFFUSE, &scaleddiffuse.x );
glLightfv( id, GL_SPECULAR, &scaledspecular.x );
glm::vec4 scaledambient( ambient.r * Factor, ambient.g * Factor, ambient.b * Factor, ambient.a );
glm::vec4 scaleddiffuse( diffuse.r * Factor, diffuse.g * Factor, diffuse.b * Factor, diffuse.a );
glm::vec4 scaledspecular( specular.r * Factor, specular.g * Factor, specular.b * Factor, specular.a );
glLightfv( id, GL_AMBIENT, glm::value_ptr(scaledambient) );
glLightfv( id, GL_DIFFUSE, glm::value_ptr(scaleddiffuse) );
glLightfv( id, GL_SPECULAR, glm::value_ptr(scaledspecular) );
}
}
inline
void apply_angle() {
glLightfv( id, GL_POSITION, position );
if( position[ 3 ] == 1.0f ) {
GLfloat directionarray[] = { (GLfloat)direction.x, (GLfloat)direction.y, (GLfloat)direction.z };
glLightfv( id, GL_SPOT_DIRECTION, directionarray );
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
if( position.w == 1.0f ) {
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
}
}
inline
void set_position( Math3D::vector3 const &Position ) {
void set_position( glm::vec3 const &Position ) {
position[ 0 ] = Position.x;
position[ 1 ] = Position.y;
position[ 2 ] = Position.z;
position = glm::vec4( Position, position.w );
}
};
@@ -229,6 +220,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 };
};

View File

@@ -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
View File

@@ -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) );
};
//---------------------------------------------------------------------------

View File

@@ -86,8 +86,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
@@ -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 ) ) {
// build colors if there's a change in sun position
@@ -150,15 +150,14 @@ void CSkyDome::Render() {
::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( 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 );
@@ -244,18 +243,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 );
@@ -283,7 +282,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);
@@ -292,7 +291,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
@@ -309,12 +308,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 );
@@ -338,10 +337,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

View File

@@ -1,8 +1,5 @@
#pragma once
#include "dumb3d.h"
#include "float3d.h"
// sky gradient based on "A practical analytic model for daylight"
// by A. J. Preetham Peter Shirley Brian Smits (University of Utah)
@@ -13,7 +10,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 );
@@ -21,30 +18,30 @@ 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;
// data
int const 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
View File

@@ -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
View File

@@ -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;
};

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 626
#define VERSION_MINOR 628
#define VERSION_REVISION 0