mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 15:09:19 +02:00
mvp matrices cached separately for each render pass, eliminated duplicate screen width/height variables
This commit is contained in:
14
EU07.cpp
14
EU07.cpp
@@ -78,8 +78,8 @@ void screenshot_save_thread( char *img )
|
|||||||
png_image png;
|
png_image png;
|
||||||
memset(&png, 0, sizeof(png_image));
|
memset(&png, 0, sizeof(png_image));
|
||||||
png.version = PNG_IMAGE_VERSION;
|
png.version = PNG_IMAGE_VERSION;
|
||||||
png.width = Global::ScreenWidth;
|
png.width = Global::iWindowWidth;
|
||||||
png.height = Global::ScreenHeight;
|
png.height = Global::iWindowHeight;
|
||||||
png.format = PNG_FORMAT_RGB;
|
png.format = PNG_FORMAT_RGB;
|
||||||
|
|
||||||
char datetime[64];
|
char datetime[64];
|
||||||
@@ -95,7 +95,7 @@ void screenshot_save_thread( char *img )
|
|||||||
std::string filename = "screenshots/" + std::string(datetime) +
|
std::string filename = "screenshots/" + std::string(datetime) +
|
||||||
"_" + std::to_string(perf) + ".png";
|
"_" + std::to_string(perf) + ".png";
|
||||||
|
|
||||||
if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::ScreenWidth * 3, nullptr) == 1)
|
if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::iWindowWidth * 3, nullptr) == 1)
|
||||||
WriteLog("saved " + filename + ".");
|
WriteLog("saved " + filename + ".");
|
||||||
else
|
else
|
||||||
WriteLog("failed to save screenshot.");
|
WriteLog("failed to save screenshot.");
|
||||||
@@ -105,8 +105,8 @@ void screenshot_save_thread( char *img )
|
|||||||
|
|
||||||
void make_screenshot()
|
void make_screenshot()
|
||||||
{
|
{
|
||||||
char *img = new char[Global::ScreenWidth * Global::ScreenHeight * 3];
|
char *img = new char[Global::iWindowWidth * Global::iWindowHeight * 3];
|
||||||
glReadPixels(0, 0, Global::ScreenWidth, Global::ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
glReadPixels(0, 0, Global::iWindowWidth, Global::iWindowHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
||||||
|
|
||||||
std::thread t(screenshot_save_thread, img);
|
std::thread t(screenshot_save_thread, img);
|
||||||
t.detach();
|
t.detach();
|
||||||
@@ -117,8 +117,8 @@ void window_resize_callback(GLFWwindow *window, int w, int h)
|
|||||||
{
|
{
|
||||||
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
||||||
// TBD, TODO: merge them?
|
// TBD, TODO: merge them?
|
||||||
Global::ScreenWidth = Global::iWindowWidth = w;
|
Global::iWindowWidth = w;
|
||||||
Global::ScreenHeight = Global::iWindowHeight = h;
|
Global::iWindowHeight = h;
|
||||||
Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ cParser *Global::pParser = NULL;
|
|||||||
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
|
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
|
||||||
TCamera *Global::pCamera = NULL; // parametry kamery
|
TCamera *Global::pCamera = NULL; // parametry kamery
|
||||||
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
|
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
|
||||||
/*
|
|
||||||
std::string Global::asTranscript[5]; // napisy na ekranie (widoczne)
|
|
||||||
*/
|
|
||||||
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
||||||
float4 Global::UITextColor = float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
|
float4 Global::UITextColor = float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
|
||||||
|
|
||||||
@@ -84,6 +81,7 @@ 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
|
||||||
|
float Global::BaseDrawRange { 2500.f };
|
||||||
opengl_light Global::DayLight;
|
opengl_light Global::DayLight;
|
||||||
int Global::DynamicLightCount { 3 };
|
int Global::DynamicLightCount { 3 };
|
||||||
bool Global::ScaleSpecularValues { true };
|
bool Global::ScaleSpecularValues { true };
|
||||||
@@ -98,7 +96,7 @@ int Global::Keys[MaxKeys];
|
|||||||
bool Global::RealisticControlMode{ false };
|
bool Global::RealisticControlMode{ false };
|
||||||
int Global::iWindowWidth = 800;
|
int Global::iWindowWidth = 800;
|
||||||
int Global::iWindowHeight = 600;
|
int Global::iWindowHeight = 600;
|
||||||
float Global::fDistanceFactor = Global::ScreenHeight / 768.0; // baza do przeliczania odległości dla LoD
|
float Global::fDistanceFactor = Global::iWindowHeight / 768.0; // baza do przeliczania odległości dla LoD
|
||||||
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
||||||
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
||||||
bool Global::InputGamepad{ true };
|
bool Global::InputGamepad{ true };
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ class Global
|
|||||||
// static bool bTimeChange;
|
// static bool bTimeChange;
|
||||||
|
|
||||||
// TODO: put these things in the renderer
|
// TODO: put these things in the renderer
|
||||||
|
static float BaseDrawRange;
|
||||||
static opengl_light DayLight;
|
static opengl_light DayLight;
|
||||||
static int DynamicLightCount;
|
static int DynamicLightCount;
|
||||||
static bool ScaleSpecularValues;
|
static bool ScaleSpecularValues;
|
||||||
@@ -315,9 +316,6 @@ class Global
|
|||||||
// informacje podczas kalibracji
|
// informacje podczas kalibracji
|
||||||
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
||||||
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
|
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
|
||||||
/*
|
|
||||||
static std::string asTranscript[5]; // napisy na ekranie (widoczne)
|
|
||||||
*/
|
|
||||||
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
||||||
static float4 UITextColor; // base color of UI text
|
static float4 UITextColor; // base color of UI text
|
||||||
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
|
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
|
||||||
|
|||||||
34
World.cpp
34
World.cpp
@@ -489,9 +489,8 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else // również przeskakiwanie
|
else // również przeskakiwanie
|
||||||
{ // Ra: to z tą kamerą (Camera.Pos i Global::pCameraPosition) jest trochę bez sensu
|
{ // Ra: to z tą kamerą (Camera.Pos i Global::pCameraPosition) jest trochę bez sensu
|
||||||
Global::SetCameraPosition(
|
Ground.Silence( Global::pCameraPosition ); // wyciszenie wszystkiego z poprzedniej pozycji
|
||||||
Global::FreeCameraInit[i]); // nowa pozycja dla generowania obiektów
|
Global::SetCameraPosition( Global::FreeCameraInit[i] ); // nowa pozycja dla generowania obiektów
|
||||||
Ground.Silence(Camera.Pos); // wyciszenie wszystkiego z poprzedniej pozycji
|
|
||||||
Camera.Init(Global::FreeCameraInit[i],
|
Camera.Init(Global::FreeCameraInit[i],
|
||||||
Global::FreeCameraInitAngle[i]); // przestawienie
|
Global::FreeCameraInitAngle[i]); // przestawienie
|
||||||
}
|
}
|
||||||
@@ -1136,25 +1135,25 @@ bool TWorld::Update()
|
|||||||
|
|
||||||
void
|
void
|
||||||
TWorld::Update_Camera( double const Deltatime ) {
|
TWorld::Update_Camera( double const Deltatime ) {
|
||||||
// Console::Update(); //tu jest zależne od FPS, co nie jest korzystne
|
|
||||||
|
|
||||||
if( false == Global::ControlPicking ) {
|
if( false == Global::ControlPicking ) {
|
||||||
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
||||||
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
||||||
// if (!FreeFlyModeFlag) //jeśli wewnątrz - patrzymy do tyłu
|
if( Controlled && LengthSquared3( Controlled->GetPosition() - Camera.Pos ) < ( 1500 * 1500 ) ) {
|
||||||
// Camera.LookAt=Train->pMechPosition-Normalize(Train->GetDirection())*10;
|
// gdy bliżej niż 1.5km
|
||||||
if( Controlled && LengthSquared3( Controlled->GetPosition() - Camera.Pos ) < ( 1500 * 1500 ) ) // gdy bliżej niż 1.5km
|
|
||||||
Camera.LookAt = Controlled->GetPosition();
|
Camera.LookAt = Controlled->GetPosition();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
TDynamicObject *d =
|
TDynamicObject *d =
|
||||||
Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
||||||
if( !d )
|
if( !d )
|
||||||
d = Ground.DynamicNearest( Camera.Pos,
|
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
||||||
1000 ); // dalej szukanie, jesli bliżej nie ma
|
if( d && pDynamicNearest ) {
|
||||||
if( d && pDynamicNearest ) // jeśli jakiś jest znaleziony wcześniej
|
// jeśli jakiś jest znaleziony wcześniej
|
||||||
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) >
|
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) > LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) ) {
|
||||||
LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) )
|
|
||||||
d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż
|
d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż
|
||||||
|
}
|
||||||
|
}
|
||||||
// poprzedni najbliższy, zostaje poprzedni
|
// poprzedni najbliższy, zostaje poprzedni
|
||||||
if( d )
|
if( d )
|
||||||
pDynamicNearest = d; // zmiana na nowy, jeśli coś znaleziony niepusty
|
pDynamicNearest = d; // zmiana na nowy, jeśli coś znaleziony niepusty
|
||||||
@@ -1164,7 +1163,7 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
if( FreeFlyModeFlag )
|
if( FreeFlyModeFlag )
|
||||||
Camera.RaLook(); // jednorazowe przestawienie kamery
|
Camera.RaLook(); // jednorazowe przestawienie kamery
|
||||||
}
|
}
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) { //||Console::Pressed(VK_F4))
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) {
|
||||||
FollowView( false ); // bez wyciszania dźwięków
|
FollowView( false ); // bez wyciszania dźwięków
|
||||||
}
|
}
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
||||||
@@ -1179,12 +1178,7 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
|
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
|
||||||
/*
|
|
||||||
if( Camera.Type == tp_Follow ) {
|
|
||||||
if( Train ) { // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
|
||||||
Train->UpdateMechPosition( Deltatime /
|
|
||||||
Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu
|
|
||||||
*/
|
|
||||||
if( (Train != nullptr)
|
if( (Train != nullptr)
|
||||||
&& (Camera.Type == tp_Follow )) {
|
&& (Camera.Type == tp_Follow )) {
|
||||||
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
||||||
@@ -1248,6 +1242,8 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
else { // kamera nieruchoma
|
else { // kamera nieruchoma
|
||||||
Global::SetCameraRotation( Camera.Yaw - M_PI );
|
Global::SetCameraRotation( Camera.Yaw - M_PI );
|
||||||
}
|
}
|
||||||
|
// all done, update camera position to the new value
|
||||||
|
Global::SetCameraPosition( Camera.Pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWorld::Update_Environment() {
|
void TWorld::Update_Environment() {
|
||||||
|
|||||||
25
frustum.cpp
25
frustum.cpp
@@ -10,6 +10,10 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "frustum.h"
|
#include "frustum.h"
|
||||||
|
|
||||||
|
std::vector<glm::vec4> ndcfrustumshapepoints = {
|
||||||
|
{ -1, -1, -1, 1 }, { 1, -1, -1, 1 }, { 1, 1, -1, 1 }, { -1, 1, -1, 1 }, // z-near
|
||||||
|
{ -1, -1, 1, 1 }, { 1, -1, 1, 1 }, { 1, 1, 1, 1 }, { -1, 1, 1, 1 } }; // z-far
|
||||||
|
|
||||||
void
|
void
|
||||||
cFrustum::calculate() {
|
cFrustum::calculate() {
|
||||||
|
|
||||||
@@ -83,6 +87,14 @@ cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
|||||||
m_frustum[ side_FRONT ][ plane_C ] = clip[ 11 ] + clip[ 10 ];
|
m_frustum[ side_FRONT ][ plane_C ] = clip[ 11 ] + clip[ 10 ];
|
||||||
m_frustum[ side_FRONT ][ plane_D ] = clip[ 15 ] + clip[ 14 ];
|
m_frustum[ side_FRONT ][ plane_D ] = clip[ 15 ] + clip[ 14 ];
|
||||||
normalize_plane( side_FRONT );
|
normalize_plane( side_FRONT );
|
||||||
|
|
||||||
|
m_inversetransformation = glm::inverse( Projection * Modelview );
|
||||||
|
|
||||||
|
// calculate frustum corners
|
||||||
|
m_frustumpoints = ndcfrustumshapepoints;
|
||||||
|
transform_to_world(
|
||||||
|
std::begin( m_frustumpoints ),
|
||||||
|
std::end( m_frustumpoints ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -169,6 +181,19 @@ cFrustum::cube_inside( float const X, float const Y, float const Z, float const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::size_t> const frustumshapepoinstorder{ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
|
||||||
|
|
||||||
|
// debug helper, draws shape of frustum in world space
|
||||||
|
void
|
||||||
|
cFrustum::draw( glm::vec3 const &Offset ) const {
|
||||||
|
|
||||||
|
::glBegin( GL_LINES );
|
||||||
|
for( auto const pointindex : frustumshapepoinstorder ) {
|
||||||
|
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
||||||
|
}
|
||||||
|
::glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void cFrustum::normalize_plane( cFrustum::side const Side ) {
|
void cFrustum::normalize_plane( cFrustum::side const Side ) {
|
||||||
|
|
||||||
float magnitude =
|
float magnitude =
|
||||||
|
|||||||
18
frustum.h
18
frustum.h
@@ -61,6 +61,20 @@ public:
|
|||||||
cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Size ); }
|
cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Size ); }
|
||||||
bool
|
bool
|
||||||
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
||||||
|
// transforms provided set of clip space points to world space
|
||||||
|
template <class Iterator_>
|
||||||
|
void
|
||||||
|
transform_to_world( Iterator_ First, Iterator_ Last ) {
|
||||||
|
std::for_each(
|
||||||
|
First, Last,
|
||||||
|
[this]( glm::vec4 &point ) {
|
||||||
|
// transform each point using the cached matrix...
|
||||||
|
point = this->m_inversetransformation * point;
|
||||||
|
// ...and scale by transformed w
|
||||||
|
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
||||||
|
// debug helper, draws shape of frustum in world space
|
||||||
|
void
|
||||||
|
draw( glm::vec3 const &Offset ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// types:
|
// types:
|
||||||
@@ -74,5 +88,7 @@ protected:
|
|||||||
normalize_plane( cFrustum::side const Side ); // normalizes a plane (A side) from the frustum
|
normalize_plane( cFrustum::side const Side ); // normalizes a plane (A side) from the frustum
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
||||||
|
glm::mat4 m_inversetransformation; // cached inverse transformation matrix
|
||||||
|
std::vector<glm::vec4> m_frustumpoints; // coordinates of corners for defined frustum, in world space
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -120,9 +120,6 @@
|
|||||||
<ClCompile Include="Texture.cpp">
|
<ClCompile Include="Texture.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TextureDDS.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Timer.cpp">
|
<ClCompile Include="Timer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -374,9 +371,6 @@
|
|||||||
<ClInclude Include="Timer.h">
|
<ClInclude Include="Timer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TextureDDS.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ResourceManager.h">
|
<ClInclude Include="ResourceManager.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
2
moon.cpp
2
moon.cpp
@@ -55,7 +55,7 @@ cMoon::render() {
|
|||||||
glEnd();
|
glEnd();
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( position.x, position.y, position.z );
|
glTranslatef( position.x, position.y, position.z );
|
||||||
gluSphere( moonsphere, /* (float)( Global::ScreenHeight / Global::FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
gluSphere( moonsphere, /* (float)( Global::iWindowHeight / Global::FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ mouse_input::poll() {
|
|||||||
|
|
||||||
auto updaterate { m_updaterate };
|
auto updaterate { m_updaterate };
|
||||||
if( m_varyingpollrate ) {
|
if( m_varyingpollrate ) {
|
||||||
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::ScreenHeight ) );
|
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::iWindowHeight ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_updateaccumulator < updaterate ) {
|
if( m_updateaccumulator < updaterate ) {
|
||||||
|
|||||||
@@ -31,17 +31,23 @@ public:
|
|||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
data() const { return m_stack.top(); }
|
data() const {
|
||||||
|
return m_stack.top(); }
|
||||||
void
|
void
|
||||||
push_matrix() { m_stack.emplace(m_stack.top()); }
|
push_matrix() {
|
||||||
|
m_stack.emplace( m_stack.top() ); }
|
||||||
void
|
void
|
||||||
pop_matrix() {
|
pop_matrix() {
|
||||||
m_stack.pop();
|
m_stack.pop();
|
||||||
if( m_stack.empty() ) { m_stack.emplace(1.0f); }
|
if( m_stack.empty() ) { m_stack.emplace( 1.f ); }
|
||||||
upload(); }
|
upload(); }
|
||||||
void
|
void
|
||||||
load_identity() {
|
load_identity() {
|
||||||
m_stack.top() = glm::mat4( 1.0f );
|
m_stack.top() = glm::mat4( 1.f );
|
||||||
|
upload(); }
|
||||||
|
void
|
||||||
|
load_matrix( glm::mat4 const &Matrix ) {
|
||||||
|
m_stack.top() = Matrix;
|
||||||
upload(); }
|
upload(); }
|
||||||
void
|
void
|
||||||
rotate( float const Angle, glm::vec3 const &Axis ) {
|
rotate( float const Angle, glm::vec3 const &Axis ) {
|
||||||
@@ -113,6 +119,11 @@ public:
|
|||||||
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
||||||
void
|
void
|
||||||
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
||||||
|
void
|
||||||
|
load_matrix( glm::mat4 const &Matrix ) { m_stacks[ m_mode ].load_matrix( Matrix ); }
|
||||||
|
template <typename Type_>
|
||||||
|
void
|
||||||
|
load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); }
|
||||||
template <typename Type_>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
||||||
@@ -184,6 +195,8 @@ extern opengl_matrices OpenGLMatrices;
|
|||||||
#define glPushMatrix OpenGLMatrices.push_matrix
|
#define glPushMatrix OpenGLMatrices.push_matrix
|
||||||
#define glPopMatrix OpenGLMatrices.pop_matrix
|
#define glPopMatrix OpenGLMatrices.pop_matrix
|
||||||
#define glLoadIdentity OpenGLMatrices.load_identity
|
#define glLoadIdentity OpenGLMatrices.load_identity
|
||||||
|
#define glLoadMatrixf OpenGLMatrices.load_matrix
|
||||||
|
#define glLoadMatrixd OpenGLMatrices.load_matrix
|
||||||
#define glRotated OpenGLMatrices.rotate
|
#define glRotated OpenGLMatrices.rotate
|
||||||
#define glRotatef OpenGLMatrices.rotate
|
#define glRotatef OpenGLMatrices.rotate
|
||||||
#define glTranslated OpenGLMatrices.translate
|
#define glTranslated OpenGLMatrices.translate
|
||||||
|
|||||||
284
renderer.cpp
284
renderer.cpp
@@ -27,6 +27,8 @@ extern TWorld World;
|
|||||||
|
|
||||||
//#define EU07_USE_ORTHO_SHADOWS
|
//#define EU07_USE_ORTHO_SHADOWS
|
||||||
|
|
||||||
|
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
|
||||||
|
|
||||||
namespace colors {
|
namespace colors {
|
||||||
|
|
||||||
glm::vec4 const none { 0.f, 0.f, 0.f, 1.f };
|
glm::vec4 const none { 0.f, 0.f, 0.f, 1.f };
|
||||||
@@ -77,6 +79,7 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
m_geometry.units().texture = m_diffusetextureunit;
|
m_geometry.units().texture = m_diffusetextureunit;
|
||||||
UILayer.set_unit( m_diffusetextureunit );
|
UILayer.set_unit( m_diffusetextureunit );
|
||||||
|
|
||||||
|
::glDepthFunc( GL_LEQUAL );
|
||||||
glEnable( GL_DEPTH_TEST );
|
glEnable( GL_DEPTH_TEST );
|
||||||
glAlphaFunc( GL_GREATER, 0.04f );
|
glAlphaFunc( GL_GREATER, 0.04f );
|
||||||
glEnable( GL_ALPHA_TEST );
|
glEnable( GL_ALPHA_TEST );
|
||||||
@@ -150,11 +153,11 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||||
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, m_pickbuffersize, m_pickbuffersize, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
::glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
||||||
// depth buffer
|
// depth buffer
|
||||||
::glGenRenderbuffersEXT( 1, &m_pickdepthbuffer );
|
::glGenRenderbuffersEXT( 1, &m_pickdepthbuffer );
|
||||||
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
|
::glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_pickdepthbuffer );
|
||||||
::glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_pickbuffersize, m_pickbuffersize );
|
::glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE );
|
||||||
// create and assemble the framebuffer
|
// create and assemble the framebuffer
|
||||||
::glGenFramebuffersEXT( 1, &m_pickframebuffer );
|
::glGenFramebuffersEXT( 1, &m_pickframebuffer );
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_pickframebuffer );
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_pickframebuffer );
|
||||||
@@ -229,10 +232,10 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
float const size = 2.5f;
|
float const size = 2.5f;
|
||||||
m_billboardgeometry = m_geometry.create_chunk(
|
m_billboardgeometry = m_geometry.create_chunk(
|
||||||
vertex_array{
|
vertex_array{
|
||||||
{ { -size, size, 0.0f }, glm::vec3(), { 1.0f, 1.0f } },
|
{ { -size, size, 0.f }, glm::vec3(), { 1.f, 1.f } },
|
||||||
{ { size, size, 0.0f }, glm::vec3(), { 0.0f, 1.0f } },
|
{ { size, size, 0.f }, glm::vec3(), { 0.f, 1.f } },
|
||||||
{ { -size, -size, 0.0f }, glm::vec3(), { 1.0f, 0.0f } },
|
{ { -size, -size, 0.f }, glm::vec3(), { 1.f, 0.f } },
|
||||||
{ { size, -size, 0.0f }, glm::vec3(), { 0.0f, 0.0f } } },
|
{ { size, -size, 0.f }, glm::vec3(), { 0.f, 0.f } } },
|
||||||
geometrybank,
|
geometrybank,
|
||||||
GL_TRIANGLE_STRIP );
|
GL_TRIANGLE_STRIP );
|
||||||
// prepare debug mode objects
|
// prepare debug mode objects
|
||||||
@@ -251,9 +254,9 @@ opengl_renderer::Render() {
|
|||||||
Render_pass( rendermode::color );
|
Render_pass( rendermode::color );
|
||||||
glfwSwapBuffers( m_window );
|
glfwSwapBuffers( m_window );
|
||||||
|
|
||||||
m_drawcount = m_renderpass.draw_queue.size();
|
m_drawcount = m_drawqueue.size();
|
||||||
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
||||||
m_drawtime = std::max( 20.0f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - drawstart ) ).count() );
|
m_drawtime = std::max( 20.f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - drawstart ) ).count() );
|
||||||
|
|
||||||
return true; // for now always succeed
|
return true; // for now always succeed
|
||||||
}
|
}
|
||||||
@@ -262,37 +265,46 @@ opengl_renderer::Render() {
|
|||||||
void
|
void
|
||||||
opengl_renderer::Render_pass( rendermode const Mode ) {
|
opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||||
|
|
||||||
m_renderpass.draw_mode = Mode;
|
m_renderpass.setup( Mode );
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
|
|
||||||
|
opengl_camera shadowcamera;
|
||||||
if( Global::RenderShadows && World.InitPerformed() ) {
|
if( Global::RenderShadows && World.InitPerformed() ) {
|
||||||
// run shadowmap pass before color
|
// run shadowmap pass before color
|
||||||
Render_pass( rendermode::shadows );
|
Render_pass( rendermode::shadows );
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
UILayer.set_texture( m_shadowdebugtexture );
|
UILayer.set_texture( m_shadowdebugtexture );
|
||||||
#endif
|
#endif
|
||||||
m_renderpass.draw_mode = rendermode::color; // restore draw mode. TODO: render mode stack
|
shadowcamera = m_renderpass.camera; // cache shadow camera placement for visualization
|
||||||
|
|
||||||
|
m_renderpass.setup( rendermode::color ); // restore draw mode. TBD, TODO: render mode stack
|
||||||
|
// setup shadowmap matrix
|
||||||
|
m_shadowtexturematrix =
|
||||||
|
//bias from [-1, 1] to [0, 1] };
|
||||||
|
glm::mat4{ 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f }
|
||||||
|
* shadowcamera.projection()
|
||||||
|
// during colour pass coordinates are moved from camera-centric to light-centric, essentially the difference between these two origins
|
||||||
|
* glm::translate(
|
||||||
|
glm::mat4{ glm::mat3{ shadowcamera.modelview() } },
|
||||||
|
glm::vec3{ m_renderpass.camera.position() - shadowcamera.position() } );
|
||||||
}
|
}
|
||||||
|
|
||||||
::glViewport( 0, 0, Global::ScreenWidth, Global::ScreenHeight );
|
::glViewport( 0, 0, Global::iWindowWidth, Global::iWindowHeight );
|
||||||
m_renderpass.draw_range = 2500.0f; // arbitrary base draw range
|
|
||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
|
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
|
||||||
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.0f ); // kolor nieba
|
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.f ); // kolor nieba
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
::glClearColor( 51.0f / 255.0f, 102.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // initial background Color
|
::glClearColor( 51.0f / 255.f, 102.0f / 255.f, 85.0f / 255.f, 1.f ); // initial background Color
|
||||||
}
|
}
|
||||||
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
// setup
|
// setup
|
||||||
setup_projection();
|
setup_matrices();
|
||||||
setup_camera();
|
|
||||||
::glDepthFunc( GL_LEQUAL );
|
|
||||||
// render
|
// render
|
||||||
setup_drawing( true );
|
setup_drawing( true );
|
||||||
setup_units( true, false, false );
|
setup_units( true, false, false );
|
||||||
@@ -300,6 +312,19 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
setup_units( true, true, true );
|
setup_units( true, true, true );
|
||||||
|
|
||||||
|
if( DebugModeFlag ) {
|
||||||
|
// draw light frustum
|
||||||
|
::glLineWidth( 2.f );
|
||||||
|
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
||||||
|
::glDisable( GL_LIGHTING );
|
||||||
|
::glDisable( GL_TEXTURE_2D );
|
||||||
|
shadowcamera.frustum().draw( m_renderpass.camera.position() );
|
||||||
|
::glLineWidth( 1.f );
|
||||||
|
::glEnable( GL_LIGHTING );
|
||||||
|
::glEnable( GL_TEXTURE_2D );
|
||||||
|
}
|
||||||
|
|
||||||
Render( &World.Ground );
|
Render( &World.Ground );
|
||||||
// ...translucent parts
|
// ...translucent parts
|
||||||
setup_drawing( true );
|
setup_drawing( true );
|
||||||
@@ -322,31 +347,34 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
::glViewport( 0, 0, m_shadowbuffersize, m_shadowbuffersize );
|
::glViewport( 0, 0, m_shadowbuffersize, m_shadowbuffersize );
|
||||||
|
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
::glClearColor( 0.f / 255.0f, 0.f / 255.0f, 0.f / 255.f, 1.f ); // initial background Color
|
::glClearColor( 0.f / 255.f, 0.f / 255.f, 0.f / 255.f, 1.f ); // initial background Color
|
||||||
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
opengl_camera worldcamera{ m_renderpass.camera }; // cache shadow camera placement for visualization
|
||||||
#else
|
#else
|
||||||
::glClear( GL_DEPTH_BUFFER_BIT );
|
::glClear( GL_DEPTH_BUFFER_BIT );
|
||||||
#endif
|
#endif
|
||||||
::glScissor( 1, 1, m_shadowbuffersize - 2, m_shadowbuffersize - 2 );
|
::glScissor( 1, 1, m_shadowbuffersize - 2, m_shadowbuffersize - 2 );
|
||||||
::glEnable( GL_SCISSOR_TEST );
|
::glEnable( GL_SCISSOR_TEST );
|
||||||
|
setup_matrices();
|
||||||
m_renderpass.draw_range = Global::shadowtune.depth; // 1.0km square centered around camera
|
|
||||||
m_shadowtexturematrix =
|
|
||||||
glm::mat4{
|
|
||||||
0.5f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.5f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.5f, 0.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 1.0f }; //bias from [-1, 1] to [0, 1] };
|
|
||||||
setup_projection();
|
|
||||||
setup_camera();
|
|
||||||
::glDepthFunc( GL_LEQUAL );
|
|
||||||
::glEnable( GL_POLYGON_OFFSET_FILL ); // alleviate depth-fighting
|
::glEnable( GL_POLYGON_OFFSET_FILL ); // alleviate depth-fighting
|
||||||
::glPolygonOffset( 2.f, 4.f );
|
::glPolygonOffset( 4.f, 8.f );
|
||||||
// render
|
// render
|
||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
setup_units( true, false, false );
|
setup_units( true, false, false );
|
||||||
|
|
||||||
|
if( DebugModeFlag ) {
|
||||||
|
// draw camera frustum
|
||||||
|
::glLineWidth( 2.f );
|
||||||
|
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
||||||
|
::glDisable( GL_LIGHTING );
|
||||||
|
::glDisable( GL_TEXTURE_2D );
|
||||||
|
worldcamera.frustum().draw( m_renderpass.camera.position() );
|
||||||
|
::glLineWidth( 1.f );
|
||||||
|
::glEnable( GL_LIGHTING );
|
||||||
|
::glEnable( GL_TEXTURE_2D );
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
setup_units( false, false, false );
|
setup_units( false, false, false );
|
||||||
#endif
|
#endif
|
||||||
@@ -364,16 +392,13 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
// setup
|
// setup
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
::glViewport( 0, 0, m_pickbuffersize, m_pickbuffersize );
|
::glViewport( 0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE );
|
||||||
#endif
|
#endif
|
||||||
::glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
::glClearColor( 0.f, 0.f, 0.f, 1.f );
|
||||||
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
m_pickcontrolsitems.clear();
|
m_pickcontrolsitems.clear();
|
||||||
m_renderpass.draw_range = 50.0f; // doesn't really matter for control picking
|
setup_matrices();
|
||||||
setup_projection();
|
|
||||||
setup_camera();
|
|
||||||
::glDepthFunc( GL_LEQUAL );
|
|
||||||
// render
|
// render
|
||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
@@ -388,17 +413,14 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
// setup
|
// setup
|
||||||
|
m_picksceneryitems.clear();
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
::glViewport( 0, 0, m_pickbuffersize, m_pickbuffersize );
|
::glViewport( 0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE );
|
||||||
#endif
|
#endif
|
||||||
::glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
::glClearColor( 0.f, 0.f, 0.f, 1.f );
|
||||||
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
m_picksceneryitems.clear();
|
setup_matrices();
|
||||||
m_renderpass.draw_range = 1000.0f; // scenery picking is likely to focus on nearby nodes
|
|
||||||
setup_projection();
|
|
||||||
setup_camera();
|
|
||||||
::glDepthFunc( GL_LEQUAL );
|
|
||||||
// render
|
// render
|
||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
@@ -415,14 +437,32 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_renderer::renderpass_config::setup( rendermode const Mode ) {
|
||||||
|
|
||||||
|
draw_mode = Mode;
|
||||||
|
|
||||||
|
if( false == World.InitPerformed() ) { return; }
|
||||||
|
|
||||||
|
switch( draw_mode ) {
|
||||||
|
case rendermode::color: { draw_range = Global::BaseDrawRange; break; }
|
||||||
|
case rendermode::shadows: { draw_range = Global::shadowtune.depth; break; }
|
||||||
|
case rendermode::pickcontrols: { draw_range = 50.f; break; }
|
||||||
|
case rendermode::pickscenery: { draw_range = Global::BaseDrawRange * 0.5f; break; }
|
||||||
|
default: { draw_range = 0.f; break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_projection();
|
||||||
|
setup_modelview();
|
||||||
|
}
|
||||||
|
|
||||||
// configures projection matrix for the current render pass
|
// configures projection matrix for the current render pass
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_projection() {
|
opengl_renderer::renderpass_config::setup_projection() {
|
||||||
|
|
||||||
::glMatrixMode( GL_PROJECTION );
|
camera.projection() = glm::mat4( 1.f );
|
||||||
::glLoadIdentity();
|
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( draw_mode ) {
|
||||||
|
|
||||||
#ifndef EU07_USE_PICKING_FRAMEBUFFER
|
#ifndef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
@@ -437,12 +477,13 @@ opengl_renderer::setup_projection() {
|
|||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// TODO: scissor test for pick modes
|
// TODO: scissor test for pick modes
|
||||||
auto const angle = Global::FieldOfView / Global::ZoomFactor;
|
auto const angle = Global::FieldOfView / Global::ZoomFactor;
|
||||||
auto const height = std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) / ( Global::ScreenWidth / m_pickbuffersize );
|
auto const height = std::max( 1.0f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE );
|
||||||
::gluPerspective(
|
camera.projection() *=
|
||||||
Global::FieldOfView / Global::ZoomFactor,
|
glm::perspective(
|
||||||
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) / ( Global::ScreenWidth / m_pickbuffersize ),
|
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||||
0.1f * Global::ZoomFactor,
|
std::max( 1.0f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE ),
|
||||||
m_renderpass.draw_range * Global::fDistanceFactor );
|
0.1f * Global::ZoomFactor,
|
||||||
|
draw_range * Global::fDistanceFactor );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -452,7 +493,6 @@ opengl_renderer::setup_projection() {
|
|||||||
#else
|
#else
|
||||||
setup_projection_light_perspective();
|
setup_projection_light_perspective();
|
||||||
#endif
|
#endif
|
||||||
m_shadowtexturematrix *= OpenGLMatrices.data( GL_PROJECTION );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,103 +503,114 @@ opengl_renderer::setup_projection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_projection_world() {
|
opengl_renderer::renderpass_config::setup_projection_world() {
|
||||||
|
|
||||||
::gluPerspective(
|
camera.projection() *=
|
||||||
Global::FieldOfView / Global::ZoomFactor,
|
glm::perspective(
|
||||||
std::max( 1.f, (float)Global::ScreenWidth ) / std::max( 1.f, (float)Global::ScreenHeight ),
|
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||||
0.1f * Global::ZoomFactor,
|
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.f, (float)Global::iWindowHeight ),
|
||||||
m_renderpass.draw_range * Global::fDistanceFactor );
|
0.1f * Global::ZoomFactor,
|
||||||
|
draw_range * Global::fDistanceFactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_projection_light_ortho() {
|
opengl_renderer::renderpass_config::setup_projection_light_ortho() {
|
||||||
// TODO: calculate lightview boundaries based on area of the world camera frustum
|
// TODO: calculate lightview boundaries based on area of the world camera frustum
|
||||||
::glOrtho(
|
camera.projection() *=
|
||||||
-Global::shadowtune.width, Global::shadowtune.width,
|
glm::ortho(
|
||||||
-Global::shadowtune.width, Global::shadowtune.width,
|
-Global::shadowtune.width, Global::shadowtune.width,
|
||||||
-Global::shadowtune.depth, Global::shadowtune.depth );
|
-Global::shadowtune.width, Global::shadowtune.width,
|
||||||
|
-Global::shadowtune.depth, Global::shadowtune.depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_projection_light_perspective() {
|
opengl_renderer::renderpass_config::setup_projection_light_perspective() {
|
||||||
|
|
||||||
::gluPerspective(
|
camera.projection() *=
|
||||||
45.f,
|
glm::perspective(
|
||||||
1.f,
|
glm::radians( 45.f ),
|
||||||
m_renderpass.draw_range * 0.1f, // light source is pulled back far enough we won't likely have anything too close to it, can get some z-range here
|
1.f,
|
||||||
m_renderpass.draw_range * Global::fDistanceFactor );
|
draw_range * 0.1f, // light source is pulled back far enough we won't likely have anything too close to it, can get some z-range here
|
||||||
|
draw_range * Global::fDistanceFactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
// configures modelview matrix for the current render pass
|
// configures modelview matrix for the current render pass
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_camera() {
|
opengl_renderer::renderpass_config::setup_modelview() {
|
||||||
|
|
||||||
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
|
camera.modelview() = glm::mat4( 1.f );
|
||||||
::glLoadIdentity();
|
|
||||||
|
|
||||||
glm::dmat4 viewmatrix;
|
glm::dmat4 viewmatrix;
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
setup_camera_world( viewmatrix );
|
setup_modelview_world( viewmatrix );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
#ifdef EU07_USE_ORTHO_SHADOWS
|
#ifdef EU07_USE_ORTHO_SHADOWS
|
||||||
setup_camera_light_ortho( viewmatrix );
|
setup_modelview_light_ortho( viewmatrix );
|
||||||
#else
|
#else
|
||||||
setup_camera_light_perspective( viewmatrix );
|
setup_modelview_light_perspective( viewmatrix );
|
||||||
#endif
|
#endif
|
||||||
// during colour pass coordinates are moved from camera-centric to light-centric, essentially the difference between these two origins
|
|
||||||
m_shadowtexturematrix *=
|
|
||||||
glm::translate(
|
|
||||||
glm::mat4{ glm::dmat3{ viewmatrix } },
|
|
||||||
glm::vec3{ glm::dvec3{ Global::pCameraPosition } - m_renderpass.camera.position() } );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_ORTHO_SHADOWS
|
||||||
m_renderpass.camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), viewmatrix );
|
m_renderpass.camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), viewmatrix );
|
||||||
// frustum tests are performed in 'world space' but after we set up frustum we no longer need camera translation, only rotation
|
// frustum tests are performed in 'world space' but after we set up frustum we no longer need camera translation, only rotation
|
||||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( viewmatrix ) ) ) );
|
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( viewmatrix ) ) ) );
|
||||||
|
#else
|
||||||
|
camera.modelview() = viewmatrix;
|
||||||
|
camera.update_frustum();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_camera_world( glm::dmat4 &Viewmatrix ) {
|
opengl_renderer::renderpass_config::setup_modelview_world( glm::dmat4 &Viewmatrix ) {
|
||||||
|
|
||||||
|
camera.position() = Global::pCameraPosition;
|
||||||
World.Camera.SetMatrix( Viewmatrix );
|
World.Camera.SetMatrix( Viewmatrix );
|
||||||
m_renderpass.camera.position() = Global::pCameraPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_camera_light_ortho( glm::dmat4 &Viewmatrix ) {
|
opengl_renderer::renderpass_config::setup_modelview_light_ortho( glm::dmat4 &Viewmatrix ) {
|
||||||
|
|
||||||
m_renderpass.camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction };
|
camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction };
|
||||||
if( m_renderpass.camera.position().y - Global::pCameraPosition.y < 0.1 ) {
|
if( camera.position().y - Global::pCameraPosition.y < 0.1 ) {
|
||||||
m_renderpass.camera.position().y = Global::pCameraPosition.y + 0.1;
|
camera.position().y = Global::pCameraPosition.y + 0.1;
|
||||||
}
|
}
|
||||||
Viewmatrix *= glm::lookAt(
|
Viewmatrix *= glm::lookAt(
|
||||||
m_renderpass.camera.position(),
|
camera.position(),
|
||||||
glm::dvec3{ Global::pCameraPosition },
|
glm::dvec3{ Global::pCameraPosition },
|
||||||
glm::dvec3{ 0.f, 1.f, 0.f } );
|
glm::dvec3{ 0.f, 1.f, 0.f } );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_camera_light_perspective( glm::dmat4 &Viewmatrix ) {
|
opengl_renderer::renderpass_config::setup_modelview_light_perspective( glm::dmat4 &Viewmatrix ) {
|
||||||
|
|
||||||
m_renderpass.camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction * m_renderpass.draw_range * 0.5f };
|
camera.position() = Global::pCameraPosition - glm::dvec3{ Global::DayLight.direction * draw_range * 0.5f };
|
||||||
m_renderpass.camera.position().y = std::max<float>( m_renderpass.draw_range * 0.5f * 0.1f, m_renderpass.camera.position().y ); // prevent shadow source from dipping too low
|
camera.position().y = std::max<double>( draw_range * 0.5f * 0.1f, camera.position().y ); // prevent shadow source from dipping too low
|
||||||
Viewmatrix *= glm::lookAt(
|
Viewmatrix *= glm::lookAt(
|
||||||
m_renderpass.camera.position(),
|
camera.position(),
|
||||||
glm::dvec3{ Global::pCameraPosition },
|
glm::dvec3{ Global::pCameraPosition },
|
||||||
glm::dvec3{ 0.f, 1.f, 0.f } );
|
glm::dvec3{ 0.f, 1.f, 0.f } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_renderer::setup_matrices() {
|
||||||
|
|
||||||
|
::glMatrixMode( GL_PROJECTION );
|
||||||
|
OpenGLMatrices.load_matrix( m_renderpass.camera.projection() );
|
||||||
|
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space
|
||||||
|
::glMatrixMode( GL_MODELVIEW );
|
||||||
|
OpenGLMatrices.load_matrix( glm::mat4( glm::mat3( m_renderpass.camera.modelview() ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::setup_drawing( bool const Alpha ) {
|
opengl_renderer::setup_drawing( bool const Alpha ) {
|
||||||
|
|
||||||
@@ -982,7 +1033,7 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
|
|
||||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||||
|
|
||||||
m_renderpass.draw_queue.clear();
|
m_drawqueue.clear();
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
@@ -1034,12 +1085,12 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
}
|
}
|
||||||
// draw queue was filled while rendering content of ground cells. now sort the nodes based on their distance to viewer...
|
// draw queue was filled while rendering content of ground cells. now sort the nodes based on their distance to viewer...
|
||||||
std::sort(
|
std::sort(
|
||||||
std::begin( m_renderpass.draw_queue ),
|
std::begin( m_drawqueue ),
|
||||||
std::end( m_renderpass.draw_queue ),
|
std::end( m_drawqueue ),
|
||||||
[]( distancesubcell_pair const &Left, distancesubcell_pair const &Right ) {
|
[]( distancesubcell_pair const &Left, distancesubcell_pair const &Right ) {
|
||||||
return ( Left.first ) < ( Right.first ); } );
|
return ( Left.first ) < ( Right.first ); } );
|
||||||
// ...then render the opaque content of the visible subcells.
|
// ...then render the opaque content of the visible subcells.
|
||||||
for( auto subcellpair : m_renderpass.draw_queue ) {
|
for( auto subcellpair : m_drawqueue ) {
|
||||||
Render( subcellpair.second );
|
Render( subcellpair.second );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1058,7 +1109,7 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
}
|
}
|
||||||
// they can also skip queue sorting, as they only deal with opaque geometry
|
// they can also skip queue sorting, as they only deal with opaque geometry
|
||||||
// NOTE: there's benefit from rendering front-to-back, but is it significant enough? TODO: investigate
|
// NOTE: there's benefit from rendering front-to-back, but is it significant enough? TODO: investigate
|
||||||
for( auto subcellpair : m_renderpass.draw_queue ) {
|
for( auto subcellpair : m_drawqueue ) {
|
||||||
Render( subcellpair.second );
|
Render( subcellpair.second );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1125,7 +1176,7 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
auto subcell = Groundcell->pSubRects + subcellindex;
|
auto subcell = Groundcell->pSubRects + subcellindex;
|
||||||
if( subcell->iNodeCount ) {
|
if( subcell->iNodeCount ) {
|
||||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||||
m_renderpass.draw_queue.emplace_back(
|
m_drawqueue.emplace_back(
|
||||||
glm::length2( m_renderpass.camera.position() - glm::dvec3( subcell->m_area.center ) ),
|
glm::length2( m_renderpass.camera.position() - glm::dvec3( subcell->m_area.center ) ),
|
||||||
subcell );
|
subcell );
|
||||||
}
|
}
|
||||||
@@ -1290,9 +1341,6 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
Node->Model->Render( Node->pCenter - m_renderpass.camera.position() );
|
|
||||||
#else
|
|
||||||
Node->Model->RaAnimate(); // jednorazowe przeliczenie animacji
|
Node->Model->RaAnimate(); // jednorazowe przeliczenie animacji
|
||||||
Node->Model->RaPrepare();
|
Node->Model->RaPrepare();
|
||||||
if( Node->Model->pModel ) {
|
if( Node->Model->pModel ) {
|
||||||
@@ -1320,7 +1368,6 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1981,21 +2028,21 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
|||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
TSubRect *tmp;
|
TSubRect *tmp;
|
||||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||||
for( auto subcellpair = std::rbegin( m_renderpass.draw_queue ); subcellpair != std::rend( m_renderpass.draw_queue ); ++subcellpair ) {
|
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair ) {
|
||||||
// przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
// przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||||
tmp = subcellpair->second;
|
tmp = subcellpair->second;
|
||||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||||
Render_Alpha( node );
|
Render_Alpha( node );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( auto subcellpair = std::rbegin( m_renderpass.draw_queue ); subcellpair != std::rend( m_renderpass.draw_queue ); ++subcellpair )
|
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair )
|
||||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||||
Render_Alpha( subcellpair->second );
|
Render_Alpha( subcellpair->second );
|
||||||
}
|
}
|
||||||
|
|
||||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||||
|
|
||||||
for( auto subcellpair = std::rbegin( m_renderpass.draw_queue ); subcellpair != std::rend( m_renderpass.draw_queue ); ++subcellpair ) {
|
for( auto subcellpair = std::rbegin( m_drawqueue ); subcellpair != std::rend( m_drawqueue ); ++subcellpair ) {
|
||||||
// druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
// druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||||
tmp = subcellpair->second;
|
tmp = subcellpair->second;
|
||||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||||
@@ -2092,9 +2139,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case TP_MODEL: {
|
case TP_MODEL: {
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
Node->Model->RenderAlpha( Node->pCenter - m_renderpass.camera.position() );
|
|
||||||
#else
|
|
||||||
Node->Model->RaPrepare();
|
Node->Model->RaPrepare();
|
||||||
if( Node->Model->pModel ) {
|
if( Node->Model->pModel ) {
|
||||||
// renderowanie rekurencyjne submodeli
|
// renderowanie rekurencyjne submodeli
|
||||||
@@ -2121,7 +2166,6 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2508,15 +2552,15 @@ opengl_renderer::Update_Pick_Control() {
|
|||||||
// determine point to examine
|
// determine point to examine
|
||||||
glm::dvec2 mousepos;
|
glm::dvec2 mousepos;
|
||||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||||
mousepos.y = Global::ScreenHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
|
mousepos.y = Global::iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
|
||||||
|
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
glm::ivec2 pickbufferpos;
|
glm::ivec2 pickbufferpos;
|
||||||
if( true == m_framebuffersupport ) {
|
if( true == m_framebuffersupport ) {
|
||||||
// ::glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
|
// ::glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
|
||||||
pickbufferpos = glm::ivec2{
|
pickbufferpos = glm::ivec2{
|
||||||
mousepos.x * m_pickbuffersize / Global::ScreenWidth,
|
mousepos.x * EU07_PICKBUFFERSIZE / Global::iWindowWidth,
|
||||||
mousepos.y * m_pickbuffersize / Global::ScreenHeight
|
mousepos.y * EU07_PICKBUFFERSIZE / Global::iWindowHeight
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2556,15 +2600,15 @@ opengl_renderer::Update_Pick_Node() {
|
|||||||
// determine point to examine
|
// determine point to examine
|
||||||
glm::dvec2 mousepos;
|
glm::dvec2 mousepos;
|
||||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||||
mousepos.y = Global::ScreenHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
|
mousepos.y = Global::iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
|
||||||
|
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
glm::ivec2 pickbufferpos;
|
glm::ivec2 pickbufferpos;
|
||||||
if( true == m_framebuffersupport ) {
|
if( true == m_framebuffersupport ) {
|
||||||
// ::glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
|
// ::glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
|
||||||
pickbufferpos = glm::ivec2{
|
pickbufferpos = glm::ivec2{
|
||||||
mousepos.x * m_pickbuffersize / Global::ScreenWidth,
|
mousepos.x * EU07_PICKBUFFERSIZE / Global::iWindowWidth,
|
||||||
mousepos.y * m_pickbuffersize / Global::ScreenHeight
|
mousepos.y * EU07_PICKBUFFERSIZE / Global::iWindowHeight
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2611,8 +2655,8 @@ opengl_renderer::Update( double const Deltatime ) {
|
|||||||
float targetfactor;
|
float targetfactor;
|
||||||
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
||||||
else if( framerate > 60.0 ) { targetfactor = 1.5f; }
|
else if( framerate > 60.0 ) { targetfactor = 1.5f; }
|
||||||
else if( framerate > 30.0 ) { targetfactor = Global::ScreenHeight / 768.0f; }
|
else if( framerate > 30.0 ) { targetfactor = Global::iWindowHeight / 768.0f; }
|
||||||
else { targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
|
else { targetfactor = Global::iWindowHeight / 768.0f * 0.75f; }
|
||||||
|
|
||||||
if( targetfactor > Global::fDistanceFactor ) {
|
if( targetfactor > Global::fDistanceFactor ) {
|
||||||
|
|
||||||
|
|||||||
107
renderer.h
107
renderer.h
@@ -26,10 +26,10 @@ struct opengl_light {
|
|||||||
GLuint id{ (GLuint)-1 };
|
GLuint id{ (GLuint)-1 };
|
||||||
glm::vec3 direction;
|
glm::vec3 direction;
|
||||||
glm::vec4
|
glm::vec4
|
||||||
position { 0.0f, 0.0f, 0.0f, 1.0f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
|
position { 0.f, 0.f, 0.f, 1.f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
|
||||||
ambient { 0.0f, 0.0f, 0.0f, 1.0f },
|
ambient { 0.f, 0.f, 0.f, 1.f },
|
||||||
diffuse { 1.0f, 1.0f, 1.0f, 1.0f },
|
diffuse { 1.f, 1.f, 1.f, 1.f },
|
||||||
specular { 1.0f, 1.0f, 1.0f, 1.0f };
|
specular { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void apply_intensity( float const Factor = 1.0f ) {
|
void apply_intensity( float const Factor = 1.0f ) {
|
||||||
@@ -54,7 +54,7 @@ struct opengl_light {
|
|||||||
void apply_angle() {
|
void apply_angle() {
|
||||||
|
|
||||||
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
|
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
|
||||||
if( position.w == 1.0f ) {
|
if( position.w == 1.f ) {
|
||||||
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
|
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ public:
|
|||||||
// methods:
|
// methods:
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
update_frustum() { m_frustum.calculate(); }
|
update_frustum() { m_frustum.calculate( m_projection, m_modelview ); }
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
update_frustum(glm::mat4 const &Projection, glm::mat4 const &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
update_frustum(glm::mat4 const &Projection, glm::mat4 const &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
||||||
@@ -100,11 +100,28 @@ public:
|
|||||||
inline
|
inline
|
||||||
glm::dvec3 &
|
glm::dvec3 &
|
||||||
position() { return m_position; }
|
position() { return m_position; }
|
||||||
|
inline
|
||||||
|
glm::mat4 const &
|
||||||
|
projection() const { return m_projection; }
|
||||||
|
inline
|
||||||
|
glm::mat4 &
|
||||||
|
projection() { return m_projection; }
|
||||||
|
inline
|
||||||
|
glm::mat4 const &
|
||||||
|
modelview() const { return m_modelview; }
|
||||||
|
inline
|
||||||
|
glm::mat4 &
|
||||||
|
modelview() { return m_modelview; }
|
||||||
|
inline
|
||||||
|
cFrustum const &
|
||||||
|
frustum() { return m_frustum; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members:
|
// members:
|
||||||
cFrustum m_frustum;
|
cFrustum m_frustum;
|
||||||
glm::dvec3 m_position;
|
glm::dvec3 m_position;
|
||||||
|
glm::mat4 m_projection;
|
||||||
|
glm::mat4 m_modelview;
|
||||||
};
|
};
|
||||||
|
|
||||||
// bare-bones render controller, in lack of anything better yet
|
// bare-bones render controller, in lack of anything better yet
|
||||||
@@ -185,7 +202,28 @@ private:
|
|||||||
opengl_camera camera;
|
opengl_camera camera;
|
||||||
rendermode draw_mode { rendermode::none };
|
rendermode draw_mode { rendermode::none };
|
||||||
float draw_range { 0.0f };
|
float draw_range { 0.0f };
|
||||||
std::vector<distancesubcell_pair> draw_queue; // list of subcells to be drawn in current render pass
|
|
||||||
|
void
|
||||||
|
setup( rendermode const Mode );
|
||||||
|
private:
|
||||||
|
// configures projection matrix for the current render pass
|
||||||
|
void
|
||||||
|
setup_projection();
|
||||||
|
void
|
||||||
|
setup_projection_world();
|
||||||
|
void
|
||||||
|
setup_projection_light_ortho();
|
||||||
|
void
|
||||||
|
setup_projection_light_perspective();
|
||||||
|
// configures camera for the current render pass
|
||||||
|
void
|
||||||
|
setup_modelview();
|
||||||
|
void
|
||||||
|
setup_modelview_world( glm::dmat4 &Viewmatrix );
|
||||||
|
void
|
||||||
|
setup_modelview_light_ortho( glm::dmat4 &Viewmatrix );
|
||||||
|
void
|
||||||
|
setup_modelview_light_perspective( glm::dmat4 &Viewmatrix );
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
typedef std::vector<opengl_light> opengllight_array;
|
||||||
@@ -196,24 +234,8 @@ private:
|
|||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void
|
void
|
||||||
Render_pass( rendermode const Mode );
|
Render_pass( rendermode const Mode );
|
||||||
// configures projection matrix for the current render pass
|
|
||||||
void
|
void
|
||||||
setup_projection();
|
setup_matrices();
|
||||||
void
|
|
||||||
setup_projection_world();
|
|
||||||
void
|
|
||||||
setup_projection_light_ortho();
|
|
||||||
void
|
|
||||||
setup_projection_light_perspective();
|
|
||||||
// configures camera for the current render pass
|
|
||||||
void
|
|
||||||
setup_camera();
|
|
||||||
void
|
|
||||||
setup_camera_world( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
|
||||||
setup_camera_light_ortho( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
|
||||||
setup_camera_light_perspective( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
void
|
||||||
setup_drawing( bool const Alpha = false );
|
setup_drawing( bool const Alpha = false );
|
||||||
void
|
void
|
||||||
@@ -267,46 +289,49 @@ private:
|
|||||||
std::size_t
|
std::size_t
|
||||||
pick_index( glm::ivec3 const &Color );
|
pick_index( glm::ivec3 const &Color );
|
||||||
// members
|
// members
|
||||||
|
GLFWwindow *m_window { nullptr };
|
||||||
geometrybank_manager m_geometry;
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengllight_array m_lights;
|
opengllight_array m_lights;
|
||||||
GLFWwindow *m_window { nullptr };
|
|
||||||
|
geometry_handle m_billboardgeometry { NULL, NULL };
|
||||||
|
texture_handle m_glaretexture { -1 };
|
||||||
|
texture_handle m_suntexture { -1 };
|
||||||
|
texture_handle m_moontexture { -1 };
|
||||||
|
texture_handle m_reflectiontexture { -1 };
|
||||||
|
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
||||||
|
|
||||||
|
bool m_framebuffersupport { false };
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
GLuint m_pickframebuffer { NULL }; // TODO: refactor pick framebuffer stuff into an object
|
GLuint m_pickframebuffer { NULL }; // TODO: refactor pick framebuffer stuff into an object
|
||||||
GLuint m_picktexture { NULL };
|
GLuint m_picktexture { NULL };
|
||||||
GLuint m_pickdepthbuffer { NULL };
|
GLuint m_pickdepthbuffer { NULL };
|
||||||
int m_pickbuffersize { 1024 }; // size of (square) textures bound with the pick framebuffer
|
|
||||||
#endif
|
#endif
|
||||||
|
int m_shadowbuffersize { 4096 };
|
||||||
GLuint m_shadowframebuffer { NULL };
|
GLuint m_shadowframebuffer { NULL };
|
||||||
GLuint m_shadowtexture { NULL };
|
GLuint m_shadowtexture { NULL };
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
GLuint m_shadowdebugtexture{ NULL };
|
GLuint m_shadowdebugtexture{ NULL };
|
||||||
#endif
|
#endif
|
||||||
int m_shadowbuffersize { 4096 };
|
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
||||||
glm::mat4 m_shadowtexturematrix;
|
|
||||||
glm::vec4 m_shadowcolor{ 0.5f, 0.5f, 0.5f, 1.f };
|
|
||||||
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
|
||||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||||
int m_helpertextureunit { GL_TEXTURE0 };
|
int m_helpertextureunit { GL_TEXTURE0 };
|
||||||
int m_diffusetextureunit { GL_TEXTURE2 };
|
int m_diffusetextureunit { GL_TEXTURE2 };
|
||||||
|
|
||||||
geometry_handle m_billboardgeometry { 0, 0 };
|
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
||||||
texture_handle m_glaretexture { -1 };
|
|
||||||
texture_handle m_suntexture { -1 };
|
|
||||||
texture_handle m_moontexture { -1 };
|
|
||||||
texture_handle m_reflectiontexture { -1 };
|
|
||||||
|
|
||||||
float m_drawtime { 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
|
||||||
double m_updateaccumulator { 0.0 };
|
double m_updateaccumulator { 0.0 };
|
||||||
std::string m_debuginfo;
|
std::string m_debuginfo;
|
||||||
|
|
||||||
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
float m_specularopaquescalefactor { 1.0f };
|
glm::vec4 m_shadowcolor { 0.5f, 0.5f, 0.5f, 1.f };
|
||||||
float m_speculartranslucentscalefactor { 1.0f };
|
float m_specularopaquescalefactor { 1.f };
|
||||||
|
float m_speculartranslucentscalefactor { 1.f };
|
||||||
|
bool m_renderspecular{ false }; // controls whether to include specular component in the calculations
|
||||||
|
|
||||||
bool m_framebuffersupport { false };
|
|
||||||
renderpass_config m_renderpass;
|
renderpass_config m_renderpass;
|
||||||
bool m_renderspecular { false }; // controls whether to include specular component in the calculations
|
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
||||||
|
|
||||||
std::vector<TGroundNode const *> m_picksceneryitems;
|
std::vector<TGroundNode const *> m_picksceneryitems;
|
||||||
std::vector<TSubModel const *> m_pickcontrolsitems;
|
std::vector<TSubModel const *> m_pickcontrolsitems;
|
||||||
TSubModel const *m_pickcontrolitem { nullptr };
|
TSubModel const *m_pickcontrolitem { nullptr };
|
||||||
|
|||||||
15
uilayer.cpp
15
uilayer.cpp
@@ -65,7 +65,7 @@ ui_layer::render() {
|
|||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho( 0, std::max( 1, Global::ScreenWidth ), std::max( 1, Global::ScreenHeight ), 0, -1, 1 );
|
glOrtho( 0, std::max( 1, Global::iWindowWidth ), std::max( 1, Global::iWindowHeight ), 0, -1, 1 );
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -107,11 +107,7 @@ ui_layer::set_background( std::string const &Filename ) {
|
|||||||
m_progressbottom = ( texture.width() != texture.height() );
|
m_progressbottom = ( texture.width() != texture.height() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void cGuiLayer::setNote( const std::string Note ) { mNote = Note; }
|
|
||||||
|
|
||||||
std::string cGuiLayer::getNote() { return mNote; }
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
ui_layer::render_progress() {
|
ui_layer::render_progress() {
|
||||||
|
|
||||||
@@ -247,13 +243,14 @@ ui_layer::render_texture() {
|
|||||||
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
||||||
|
|
||||||
auto const size = 512.f;
|
auto const size = 512.f;
|
||||||
|
auto const offset = 64.f;
|
||||||
|
|
||||||
glBegin( GL_TRIANGLE_STRIP );
|
glBegin( GL_TRIANGLE_STRIP );
|
||||||
|
|
||||||
glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( 0.f, 256.f );
|
glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( offset, Global::iWindowHeight - offset - size );
|
||||||
glMultiTexCoord2f( m_textureunit, 0.f, 0.f ); glVertex2f( 0.f, 256.f + size );
|
glMultiTexCoord2f( m_textureunit, 0.f, 0.f ); glVertex2f( offset, Global::iWindowHeight - offset );
|
||||||
glMultiTexCoord2f( m_textureunit, 1.f, 1.f ); glVertex2f( size, 256.f );
|
glMultiTexCoord2f( m_textureunit, 1.f, 1.f ); glVertex2f( offset + size, Global::iWindowHeight - offset - size );
|
||||||
glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( size, 256.f + size );
|
glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( offset + size, Global::iWindowHeight - offset );
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user