mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-20 13:39:18 +02:00
merge (with bugs)
This commit is contained in:
566
renderer.cpp
566
renderer.cpp
@@ -15,6 +15,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "dynobj.h"
|
||||
#include "uilayer.h"
|
||||
#include "logs.h"
|
||||
#include "usefull.h"
|
||||
#include "World.h"
|
||||
|
||||
opengl_renderer GfxRenderer;
|
||||
extern TWorld World;
|
||||
@@ -101,7 +103,13 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
World.shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
|
||||
Global::daylight.intensity = 1.0f; //m7todo: przenieść
|
||||
|
||||
return true;
|
||||
WriteLog("Loading common gfx data...");
|
||||
m_glaretextureid = GetTextureId("fx\\lightglare", szTexturePath);
|
||||
m_suntextureid = GetTextureId("fx\\sun", szTexturePath);
|
||||
m_moontextureid = GetTextureId("fx\\moon", szTexturePath);
|
||||
WriteLog("...gfx data pre-loading done");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -115,29 +123,21 @@ opengl_renderer::Render() {
|
||||
::glDepthFunc( GL_LEQUAL );
|
||||
|
||||
::glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
|
||||
glm::mat4 projection = glm::perspective(
|
||||
Global::FieldOfView / Global::ZoomFactor * 0.0174532925f,
|
||||
::gluPerspective(
|
||||
Global::FieldOfView / Global::ZoomFactor,
|
||||
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
|
||||
0.1f * Global::ZoomFactor,
|
||||
m_drawrange * Global::fDistanceFactor );
|
||||
::glLoadMatrixf( &projection[0][0] );
|
||||
|
||||
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
|
||||
glm::mat4 modelview( 1.0f );
|
||||
::glLoadIdentity();
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
|
||||
World.Camera.SetMatrix( modelview );
|
||||
::glLoadMatrixf( &modelview[ 0 ][ 0 ] );
|
||||
m_camera.update_frustum( projection, modelview );
|
||||
World.Camera.SetMatrix();
|
||||
m_camera.update_frustum();
|
||||
|
||||
if( !Global::bWireFrame ) {
|
||||
// bez nieba w trybie rysowania linii
|
||||
World.Environment.render();
|
||||
}
|
||||
|
||||
glDebug("rendering ground");
|
||||
Render( &World.Environment );
|
||||
World.Ground.Render( World.Camera.Pos );
|
||||
|
||||
glDebug("rendering cab");
|
||||
@@ -154,12 +154,135 @@ opengl_renderer::Render() {
|
||||
return true; // for now always succeed
|
||||
}
|
||||
|
||||
#ifndef EU07_USE_OLD_RENDERCODE
|
||||
bool
|
||||
opengl_renderer::Render( world_environment *Environment ) {
|
||||
|
||||
if( Global::bWireFrame ) {
|
||||
// bez nieba w trybie rysowania linii
|
||||
return false;
|
||||
}
|
||||
|
||||
Bind( 0 );
|
||||
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_DEPTH_TEST );
|
||||
::glDepthMask( GL_FALSE );
|
||||
::glPushMatrix();
|
||||
::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
|
||||
// setup fog
|
||||
if( Global::fFogEnd > 0 ) {
|
||||
// fog setup
|
||||
::glFogfv( GL_FOG_COLOR, Global::FogColor );
|
||||
::glFogf( GL_FOG_DENSITY, 1.0f / Global::fFogEnd );
|
||||
::glEnable( GL_FOG );
|
||||
}
|
||||
else { ::glDisable( GL_FOG ); }
|
||||
|
||||
Environment->m_skydome.Render();
|
||||
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 ),
|
||||
duskfactor );
|
||||
|
||||
if( DebugModeFlag == true ) {
|
||||
// mark sun position for easier debugging
|
||||
Environment->m_sun.render();
|
||||
Environment->m_moon.render();
|
||||
}
|
||||
// render actual sun and moon
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
||||
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_ALPHA_TEST );
|
||||
::glEnable( GL_BLEND );
|
||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
|
||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||
// sun
|
||||
{
|
||||
Bind( m_suntextureid );
|
||||
::glColor4f( suncolor.x, suncolor.y, suncolor.z, 1.0f );
|
||||
auto const sunvector = Environment->m_sun.getDirection();
|
||||
auto const sunposition = modelview * glm::vec4( sunvector.x, sunvector.y, sunvector.z, 1.0f );
|
||||
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity(); // macierz jedynkowa
|
||||
::glTranslatef( sunposition.x, sunposition.y, sunposition.z ); // początek układu zostaje bez zmian
|
||||
|
||||
float const size = 0.045f;
|
||||
::glBegin( GL_TRIANGLE_STRIP );
|
||||
::glTexCoord2f( 1.0f, 1.0f ); ::glVertex3f( -size, size, 0.0f );
|
||||
::glTexCoord2f( 1.0f, 0.0f ); ::glVertex3f( -size, -size, 0.0f );
|
||||
::glTexCoord2f( 0.0f, 1.0f ); ::glVertex3f( size, size, 0.0f );
|
||||
::glTexCoord2f( 0.0f, 0.0f ); ::glVertex3f( size, -size, 0.0f );
|
||||
::glEnd();
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
// moon
|
||||
{
|
||||
Bind( m_moontextureid );
|
||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, 1.0f - Global::fLuminance * 0.5f );
|
||||
|
||||
auto const moonvector = Environment->m_moon.getDirection();
|
||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity(); // macierz jedynkowa
|
||||
::glTranslatef( moonposition.x, moonposition.y, moonposition.z );
|
||||
|
||||
float const size = 0.02f; // TODO: expose distance/scale factor from the moon object
|
||||
// choose the moon appearance variant, based on current moon phase
|
||||
// NOTE: implementation specific, 8 variants are laid out in 3x3 arrangement
|
||||
// from new moon onwards, top left to right bottom (last spot is left for future use, if any)
|
||||
auto const moonphase = Environment->m_moon.getPhase();
|
||||
float moonu, moonv;
|
||||
if( moonphase < 1.84566f ) { moonv = 1.0f - 0.0f; moonu = 0.0f; }
|
||||
else if( moonphase < 5.53699f ) { moonv = 1.0f - 0.0f; moonu = 0.333f; }
|
||||
else if( moonphase < 9.22831f ) { moonv = 1.0f - 0.0f; moonu = 0.667f; }
|
||||
else if( moonphase < 12.91963f ) { moonv = 1.0f - 0.333f; moonu = 0.0f; }
|
||||
else if( moonphase < 16.61096f ) { moonv = 1.0f - 0.333f; moonu = 0.333f; }
|
||||
else if( moonphase < 20.30228f ) { moonv = 1.0f - 0.333f; moonu = 0.667f; }
|
||||
else if( moonphase < 23.99361f ) { moonv = 1.0f - 0.667f; moonu = 0.0f; }
|
||||
else if( moonphase < 27.68493f ) { moonv = 1.0f - 0.667f; moonu = 0.333f; }
|
||||
else { moonv = 1.0f - 0.0f; moonu = 0.0f; }
|
||||
|
||||
::glBegin( GL_TRIANGLE_STRIP );
|
||||
::glTexCoord2f( moonu, moonv ); ::glVertex3f( -size, size, 0.0f );
|
||||
::glTexCoord2f( moonu, moonv - 0.333f ); ::glVertex3f( -size, -size, 0.0f );
|
||||
::glTexCoord2f( moonu + 0.333f, moonv ); ::glVertex3f( size, size, 0.0f );
|
||||
::glTexCoord2f( moonu + 0.333f, moonv - 0.333f ); ::glVertex3f( size, -size, 0.0f );
|
||||
::glEnd();
|
||||
|
||||
::glPopMatrix();
|
||||
}
|
||||
::glPopAttrib();
|
||||
|
||||
// clouds
|
||||
Environment->m_clouds.Render(
|
||||
interpolate( Environment->m_skydome.GetAverageColor(), suncolor, duskfactor * 0.25f )
|
||||
* ( 1.0f - Global::Overcast * 0.5f ) // overcast darkens the clouds
|
||||
* 2.5f ); // arbitrary adjustment factor
|
||||
|
||||
Global::daylight.intensity = 1.0f;
|
||||
|
||||
::glPopMatrix();
|
||||
::glDepthMask( GL_TRUE );
|
||||
::glEnable( GL_DEPTH_TEST );
|
||||
::glEnable( GL_LIGHTING );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TGround *Ground ) {
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glAlphaFunc( GL_GREATER, 0.35f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
glAlphaFunc( GL_GREATER, 0.45f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
glEnable( GL_LIGHTING );
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
@@ -194,6 +317,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
Dynamic->renderme = true;
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
@@ -216,63 +340,34 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
Global::daylight.intensity = Dynamic->fShade;
|
||||
}
|
||||
|
||||
// TODO: implement universal render path down the road
|
||||
if( Global::bUseVBO ) {
|
||||
// wersja VBO
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
// enable cab light if needed
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
// enable cab light if needed
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
||||
}
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
||||
}
|
||||
|
||||
Dynamic->mdLowPolyInt->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
|
||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||
|
||||
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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
Dynamic->mdModel->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
|
||||
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Dynamic->mdLoad->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
|
||||
}
|
||||
else {
|
||||
// wersja Display Lists
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
// enable cab light if needed
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
||||
}
|
||||
|
||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||
|
||||
// post-render cleanup
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
// restore regular light level
|
||||
Global::daylight.intensity = 1.0f;
|
||||
@@ -301,14 +396,25 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double
|
||||
}
|
||||
|
||||
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
||||
|
||||
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// setup
|
||||
if( false == Model->StartVBO() )
|
||||
return false;
|
||||
|
||||
Model->Root->ReplacableSet(
|
||||
( Material != nullptr ?
|
||||
Material->replacable_skins :
|
||||
nullptr ),
|
||||
alpha );
|
||||
|
||||
Model->Root->RenderDL();
|
||||
Model->Root->pRoot = Model;
|
||||
|
||||
// render
|
||||
Render(Model->Root);
|
||||
|
||||
// post-render cleanup
|
||||
Model->EndVBO();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -332,6 +438,154 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
|
||||
return result;
|
||||
}
|
||||
|
||||
void opengl_renderer::Render(TSubModel *Submodel)
|
||||
{
|
||||
World.shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
World.shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
|
||||
Render(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
|
||||
}
|
||||
|
||||
void opengl_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
{
|
||||
World.shader.set_mv(OpenGLMatrices.data(GL_MODELVIEW));
|
||||
World.shader.set_p(OpenGLMatrices.data(GL_PROJECTION));
|
||||
Render_Alpha(Submodel, OpenGLMatrices.data(GL_MODELVIEW));
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
|
||||
if( ( Submodel->iVisible )
|
||||
&& ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / Global::fDistanceFactor ) )
|
||||
&& ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) )
|
||||
{
|
||||
glm::mat4 mm = m;
|
||||
if (Submodel->iFlags & 0xC000)
|
||||
{
|
||||
if (Submodel->fMatrix)
|
||||
mm *= glm::make_mat4(Submodel->fMatrix->e);
|
||||
if (Submodel->b_Anim)
|
||||
Submodel->RaAnimation(mm, Submodel->b_Anim);
|
||||
World.shader.set_mv(mm);
|
||||
}
|
||||
|
||||
if( Submodel->eType < TP_ROTATOR ) {
|
||||
// renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
|
||||
{
|
||||
// material configuration:
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 )
|
||||
{ // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
}
|
||||
/*
|
||||
::glColor3fv( Submodel->f4Diffuse ); // McZapkie-240702: zamiast ub
|
||||
// ...luminance
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
||||
}
|
||||
*/
|
||||
|
||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
||||
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||
|
||||
/*
|
||||
// post-draw reset
|
||||
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 ) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
//m7todo: restore
|
||||
/*
|
||||
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
|
||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
|
||||
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
|
||||
|
||||
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) // kąt większy niż maksymalny stożek swiatła
|
||||
{
|
||||
float lightlevel = 1.0f;
|
||||
// view angle attenuation
|
||||
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||
float const distancefactor = std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) );
|
||||
|
||||
if( lightlevel > 0.0f ) {
|
||||
// material configuration:
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
|
||||
|
||||
Bind( 0 );
|
||||
::glPointSize( std::max( 2.0f, 4.0f * distancefactor * anglefactor ) );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], lightlevel * anglefactor );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glEnable( GL_BLEND );
|
||||
|
||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
||||
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||
|
||||
// post-draw reset
|
||||
::glPopAttrib();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Submodel->eType == TP_STARS ) {
|
||||
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
|
||||
// material configuration:
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
|
||||
|
||||
Bind( 0 );
|
||||
::glDisable( GL_LIGHTING );
|
||||
|
||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
||||
// NOTE: we're doing manual switch to color vbo setup, because there doesn't seem to be any convenient way available atm
|
||||
// TODO: implement easier way to go about it
|
||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
::glEnableClientState( GL_COLOR_ARRAY );
|
||||
::glColorPointer( 3, GL_FLOAT, sizeof( CVertNormTex ), static_cast<char *>( nullptr ) + 12 ); // kolory
|
||||
|
||||
::glDrawArrays( GL_POINTS, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
// post-draw reset
|
||||
::glPopAttrib();
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
if( Submodel->Child != NULL )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x001F0000 )
|
||||
Render( Submodel->Child, mm );
|
||||
|
||||
if( Submodel->iFlags & 0xC000 )
|
||||
World.shader.set_mv(m);
|
||||
}
|
||||
|
||||
if( Submodel->b_Anim < at_SecondsJump )
|
||||
Submodel->b_Anim = at_None; // wyłączenie animacji dla kolejnego użycia subm
|
||||
|
||||
if( Submodel->Next )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F000000 )
|
||||
Render( Submodel->Next, m ); // dalsze rekurencyjnie
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
@@ -339,9 +593,10 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition );
|
||||
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
::glPushMatrix();
|
||||
@@ -353,9 +608,13 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
|
||||
|
||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||
// wersja Display Lists
|
||||
// NOTE: VBO path is removed
|
||||
// TODO: implement universal render path down the road
|
||||
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::daylight.intensity = Dynamic->fShade;
|
||||
}
|
||||
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
@@ -382,6 +641,12 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
||||
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
|
||||
|
||||
// post-render cleanup
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
// restore regular light level
|
||||
Global::daylight.intensity = 1.0f;
|
||||
}
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
if( Dynamic->btnOn )
|
||||
@@ -405,13 +670,24 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d
|
||||
|
||||
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
|
||||
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// setup
|
||||
if( false == Model->StartVBO() )
|
||||
return false;
|
||||
|
||||
Model->Root->ReplacableSet(
|
||||
( Material != nullptr ?
|
||||
Material->replacable_skins :
|
||||
nullptr ),
|
||||
Material->replacable_skins :
|
||||
nullptr ),
|
||||
alpha );
|
||||
|
||||
Model->Root->RenderAlphaDL();
|
||||
Model->Root->pRoot = Model;
|
||||
|
||||
// render
|
||||
Render_Alpha( Model->Root );
|
||||
|
||||
// post-render cleanup
|
||||
Model->EndVBO();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -434,8 +710,129 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render_Alpha( TSubModel *Submodel, glm::mat4 m) {
|
||||
// renderowanie przezroczystych przez DL
|
||||
if( ( Submodel->iVisible )
|
||||
&& ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / Global::fDistanceFactor ) )
|
||||
&& ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) ) {
|
||||
|
||||
glm::mat4 mm = m;
|
||||
if (Submodel->iFlags & 0xC000)
|
||||
{
|
||||
if (Submodel->fMatrix)
|
||||
mm *= glm::make_mat4(Submodel->fMatrix->e);
|
||||
if (Submodel->b_Anim)
|
||||
Submodel->RaAnimation(mm, Submodel->b_Anim);
|
||||
World.shader.set_mv(mm);
|
||||
}
|
||||
|
||||
if( Submodel->eType < TP_ROTATOR ) {
|
||||
// renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
|
||||
{
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
}
|
||||
/*
|
||||
::glColor3fv( Submodel->f4Diffuse ); // McZapkie-240702: zamiast ub
|
||||
// ...luminance
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse );
|
||||
}
|
||||
*/
|
||||
|
||||
// main draw call. TODO: generic buffer base class, specialized for vbo, dl etc
|
||||
::glDrawArrays( Submodel->eType, Submodel->iVboPtr, Submodel->iNumVerts );
|
||||
|
||||
/*
|
||||
// post-draw reset
|
||||
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 ) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
|
||||
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
// NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh
|
||||
// TODO: separate instance data from reusable geometry
|
||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||
auto const lightcenter = modelview * glm::vec4( 0.0f, 0.0f, -0.05f, 1.0f ); // pozycja punktu świecącego względem kamery
|
||||
Submodel->fCosViewAngle = glm::dot( glm::normalize( modelview * glm::vec4( 0.0f, 0.0f, -1.0f, 1.0f ) - lightcenter ), glm::normalize( -lightcenter ) );
|
||||
|
||||
float glarelevel = 0.6f; // luminosity at night is at level of ~0.1, so the overall resulting transparency is ~0.5 at full 'brightness'
|
||||
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) {
|
||||
|
||||
glarelevel *= ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
||||
glarelevel = std::max( 0.0f, glarelevel - static_cast<float>(Global::fLuminance) );
|
||||
|
||||
if( glarelevel > 0.0f ) {
|
||||
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
||||
|
||||
Bind( m_glaretextureid );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity(); // macierz jedynkowa
|
||||
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
||||
::glRotated( atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
||||
|
||||
// TODO: turn the drawing instructions into a compiled call / array
|
||||
::glBegin( GL_TRIANGLE_STRIP );
|
||||
float const size = 2.5f;
|
||||
::glTexCoord2f( 1.0f, 1.0f ); ::glVertex3f( -size, size, 0.0f );
|
||||
::glTexCoord2f( 0.0f, 1.0f ); ::glVertex3f( size, size, 0.0f );
|
||||
::glTexCoord2f( 1.0f, 0.0f ); ::glVertex3f( -size, -size, 0.0f );
|
||||
::glTexCoord2f( 0.0f, 0.0f ); ::glVertex3f( size, -size, 0.0f );
|
||||
/*
|
||||
// NOTE: we could do simply...
|
||||
vec3 vertexPosition_worldspace =
|
||||
particleCenter_wordspace
|
||||
+ CameraRight_worldspace * squareVertices.x * BillboardSize.x
|
||||
+ CameraUp_worldspace * squareVertices.y * BillboardSize.y;
|
||||
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
||||
*/
|
||||
::glEnd();
|
||||
|
||||
::glPopMatrix();
|
||||
::glPopAttrib();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( Submodel->Child != NULL )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x002F0000 )
|
||||
Render_Alpha( Submodel->Child, mm );
|
||||
|
||||
if( Submodel->iFlags & 0xC000 )
|
||||
World.shader.set_mv(m);
|
||||
}
|
||||
|
||||
if( Submodel->b_aAnim < at_SecondsJump )
|
||||
Submodel->b_aAnim = at_None; // wyłączenie animacji dla kolejnego użycia submodelu
|
||||
|
||||
if( Submodel->Next != NULL )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x2F000000 )
|
||||
Render_Alpha( Submodel->Next, m );
|
||||
};
|
||||
|
||||
void
|
||||
opengl_renderer::Update ( double const Deltatime ) {
|
||||
|
||||
@@ -530,17 +927,20 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
// if the light passed tests so far, it's good enough
|
||||
|
||||
auto const luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||
float3 position(scenelight.position.x, scenelight.position.y, scenelight.position.z);
|
||||
float3 direction(scenelight.direction.x, scenelight.direction.y, scenelight.direction.z);
|
||||
float3 color(scenelight.color.x,
|
||||
scenelight.color.y,
|
||||
scenelight.color.z);
|
||||
glm::vec3 position(scenelight.position.x, scenelight.position.y, scenelight.position.z);
|
||||
glm::vec3 direction(scenelight.direction.x, scenelight.direction.y, scenelight.direction.z);
|
||||
glm::vec3 color(scenelight.color.x,
|
||||
scenelight.color.y,
|
||||
scenelight.color.z);
|
||||
|
||||
World.shader.set_light((GLuint)renderlight + 1, gl_program_light::SPOT, position, direction, 0.906f, 0.866f, color, 0.007f, 0.0002f);
|
||||
|
||||
++renderlight;
|
||||
}
|
||||
|
||||
World.shader.set_ambient(Global::daylight.ambient);
|
||||
World.shader.set_light(0, gl_program_light::DIR, glm::vec3(0.0f), Global::daylight.direction,
|
||||
0.0f, 0.0f, Global::daylight.color, 0.0f, 0.0f);
|
||||
World.shader.set_light_count((GLuint)renderlight + 1);
|
||||
}
|
||||
|
||||
@@ -560,8 +960,8 @@ opengl_renderer::Init_caps() {
|
||||
+ " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) )
|
||||
+ " OpenGL Version: " + oglversion );
|
||||
|
||||
if( !GLEW_VERSION_1_4 ) {
|
||||
ErrorLog( "Requires openGL >= 1.4" );
|
||||
if( !GLEW_VERSION_3_2 ) {
|
||||
ErrorLog( "Requires openGL >= 3.2" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user