mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
virtual opengl matrix stack, light glare billboards
This commit is contained in:
16
Camera.cpp
16
Camera.cpp
@@ -111,12 +111,12 @@ vector3 TCamera::GetDirection()
|
||||
|
||||
return (Normalize(Vec));
|
||||
}
|
||||
/*
|
||||
|
||||
bool TCamera::SetMatrix()
|
||||
{
|
||||
glRotated( -Roll * 180.0f / M_PI, 0, 0, 1 ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
glRotated( -Pitch * 180.0f / M_PI, 1, 0, 0 );
|
||||
glRotated( -Yaw * 180.0f / M_PI, 0, 1, 0 ); // w zewnętrznym widoku: kierunek patrzenia
|
||||
glRotated( -Roll * 180.0 / M_PI, 0.0, 0.0, 1.0 ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
glRotated( -Pitch * 180.0 / M_PI, 1.0, 0.0, 0.0 );
|
||||
glRotated( -Yaw * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // w zewnętrznym widoku: kierunek patrzenia
|
||||
|
||||
if( Type == tp_Follow )
|
||||
{
|
||||
@@ -132,7 +132,7 @@ bool TCamera::SetMatrix()
|
||||
Global::SetCameraPosition(Pos); // było +pOffset
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool TCamera::SetMatrix( glm::mat4 &Matrix ) {
|
||||
|
||||
Matrix = glm::rotate( Matrix, (float)-Roll, glm::vec3( 0.0f, 0.0f, 1.0f ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
@@ -157,9 +157,9 @@ bool TCamera::SetMatrix( glm::mat4 &Matrix ) {
|
||||
void TCamera::SetCabMatrix(vector3 &p)
|
||||
{ // ustawienie widoku z kamery bez przesunięcia robionego przez OpenGL - nie powinno tak trząść
|
||||
|
||||
glRotated(-Roll * 180.0f / M_PI, 0, 0, 1);
|
||||
glRotated(-Pitch * 180.0f / M_PI, 1, 0, 0);
|
||||
glRotated(-Yaw * 180.0f / M_PI, 0, 1, 0); // w zewnętrznym widoku: kierunek patrzenia
|
||||
glRotated(-Roll * 180.0 / M_PI, 0.0, 0.0, 1.0);
|
||||
glRotated(-Pitch * 180.0 / M_PI, 1.0, 0.0, 0.0);
|
||||
glRotated(-Yaw * 180.0 / M_PI, 0.0, 1.0, 0.0); // w zewnętrznym widoku: kierunek patrzenia
|
||||
if (Type == tp_Follow)
|
||||
gluLookAt(Pos.x - p.x, Pos.y - p.y, Pos.z - p.z, LookAt.x - p.x, LookAt.y - p.y,
|
||||
LookAt.z - p.z, vUp.x, vUp.y, vUp.z); // Ra: pOffset is zero
|
||||
|
||||
2
Camera.h
2
Camera.h
@@ -48,9 +48,7 @@ class TCamera
|
||||
void Update();
|
||||
vector3 GetDirection();
|
||||
// vector3 inline GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; };
|
||||
/*
|
||||
bool SetMatrix();
|
||||
*/
|
||||
bool SetMatrix(glm::mat4 &Matrix);
|
||||
void SetCabMatrix( vector3 &p );
|
||||
void RaLook();
|
||||
|
||||
@@ -571,7 +571,11 @@ void TGroundNode::RenderDL()
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
TSubModel::fSquareDist = 0;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
return smTerrain->RenderDL();
|
||||
#else
|
||||
GfxRenderer.Render( smTerrain );
|
||||
#endif
|
||||
}
|
||||
// if (pTriGroup) if (pTriGroup!=this) return; //wyświetla go inny obiekt
|
||||
double mgn = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor;
|
||||
|
||||
42
Model3d.cpp
42
Model3d.cpp
@@ -320,8 +320,10 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
fCosFalloffAngle = cos(DegToRad(0.5 * fCosFalloffAngle));
|
||||
fCosHotspotAngle = cos(DegToRad(0.5 * fCosHotspotAngle));
|
||||
iNumVerts = 1;
|
||||
iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi
|
||||
// zostać bez zmiany
|
||||
/*
|
||||
iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi zostać bez zmiany
|
||||
*/
|
||||
iFlags |= 0x4030; // drawn both in solid (light point) and transparent (light glare) phases
|
||||
}
|
||||
else if (eType < TP_ROTATOR)
|
||||
{
|
||||
@@ -967,9 +969,9 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
if (iAnimOwner != iInstance)
|
||||
break; // cudza animacja
|
||||
glTranslatef(v_TransVector.x, v_TransVector.y, v_TransVector.z);
|
||||
glRotatef(v_Angles.x, 1.0, 0.0, 0.0);
|
||||
glRotatef(v_Angles.y, 0.0, 1.0, 0.0);
|
||||
glRotatef(v_Angles.z, 0.0, 0.0, 1.0);
|
||||
glRotatef(v_Angles.x, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(v_Angles.y, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(v_Angles.z, 0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
case at_SecondsJump: // sekundy z przeskokiem
|
||||
glRotatef(floor(GlobalTime->mr) * 6.0, 0.0, 1.0, 0.0);
|
||||
@@ -999,11 +1001,13 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
break;
|
||||
case at_Billboard: // obrót w pionie do kamery
|
||||
{
|
||||
/*
|
||||
matrix4x4 mat; // potrzebujemy współrzędne przesunięcia środka układu
|
||||
// współrzędnych submodelu
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray()); // pobranie aktualnej matrycy
|
||||
float3 gdzie = float3(mat[3][0], mat[3][1],
|
||||
mat[3][2]); // początek układu współrzędnych submodelu względem kamery
|
||||
*/
|
||||
matrix4x4 mat; mat.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||
float3 gdzie = float3(mat[3][0], mat[3][1], mat[3][2]); // początek układu współrzędnych submodelu względem kamery
|
||||
glLoadIdentity(); // macierz jedynkowa
|
||||
glTranslatef(gdzie.x, gdzie.y, gdzie.z); // początek układu zostaje bez
|
||||
// zmian
|
||||
@@ -1020,9 +1024,8 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
glRotated(-fmod(Global::fTimeAngleDeg, 360.0), 0.0, 1.0, 0.0); // obrót dobowy osi OX
|
||||
break;
|
||||
case at_IK11: // ostatni element animacji szkieletowej (podudzie, stopa)
|
||||
glRotatef(v_Angles.z, 0.0, 1.0, 0.0); // obrót względem osi pionowej
|
||||
// (azymut)
|
||||
glRotatef(v_Angles.x, 1.0, 0.0, 0.0); // obrót względem poziomu (deklinacja)
|
||||
glRotatef(v_Angles.z, 0.0f, 1.0f, 0.0f); // obrót względem osi pionowej (azymut)
|
||||
glRotatef(v_Angles.x, 1.0f, 0.0f, 0.0f); // obrót względem poziomu (deklinacja)
|
||||
break;
|
||||
case at_DigiClk: // animacja zegara cyfrowego
|
||||
{ // ustawienie animacji w submodelach potomnych
|
||||
@@ -1048,6 +1051,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TSubModel::RenderDL()
|
||||
{ // główna procedura renderowania przez DL
|
||||
if( ( iVisible )
|
||||
@@ -1228,6 +1232,7 @@ void TSubModel::RenderAlphaDL()
|
||||
if (iAlpha & iFlags & 0x2F000000)
|
||||
Next->RenderAlphaDL();
|
||||
}; // RenderAlpha
|
||||
#endif
|
||||
|
||||
void TSubModel::RenderVBO()
|
||||
{ // główna procedura renderowania przez VBO
|
||||
@@ -1271,8 +1276,11 @@ void TSubModel::RenderVBO()
|
||||
}
|
||||
else if (eType == TP_FREESPOTLIGHT)
|
||||
{ // wersja VBO
|
||||
/*
|
||||
matrix4x4 mat; // macierz opisuje układ renderowania względem kamery
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray());
|
||||
*/
|
||||
matrix4x4 mat; mat.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||
// kąt między kierunkiem światła a współrzędnymi kamery
|
||||
vector3 gdzie = mat * vector3(0, 0, 0); // pozycja punktu świecącego względem kamery
|
||||
fCosViewAngle = DotProduct(Normalize(mat * vector3(0, 0, 1) - gdzie), Normalize(gdzie));
|
||||
@@ -2016,8 +2024,6 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v,
|
||||
pName = "";
|
||||
if (iTexture > 0)
|
||||
{ // obsługa stałej tekstury
|
||||
// TextureID=TTexturesManager::GetTextureID(t->String(TextureID));
|
||||
// asTexture=AnsiString(t->String(iTexture));
|
||||
pTexture = t->at(iTexture);
|
||||
if (pTexture.find_last_of("/\\") == std::string::npos)
|
||||
pTexture.insert(0, Global::asCurrentTexturePath);
|
||||
@@ -2029,9 +2035,17 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v,
|
||||
}
|
||||
else
|
||||
TextureID = iTexture;
|
||||
|
||||
b_aAnim = b_Anim; // skopiowanie animacji do drugiego cyklu
|
||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem
|
||||
// tablic)
|
||||
|
||||
if( (eType == TP_FREESPOTLIGHT) && (iFlags & 0x10)) {
|
||||
// we've added light glare which needs to be rendered during transparent phase,
|
||||
// but models converted to e3d before addition won't have the render flag set correctly for this
|
||||
// so as a workaround we're doing it here manually
|
||||
iFlags |= 0x20;
|
||||
}
|
||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||
|
||||
iVboPtr = tVboPtr;
|
||||
Vertices = v + iVboPtr;
|
||||
// if (!iNumVerts) eType=-1; //tymczasowo zmiana typu, żeby się nie
|
||||
|
||||
@@ -182,8 +182,7 @@ private:
|
||||
int iFarAttenDecay; // ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R)
|
||||
float fFarDecayRadius; // normalizacja j.w.
|
||||
float fCosFalloffAngle; // cosinus kąta stożka pod którym widać światło
|
||||
float fCosHotspotAngle; // cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie
|
||||
// światła
|
||||
float fCosHotspotAngle; // cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie światła
|
||||
float fCosViewAngle; // cos kata pod jakim sie teraz patrzy
|
||||
|
||||
TSubModel *Next;
|
||||
@@ -256,9 +255,11 @@ public:
|
||||
void SetRotateIK1(float3 vNewAngles);
|
||||
TSubModel * GetFromName(std::string const &search, bool i = true);
|
||||
TSubModel * GetFromName(char const *search, bool i = true);
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void RenderDL();
|
||||
void RenderAlphaDL();
|
||||
void RenderVBO();
|
||||
#endif
|
||||
void RenderVBO();
|
||||
void RenderAlphaVBO();
|
||||
// inline matrix4x4* GetMatrix() {return dMatrix;};
|
||||
inline float4x4 * GetMatrix()
|
||||
|
||||
@@ -1153,7 +1153,6 @@ TWorld::Render_Cab() {
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
if( ( Train->Dynamic()->mdKabina != Train->Dynamic()->mdModel ) &&
|
||||
|
||||
5
dumb3d.h
5
dumb3d.h
@@ -139,14 +139,15 @@ class matrix4x4
|
||||
// the column increasing fastest. However, some APIs (OpenGL in particular) do this
|
||||
// backwards, hence the "constructor" from C matrices, or from OpenGL matrices.
|
||||
// Note that matrices are stored internally in OpenGL format.
|
||||
void C_Matrix(scalar_t *initArray)
|
||||
void C_Matrix(scalar_t const *initArray)
|
||||
{
|
||||
int i = 0;
|
||||
for (int y = 0; y < 4; ++y)
|
||||
for (int x = 0; x < 4; ++x)
|
||||
(*this)(x)[y] = initArray[i++];
|
||||
}
|
||||
void OpenGL_Matrix(scalar_t *initArray)
|
||||
template <typename _Type>
|
||||
void OpenGL_Matrix(_Type const *initArray)
|
||||
{
|
||||
int i = 0;
|
||||
for (int x = 0; x < 4; ++x)
|
||||
|
||||
15
frustum.cpp
15
frustum.cpp
@@ -11,10 +11,19 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "frustum.h"
|
||||
|
||||
void
|
||||
cFrustum::calculate( glm::mat4 &Projection, glm::mat4 &Modelview ) {
|
||||
cFrustum::calculate() {
|
||||
|
||||
float *proj = &Projection[ 0 ][ 0 ];
|
||||
float *modl = &Modelview[ 0 ][ 0 ];
|
||||
auto const &projection = OpenGLMatrices.data( GL_PROJECTION );
|
||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||
|
||||
calculate( projection, modelview );
|
||||
}
|
||||
|
||||
void
|
||||
cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
||||
|
||||
float const *proj = &Projection[ 0 ][ 0 ];
|
||||
float const *modl = &Modelview[ 0 ][ 0 ];
|
||||
float clip[ 16 ];
|
||||
|
||||
// multiply the matrices to retrieve clipping planes
|
||||
|
||||
@@ -21,8 +21,10 @@ public:
|
||||
|
||||
// methods:
|
||||
// update the frustum to match current view orientation
|
||||
void
|
||||
calculate();
|
||||
void
|
||||
calculate(glm::mat4 &Projection, glm::mat4 &Modelview);
|
||||
calculate(glm::mat4 const &Projection, glm::mat4 const &Modelview);
|
||||
// returns true if specified point is inside of the frustum
|
||||
inline
|
||||
bool
|
||||
|
||||
@@ -207,6 +207,9 @@
|
||||
<ClCompile Include="uilayer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="glwidgetlibrary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Globals.h">
|
||||
@@ -401,6 +404,12 @@
|
||||
<ClInclude Include="uilayer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="glwidgetlibrary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="openglmatrixstack.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="maszyna.rc">
|
||||
|
||||
183
openglmatrixstack.h
Normal file
183
openglmatrixstack.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "GL/glew.h"
|
||||
#ifdef _WINDOWS
|
||||
#include "GL/wglew.h"
|
||||
#endif
|
||||
|
||||
// encapsulation of the fixed pipeline opengl matrix stack
|
||||
class opengl_matrices {
|
||||
|
||||
// types:
|
||||
class opengl_stack {
|
||||
|
||||
public:
|
||||
// constructors:
|
||||
opengl_stack() { m_stack.emplace(1.0f); }
|
||||
|
||||
// methods:
|
||||
glm::mat4 const &
|
||||
data() const { return m_stack.top(); }
|
||||
void
|
||||
push_matrix() { m_stack.emplace(m_stack.top()); }
|
||||
void
|
||||
pop_matrix() {
|
||||
m_stack.pop();
|
||||
if( m_stack.empty() ) { m_stack.emplace(1.0f); }
|
||||
upload(); }
|
||||
void
|
||||
load_identity() {
|
||||
m_stack.top() = glm::mat4( 1.0f );
|
||||
upload(); }
|
||||
void
|
||||
rotate( float const Angle, glm::vec3 const &Axis ) {
|
||||
m_stack.top() = glm::rotate( m_stack.top(), Angle, Axis );
|
||||
upload(); }
|
||||
void
|
||||
translate( glm::vec3 const &Translation ) {
|
||||
m_stack.top() = glm::translate( m_stack.top(), Translation );
|
||||
upload(); }
|
||||
void
|
||||
multiply( glm::mat4 const &Matrix ) {
|
||||
m_stack.top() *= Matrix;
|
||||
upload(); }
|
||||
void
|
||||
perspective( float const Fovy, float const Aspect, float const Znear, float const Zfar ) {
|
||||
m_stack.top() *= glm::perspective( Fovy, Aspect, Znear, Zfar );
|
||||
upload(); }
|
||||
void
|
||||
look_at( glm::vec3 const &Eye, glm::vec3 const &Center, glm::vec3 const &Up ) {
|
||||
m_stack.top() *= glm::lookAt( Eye, Center, Up );
|
||||
upload(); }
|
||||
|
||||
private:
|
||||
// types:
|
||||
typedef std::stack<glm::mat4> mat4_stack;
|
||||
|
||||
// methods:
|
||||
void
|
||||
upload() { ::glLoadMatrixf( &m_stack.top()[0][0] ); }
|
||||
|
||||
// members:
|
||||
mat4_stack m_stack;
|
||||
};
|
||||
|
||||
enum stack_mode { gl_projection = 0, gl_modelview = 1 };
|
||||
typedef std::vector<opengl_stack> openglstack_array;
|
||||
|
||||
public:
|
||||
// constructors:
|
||||
opengl_matrices() {
|
||||
m_stacks.emplace_back(); // projection
|
||||
m_stacks.emplace_back(); // modelview
|
||||
}
|
||||
|
||||
// methods:
|
||||
void
|
||||
mode( GLuint const Mode ) {
|
||||
switch( Mode ) {
|
||||
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
||||
case GL_MODELVIEW: { m_mode = stack_mode::gl_modelview; break; }
|
||||
default: { break; } }
|
||||
glMatrixMode( Mode ); }
|
||||
glm::mat4 const &
|
||||
data( GLuint const Mode = -1 ) const {
|
||||
switch( Mode ) {
|
||||
case GL_PROJECTION: { return m_stacks[ stack_mode::gl_projection ].data(); }
|
||||
case GL_MODELVIEW: { return m_stacks[ stack_mode::gl_modelview ].data(); }
|
||||
default: { return m_stacks[ m_mode ].data(); } } }
|
||||
float const *
|
||||
data_array( GLuint const Mode = -1 ) const {
|
||||
return glm::value_ptr( data( Mode ) ); }
|
||||
void
|
||||
push_matrix() { m_stacks[ m_mode ].push_matrix(); }
|
||||
void
|
||||
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
||||
void
|
||||
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
||||
template <typename _Type>
|
||||
void
|
||||
rotate( _Type const Angle, _Type const X, _Type const Y, _Type const Z ) {
|
||||
m_stacks[ m_mode ].rotate(
|
||||
static_cast<float>(Angle) * 0.0174532925f, // deg2rad
|
||||
glm::vec3(
|
||||
static_cast<float>(X),
|
||||
static_cast<float>(Y),
|
||||
static_cast<float>(Z) ) ); }
|
||||
template <typename _Type>
|
||||
void
|
||||
translate( _Type const X, _Type const Y, _Type const Z ) {
|
||||
m_stacks[ m_mode ].translate(
|
||||
glm::vec3(
|
||||
static_cast<float>( X ),
|
||||
static_cast<float>( Y ),
|
||||
static_cast<float>( Z ) ) ); }
|
||||
template <typename _Type>
|
||||
void
|
||||
multiply( _Type const *Matrix ) {
|
||||
m_stacks[ m_mode ].multiply(
|
||||
glm::make_mat4( Matrix ) ); }
|
||||
template <typename _Type>
|
||||
void
|
||||
perspective( _Type const Fovy, _Type const Aspect, _Type const Znear, _Type const Zfar ) {
|
||||
m_stacks[ m_mode ].perspective(
|
||||
static_cast<float>( Fovy ),
|
||||
static_cast<float>( Aspect ),
|
||||
static_cast<float>( Znear ),
|
||||
static_cast<float>( Zfar ) ); }
|
||||
template <typename _Type>
|
||||
void
|
||||
look_at( _Type const Eyex, _Type const Eyey, _Type const Eyez, _Type const Centerx, _Type const Centery, _Type const Centerz, _Type const Upx, _Type const Upy, _Type const Upz ) {
|
||||
m_stacks[ m_mode ].look_at(
|
||||
glm::vec3(
|
||||
static_cast<float>( Eyex ),
|
||||
static_cast<float>( Eyey ),
|
||||
static_cast<float>( Eyez ) ),
|
||||
glm::vec3(
|
||||
static_cast<float>( Centerx ),
|
||||
static_cast<float>( Centery ),
|
||||
static_cast<float>( Centerz ) ),
|
||||
glm::vec3(
|
||||
static_cast<float>( Upx ),
|
||||
static_cast<float>( Upy ),
|
||||
static_cast<float>( Upz ) ) ); }
|
||||
|
||||
private:
|
||||
// members:
|
||||
stack_mode m_mode{ stack_mode::gl_projection };
|
||||
openglstack_array m_stacks;
|
||||
|
||||
};
|
||||
|
||||
extern opengl_matrices OpenGLMatrices;
|
||||
|
||||
// NOTE: standard opengl calls re-definitions
|
||||
#define glMatrixMode OpenGLMatrices.mode
|
||||
#define glPushMatrix OpenGLMatrices.push_matrix
|
||||
#define glPopMatrix OpenGLMatrices.pop_matrix
|
||||
#define glLoadIdentity OpenGLMatrices.load_identity
|
||||
#define glRotated OpenGLMatrices.rotate
|
||||
#define glRotatef OpenGLMatrices.rotate
|
||||
#define glTranslated OpenGLMatrices.translate
|
||||
#define glTranslatef OpenGLMatrices.translate
|
||||
// NOTE: no scale override as we aren't using it anywhere
|
||||
#define glMultMatrixd OpenGLMatrices.multiply
|
||||
#define glMultMatrixf OpenGLMatrices.multiply
|
||||
#define gluPerspective OpenGLMatrices.perspective
|
||||
#define gluLookAt OpenGLMatrices.look_at
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
238
renderer.cpp
238
renderer.cpp
@@ -15,8 +15,11 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "dynobj.h"
|
||||
#include "uilayer.h"
|
||||
#include "logs.h"
|
||||
#include "usefull.h"
|
||||
#include "glwidgetlibrary.h"
|
||||
|
||||
opengl_renderer GfxRenderer;
|
||||
opengl_matrices OpenGLMatrices;
|
||||
extern TWorld World;
|
||||
|
||||
// returns true if specified object is within camera frustum, false otherwise
|
||||
@@ -115,6 +118,8 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
|
||||
m_lights.emplace_back( light );
|
||||
}
|
||||
// preload some common textures
|
||||
m_glaretextureid = GetTextureId( "fx\\lightglare", szTexturePath );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -128,22 +133,31 @@ opengl_renderer::Render() {
|
||||
::glDepthFunc( GL_LEQUAL );
|
||||
|
||||
::glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
|
||||
::gluPerspective(
|
||||
Global::FieldOfView / Global::ZoomFactor * 0.0174532925f,
|
||||
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
|
||||
0.1f * Global::ZoomFactor,
|
||||
m_drawrange * Global::fDistanceFactor );
|
||||
/*
|
||||
glm::mat4 projection = glm::perspective(
|
||||
Global::FieldOfView / Global::ZoomFactor * 0.0174532925f,
|
||||
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() ) {
|
||||
|
||||
/*
|
||||
glm::mat4 modelview( 1.0f );
|
||||
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
|
||||
@@ -318,7 +332,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double
|
||||
nullptr ),
|
||||
alpha );
|
||||
|
||||
Model->Root->RenderDL();
|
||||
Render( Model->Root );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -342,6 +356,85 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// główna procedura renderowania przez DL
|
||||
if( ( Submodel->iVisible )
|
||||
&& ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / Global::fDistanceFactor ) )
|
||||
&& ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) ) {
|
||||
|
||||
if( Submodel->iFlags & 0xC000 ) {
|
||||
::glPushMatrix();
|
||||
if( Submodel->fMatrix )
|
||||
::glMultMatrixf( Submodel->fMatrix->readArray() );
|
||||
if( Submodel->b_Anim )
|
||||
Submodel->RaAnimation( Submodel->b_Anim );
|
||||
}
|
||||
if( Submodel->eType < TP_ROTATOR ) { // renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) // rysuj gdy element nieprzezroczysty
|
||||
{
|
||||
if( Submodel->TextureID < 0 ) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skóry
|
||||
GfxRenderer.Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
// TexAlpha=!(iAlpha&1); //zmiana tylko w przypadku wymienej tekstury
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind( Submodel->TextureID ); // również 0
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
|
||||
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
|
||||
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
|
||||
}
|
||||
else
|
||||
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
|
||||
}
|
||||
}
|
||||
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
|
||||
// wersja DL
|
||||
/*
|
||||
matrix4x4 modelview;
|
||||
::glGetDoublev( GL_MODELVIEW_MATRIX, modelview.getArray() );
|
||||
*/
|
||||
matrix4x4 modelview; modelview.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||
// kąt między kierunkiem światła a współrzędnymi kamery
|
||||
auto const lightcenter = modelview * vector3( 0.0, 0.0, 0.0 ); // pozycja punktu świecącego względem kamery
|
||||
Submodel->fCosViewAngle = DotProduct( Normalize( modelview * vector3( 0.0, 0.0, -1.0 ) - lightcenter ), Normalize( -lightcenter ) );
|
||||
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) // kąt większy niż maksymalny stożek swiatła
|
||||
{
|
||||
double Distdimm = 1.0;
|
||||
if( Submodel->fCosViewAngle < Submodel->fCosHotspotAngle ) // zmniejszona jasność między Hotspot a Falloff
|
||||
if( Submodel->fCosFalloffAngle < Submodel->fCosHotspotAngle )
|
||||
Distdimm = 1.0 - ( Submodel->fCosHotspotAngle - Submodel->fCosViewAngle ) / ( Submodel->fCosHotspotAngle - Submodel->fCosFalloffAngle );
|
||||
::glColor3f( Submodel->f4Diffuse[ 0 ] * Distdimm, Submodel->f4Diffuse[ 1 ] * Distdimm, Submodel->f4Diffuse[ 2 ] * Distdimm );
|
||||
::glCallList( Submodel->uiDisplayList ); // wyświetlenie warunkowe
|
||||
}
|
||||
}
|
||||
else if( Submodel->eType == TP_STARS ) {
|
||||
// glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie blendowaly
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
|
||||
::glCallList( Submodel->uiDisplayList ); // narysuj naraz wszystkie punkty z DL
|
||||
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
|
||||
}
|
||||
}
|
||||
if( Submodel->Child != NULL )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x001F0000 )
|
||||
Render( Submodel->Child );
|
||||
|
||||
if( Submodel->iFlags & 0xC000 )
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
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 ); // dalsze rekurencyjnie
|
||||
};
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
@@ -450,7 +543,7 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d
|
||||
nullptr ),
|
||||
alpha );
|
||||
|
||||
Model->Root->RenderAlphaDL();
|
||||
Render_Alpha( Model->Root );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -473,6 +566,141 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
// renderowanie przezroczystych przez DL
|
||||
if( ( Submodel->iVisible )
|
||||
&& ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / Global::fDistanceFactor ) )
|
||||
&& ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) ) {
|
||||
|
||||
if( Submodel->iFlags & 0xC000 ) {
|
||||
::glPushMatrix();
|
||||
if( Submodel->fMatrix )
|
||||
::glMultMatrixf( Submodel->fMatrix->readArray() );
|
||||
if( Submodel->b_aAnim )
|
||||
Submodel->RaAnimation( Submodel->b_aAnim );
|
||||
}
|
||||
|
||||
if( Submodel->eType < TP_ROTATOR ) { // renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) // rysuj gdy element przezroczysty
|
||||
{
|
||||
if( Submodel->TextureID < 0 ) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skóry
|
||||
GfxRenderer.Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
// TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind( Submodel->TextureID ); // również 0
|
||||
if( Global::fLuminance < Submodel->fLight ) {
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
|
||||
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
|
||||
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
|
||||
}
|
||||
else
|
||||
::glCallList( Submodel->uiDisplayList ); // tylko dla siatki
|
||||
}
|
||||
}
|
||||
else if( Submodel->eType == TP_FREESPOTLIGHT ) {
|
||||
// dorobić aureolę!
|
||||
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
|
||||
/*
|
||||
matrix4x4 modelview;
|
||||
::glGetDoublev( GL_MODELVIEW_MATRIX, modelview.getArray() );
|
||||
*/
|
||||
/*
|
||||
matrix4x4 modelview; modelview.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||
// kąt między kierunkiem światła a współrzędnymi kamery
|
||||
auto const lightcenter = modelview * vector3( 0.0, 0.0, -0.05 ); // pozycja punktu świecącego względem kamery
|
||||
Submodel->fCosViewAngle = DotProduct( Normalize( modelview * vector3( 0.0, 0.0, -1.0 ) - lightcenter ), Normalize( -lightcenter ) );
|
||||
*/
|
||||
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 fadelevel = 0.5f;
|
||||
if( ( Submodel->fCosViewAngle > 0.0 ) && ( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) ) {
|
||||
|
||||
fadelevel *= ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0 - Submodel->fCosFalloffAngle );
|
||||
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
||||
Bind( m_glaretextureid );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], fadelevel );
|
||||
::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
|
||||
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, Submodel->f4Diffuse ); // zeby swiecilo na kolorowo
|
||||
|
||||
::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();
|
||||
|
||||
float4 const noemission( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, &noemission.x );
|
||||
|
||||
::glPopMatrix();
|
||||
::glPopAttrib();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Submodel->Child != NULL ) {
|
||||
if( Submodel->eType == TP_TEXT ) { // tekst renderujemy w specjalny sposób, zamiast submodeli z łańcucha Child
|
||||
int i, j = (int)Submodel->pasText->size();
|
||||
TSubModel *p;
|
||||
if( !Submodel->smLetter ) { // jeśli nie ma tablicy, to ją stworzyć; miejsce nieodpowiednie, ale tymczasowo może być
|
||||
Submodel->smLetter = new TSubModel *[ 256 ]; // tablica wskaźników submodeli dla wyświetlania tekstu
|
||||
::ZeroMemory( Submodel->smLetter, 256 * sizeof( TSubModel * ) ); // wypełnianie zerami
|
||||
p = Submodel->Child;
|
||||
while( p ) {
|
||||
Submodel->smLetter[ p->pName[ 0 ] ] = p;
|
||||
p = p->Next; // kolejny znak
|
||||
}
|
||||
}
|
||||
for( i = 1; i <= j; ++i ) {
|
||||
p = Submodel->smLetter[ ( *( Submodel->pasText) )[ i ] ]; // znak do wyświetlenia
|
||||
if( p ) { // na razie tylko jako przezroczyste
|
||||
Render_Alpha( p );
|
||||
if( p->fMatrix )
|
||||
::glMultMatrixf( p->fMatrix->readArray() ); // przesuwanie widoku
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Submodel->iAlpha & Submodel->iFlags & 0x002F0000 )
|
||||
Render_Alpha( Submodel->Child );
|
||||
}
|
||||
|
||||
if( Submodel->iFlags & 0xC000 )
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
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 );
|
||||
};
|
||||
#endif
|
||||
|
||||
void
|
||||
|
||||
@@ -89,6 +89,9 @@ class opengl_camera {
|
||||
public:
|
||||
// methods:
|
||||
inline
|
||||
void
|
||||
update_frustum() { m_frustum.calculate(); }
|
||||
inline
|
||||
void
|
||||
update_frustum(glm::mat4 &Projection, glm::mat4 &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
||||
bool
|
||||
@@ -122,12 +125,16 @@ public:
|
||||
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
||||
bool
|
||||
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||
void
|
||||
Render( TSubModel *Submodel );
|
||||
bool
|
||||
Render_Alpha( TDynamicObject *Dynamic );
|
||||
bool
|
||||
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
||||
bool
|
||||
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||
void
|
||||
Render_Alpha( TSubModel *Submodel );
|
||||
#endif
|
||||
// maintenance jobs
|
||||
void
|
||||
@@ -185,6 +192,7 @@ private:
|
||||
double m_updateaccumulator{ 0.0 };
|
||||
std::string m_debuginfo;
|
||||
GLFWwindow *m_window{ nullptr };
|
||||
texture_manager::size_type m_glaretextureid{ -1 };
|
||||
};
|
||||
|
||||
extern opengl_renderer GfxRenderer;
|
||||
|
||||
@@ -18,7 +18,7 @@ cStars::render() {
|
||||
::glPushMatrix();
|
||||
|
||||
::glRotatef( m_latitude, 1.0f, 0.0f, 0.0f ); // ustawienie osi OY na północ
|
||||
::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
|
||||
::glRotatef( -std::fmod( (float)Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
|
||||
|
||||
::glPointSize( 2.0f );
|
||||
if( Global::bUseVBO ) {
|
||||
|
||||
Reference in New Issue
Block a user