mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
build 170810. multi-texture materials, reflection map support
This commit is contained in:
@@ -440,14 +440,15 @@ bool TAnimModel::Init(TModel3d *pNewModel)
|
||||
|
||||
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
|
||||
{
|
||||
if (asReplacableTexture.substr(0, 1) ==
|
||||
"*") // od gwiazdki zaczynają się teksty na wyświetlaczach
|
||||
asText = asReplacableTexture.substr(1, asReplacableTexture.length() - 1); // zapamiętanie tekstu
|
||||
else if (asReplacableTexture != "none")
|
||||
m_materialdata.replacable_skins[1] =
|
||||
GfxRenderer.Fetch_Texture( asReplacableTexture, "" );
|
||||
if( ( m_materialdata.replacable_skins[ 1 ] != 0 )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
|
||||
if( asReplacableTexture.substr( 0, 1 ) == "*" ) {
|
||||
// od gwiazdki zaczynają się teksty na wyświetlaczach
|
||||
asText = asReplacableTexture.substr( 1, asReplacableTexture.length() - 1 ); // zapamiętanie tekstu
|
||||
}
|
||||
else if( asReplacableTexture != "none" ) {
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( asReplacableTexture );
|
||||
}
|
||||
if( ( m_materialdata.replacable_skins[ 1 ] != NULL )
|
||||
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
|
||||
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha = 0x31310031;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "Texture.h"
|
||||
#include "material.h"
|
||||
#include "DynObj.h"
|
||||
|
||||
const int iMaxNumLights = 8;
|
||||
|
||||
34
Driver.cpp
34
Driver.cpp
@@ -4591,20 +4591,20 @@ bool TController::UpdateSituation(double dt)
|
||||
// if not MinVelFlag)
|
||||
if (fBrakeTime < 0 ? true : (AccDesired < fAccGravity - 0.3) ||
|
||||
(mvOccupied->BrakeCtrlPos <= 0))
|
||||
if (!IncBrake()) // jeśli upłynął czas reakcji hamulca, chyba że
|
||||
// nagłe albo luzował
|
||||
if( false == IncBrake() ) {
|
||||
// jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował
|
||||
MinVelFlag = true;
|
||||
else
|
||||
{
|
||||
}
|
||||
else {
|
||||
MinVelFlag = false;
|
||||
fBrakeTime =
|
||||
3 +
|
||||
0.5 *
|
||||
(mvOccupied
|
||||
->BrakeDelay[2 + 2 * mvOccupied->BrakeDelayFlag] -
|
||||
3);
|
||||
// Ra: ten czas należy zmniejszyć, jeśli czas dojazdu do
|
||||
// zatrzymania jest mniejszy
|
||||
3.0
|
||||
+ 0.5 * ( (
|
||||
mvOccupied->BrakeDelayFlag > bdelay_G ?
|
||||
mvOccupied->BrakeDelay[ 1 ] :
|
||||
mvOccupied->BrakeDelay[ 3 ] )
|
||||
- 3.0 );
|
||||
// Ra: ten czas należy zmniejszyć, jeśli czas dojazdu do zatrzymania jest mniejszy
|
||||
fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1
|
||||
}
|
||||
if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - 0.2))
|
||||
@@ -4613,11 +4613,15 @@ bool TController::UpdateSituation(double dt)
|
||||
// if (fBrakeTime<0)
|
||||
{ // jak hamuje, to nie tykaj kranu za często
|
||||
// yB: luzuje hamulec dopiero przy różnicy opóźnień rzędu 0.2
|
||||
if (OrderList[OrderPos] !=
|
||||
Disconnect) // przy odłączaniu nie zwalniamy tu hamulca
|
||||
if( OrderList[ OrderPos ] != Disconnect ) {
|
||||
// przy odłączaniu nie zwalniamy tu hamulca
|
||||
DecBrake(); // tutaj zmniejszało o 1 przy odczepianiu
|
||||
fBrakeTime =
|
||||
(mvOccupied->BrakeDelay[1 + 2 * mvOccupied->BrakeDelayFlag]) / 3.0;
|
||||
}
|
||||
fBrakeTime = (
|
||||
mvOccupied->BrakeDelayFlag > bdelay_G ?
|
||||
mvOccupied->BrakeDelay[ 0 ] :
|
||||
mvOccupied->BrakeDelay[ 2 ] )
|
||||
/ 3.0;
|
||||
fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1
|
||||
}
|
||||
}
|
||||
|
||||
68
DynObj.cpp
68
DynObj.cpp
@@ -4036,7 +4036,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
{
|
||||
std::string nowheretexture = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
|
||||
if( false == nowheretexture.empty() ) {
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( nowheretexture, "", 9 );
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Material( nowheretexture );
|
||||
}
|
||||
|
||||
if (m_materialdata.multi_textures > 0) {
|
||||
@@ -4048,7 +4048,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
int skinindex = 0;
|
||||
std::string texturename; nameparser >> texturename;
|
||||
while( ( texturename != "" ) && ( skinindex < 4 ) ) {
|
||||
m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + texturename, "" );
|
||||
m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( Global::asCurrentTexturePath + texturename );
|
||||
++skinindex;
|
||||
texturename = ""; nameparser >> texturename;
|
||||
}
|
||||
@@ -4058,24 +4058,24 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
// otherwise try the basic approach
|
||||
int skinindex = 0;
|
||||
do {
|
||||
texture_handle texture = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
|
||||
if( texture == NULL ) {
|
||||
material_handle material = GfxRenderer.Fetch_Material( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), true );
|
||||
if( material == NULL ) {
|
||||
break;
|
||||
}
|
||||
m_materialdata.replacable_skins[ skinindex + 1 ] = texture;
|
||||
m_materialdata.replacable_skins[ skinindex + 1 ] = material;
|
||||
++skinindex;
|
||||
} while( skinindex < 4 );
|
||||
m_materialdata.multi_textures = skinindex;
|
||||
if( m_materialdata.multi_textures == 0 ) {
|
||||
// zestaw nie zadziałał, próbujemy normanie
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Global::asCurrentTexturePath + ReplacableSkin );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Texture( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Global::asCurrentTexturePath + ReplacableSkin );
|
||||
}
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) {
|
||||
if( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) {
|
||||
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha = 0x31310031;
|
||||
}
|
||||
@@ -4085,17 +4085,17 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
|
||||
if( ( m_materialdata.replacable_skins[ 2 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha ) ) {
|
||||
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 2 ] ).has_alpha ) ) {
|
||||
// tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x02020002;
|
||||
}
|
||||
if( ( m_materialdata.replacable_skins[ 3 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 3 ] ).has_alpha ) ) {
|
||||
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 3 ] ).has_alpha ) ) {
|
||||
// tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x04040004;
|
||||
}
|
||||
if( ( m_materialdata.replacable_skins[ 4 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha ) ) {
|
||||
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 4 ] ).has_alpha ) ) {
|
||||
// tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x08080008;
|
||||
}
|
||||
@@ -5371,7 +5371,7 @@ int TDynamicObject::RouteWish(TTrack *tr)
|
||||
|
||||
std::string TDynamicObject::TextureTest(std::string const &name)
|
||||
{ // Ra 2015-01: sprawdzenie dostępności tekstury o podanej nazwie
|
||||
std::vector<std::string> extensions = { ".dds", ".tga", ".bmp" };
|
||||
std::vector<std::string> extensions = { ".mat", ".dds", ".tga", ".bmp" };
|
||||
for( auto const &extension : extensions ) {
|
||||
if( true == FileExists( name + extension ) ) {
|
||||
return name + extension;
|
||||
@@ -5393,36 +5393,22 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||||
numer = Global::Bezogonkow(numer);
|
||||
asDestination = to;
|
||||
to = Global::Bezogonkow(to); // do szukania pliku obcinamy ogonki
|
||||
std::string x = TextureTest(asBaseDir + numer + "@" + MoverParameters->TypeName);
|
||||
if (!x.empty())
|
||||
{
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
|
||||
std::vector<std::string> destinations = {
|
||||
asBaseDir + numer + "@" + MoverParameters->TypeName,
|
||||
asBaseDir + numer,
|
||||
asBaseDir + to + "@" + MoverParameters->TypeName,
|
||||
asBaseDir + to,
|
||||
asBaseDir + "nowhere" };
|
||||
|
||||
for( auto const &destination : destinations ) {
|
||||
|
||||
auto material = TextureTest( destination );
|
||||
if( false == material.empty() ) {
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Material( material );
|
||||
break;
|
||||
}
|
||||
}
|
||||
x = TextureTest(asBaseDir + numer );
|
||||
if (!x.empty())
|
||||
{
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
}
|
||||
if (to.empty())
|
||||
to = "nowhere";
|
||||
x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejności z nazwą FIZ/MMD
|
||||
if (!x.empty())
|
||||
{
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
}
|
||||
x = TextureTest(asBaseDir + to); // na razie prymitywnie
|
||||
if (!x.empty())
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
|
||||
else
|
||||
{
|
||||
x = TextureTest(asBaseDir + "nowhere"); // jak nie znalazł dedykowanej, to niech daje nowhere
|
||||
if (!x.empty())
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Texture( x, "", 9 );
|
||||
}
|
||||
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa tekstury nr 4
|
||||
};
|
||||
|
||||
void TDynamicObject::OverheadTrack(float o)
|
||||
|
||||
2
DynObj.h
2
DynObj.h
@@ -143,7 +143,7 @@ class TAnim
|
||||
struct material_data {
|
||||
|
||||
int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości
|
||||
texture_handle replacable_skins[ 5 ] = { NULL, NULL, NULL, NULL, NULL }; // McZapkie:zmienialne nadwozie
|
||||
material_handle replacable_skins[ 5 ] = { NULL, NULL, NULL, NULL, NULL }; // McZapkie:zmienialne nadwozie
|
||||
int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
||||
};
|
||||
|
||||
|
||||
39
Ground.cpp
39
Ground.cpp
@@ -67,7 +67,7 @@ TGroundNode::TGroundNode()
|
||||
nNext = nNext2 = NULL;
|
||||
iCount = 0; // wierzchołków w trójkącie
|
||||
// iNumPts=0; //punktów w linii
|
||||
TextureID = 0;
|
||||
m_material = 0;
|
||||
iFlags = 0; // tryb przezroczystości nie zbadany
|
||||
Pointer = NULL; // zerowanie wskaźnika kontekstowego
|
||||
bVisible = false; // czy widoczny
|
||||
@@ -508,7 +508,7 @@ TGroundRect::mergeable( TGroundNode const &Left, TGroundNode const &Right ) {
|
||||
// since view ranges and transparency type for all nodes put through this method are guaranteed to be equal,
|
||||
// we can skip their tests and only do the material check.
|
||||
// TODO, TBD: material as dedicated type, and refactor this method into a simple equality test
|
||||
return ( ( Left.TextureID == Right.TextureID )
|
||||
return ( ( Left.m_material == Right.m_material )
|
||||
&& ( Left.Ambient == Right.Ambient )
|
||||
&& ( Left.Diffuse == Right.Diffuse )
|
||||
&& ( Left.Specular == Right.Specular ) );
|
||||
@@ -776,7 +776,7 @@ void TGround::RaTriangleDivider(TGroundNode *node)
|
||||
TGroundNode *ntri; // wskaźnik na nowy trójkąt
|
||||
ntri = new TGroundNode(GL_TRIANGLES); // a ten jest nowy
|
||||
// kopiowanie parametrów, przydałby się konstruktor kopiujący
|
||||
ntri->TextureID = node->TextureID;
|
||||
ntri->m_material = node->m_material;
|
||||
ntri->iFlags = node->iFlags;
|
||||
ntri->Ambient = node->Ambient;
|
||||
ntri->Diffuse = node->Diffuse;
|
||||
@@ -1376,23 +1376,36 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
*parser >> token;
|
||||
}
|
||||
str = token;
|
||||
tmp->TextureID = GfxRenderer.Fetch_Texture( str );
|
||||
tmp->m_material = GfxRenderer.Fetch_Material( str );
|
||||
auto const texturehandle = (
|
||||
tmp->m_material != NULL ?
|
||||
GfxRenderer.Material( tmp->m_material ).texture1 :
|
||||
NULL );
|
||||
auto const &texture = (
|
||||
texturehandle ?
|
||||
GfxRenderer.Texture( texturehandle ) :
|
||||
opengl_texture() ); // dirty workaround for lack of better api
|
||||
bool const clamps = (
|
||||
tmp->TextureID ?
|
||||
GfxRenderer.Texture( tmp->TextureID ).traits.find( 's' ) != std::string::npos :
|
||||
texturehandle ?
|
||||
texture.traits.find( 's' ) != std::string::npos :
|
||||
false );
|
||||
bool const clampt = (
|
||||
tmp->TextureID ?
|
||||
GfxRenderer.Texture( tmp->TextureID ).traits.find( 't' ) != std::string::npos :
|
||||
texturehandle ?
|
||||
texture.traits.find( 't' ) != std::string::npos :
|
||||
false );
|
||||
|
||||
tmp->iFlags |= 200; // z usuwaniem
|
||||
// remainder of legacy 'problend' system -- geometry assigned a texture with '@' in its name is treated as translucent, opaque otherwise
|
||||
tmp->iFlags |= (
|
||||
( ( str.find( '@' ) != std::string::npos )
|
||||
&& ( true == GfxRenderer.Texture( tmp->TextureID ).has_alpha ) ) ?
|
||||
0x20 :
|
||||
0x10 );
|
||||
if( texturehandle != NULL ) {
|
||||
tmp->iFlags |= (
|
||||
( ( texture.name.find( '@' ) != std::string::npos )
|
||||
&& ( true == texture.has_alpha ) ) ?
|
||||
0x20 :
|
||||
0x10 );
|
||||
}
|
||||
else {
|
||||
tmp->iFlags |= 0x10;
|
||||
}
|
||||
|
||||
TGroundVertex vertex, vertex1, vertex2;
|
||||
std::size_t vertexcount{ 0 };
|
||||
|
||||
4
Ground.h
4
Ground.h
@@ -15,7 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "VBO.h"
|
||||
#include "Classes.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Texture.h"
|
||||
#include "material.h"
|
||||
#include "dumb3d.h"
|
||||
#include "Float3d.h"
|
||||
#include "Names.h"
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
int iCount; // dla terenu
|
||||
};
|
||||
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
||||
texture_handle TextureID; // główna (jedna) tekstura obiektu
|
||||
material_handle m_material; // główna (jedna) tekstura obiektu
|
||||
glm::vec3
|
||||
Ambient{ 1.0f, 1.0f, 1.0f },
|
||||
Diffuse{ 1.0f, 1.0f, 1.0f },
|
||||
|
||||
97
Model3d.cpp
97
Model3d.cpp
@@ -63,16 +63,16 @@ TSubModel::~TSubModel()
|
||||
// wyświetlania
|
||||
};
|
||||
|
||||
void TSubModel::TextureNameSet(std::string const &Name)
|
||||
void TSubModel::Name_Material(std::string const &Name)
|
||||
{ // ustawienie nazwy submodelu, o
|
||||
// ile nie jest wczytany z E3D
|
||||
if (iFlags & 0x0200)
|
||||
{ // tylko jeżeli submodel zosta utworzony przez new
|
||||
pTexture = Name;
|
||||
m_materialname = Name;
|
||||
}
|
||||
};
|
||||
|
||||
void TSubModel::NameSet(std::string const &Name)
|
||||
void TSubModel::Name(std::string const &Name)
|
||||
{ // ustawienie nazwy submodelu, o ile
|
||||
// nie jest wczytany z E3D
|
||||
if (iFlags & 0x0200)
|
||||
@@ -177,7 +177,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
std::string token;
|
||||
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
||||
parser >> token;
|
||||
NameSet(token);
|
||||
Name(token);
|
||||
if (dynamic) {
|
||||
// dla pojazdu, blokujemy załączone submodele, które mogą być nieobsługiwane
|
||||
if( ( token.size() >= 3 )
|
||||
@@ -305,50 +305,51 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
*/
|
||||
if (!parser.expectToken("map:"))
|
||||
Error("Model map parse failure!");
|
||||
std::string texture = parser.getToken<std::string>();
|
||||
if (texture == "none")
|
||||
std::string material = parser.getToken<std::string>();
|
||||
if (material == "none")
|
||||
{ // rysowanie podanym kolorem
|
||||
TextureID = 0;
|
||||
m_material = NULL;
|
||||
iFlags |= 0x10; // rysowane w cyklu nieprzezroczystych
|
||||
}
|
||||
else if (texture.find("replacableskin") != texture.npos)
|
||||
else if (material.find("replacableskin") != material.npos)
|
||||
{ // McZapkie-060702: zmienialne skory modelu
|
||||
TextureID = -1;
|
||||
m_material = -1;
|
||||
iFlags |= (Opacity < 1.0) ? 1 : 0x10; // zmienna tekstura 1
|
||||
}
|
||||
else if (texture == "-1")
|
||||
else if (material == "-1")
|
||||
{
|
||||
TextureID = -1;
|
||||
m_material = -1;
|
||||
iFlags |= (Opacity < 1.0) ? 1 : 0x10; // zmienna tekstura 1
|
||||
}
|
||||
else if (texture == "-2")
|
||||
else if (material == "-2")
|
||||
{
|
||||
TextureID = -2;
|
||||
m_material = -2;
|
||||
iFlags |= (Opacity < 1.0) ? 2 : 0x10; // zmienna tekstura 2
|
||||
}
|
||||
else if (texture == "-3")
|
||||
else if (material == "-3")
|
||||
{
|
||||
TextureID = -3;
|
||||
m_material = -3;
|
||||
iFlags |= (Opacity < 1.0) ? 4 : 0x10; // zmienna tekstura 3
|
||||
}
|
||||
else if (texture == "-4")
|
||||
else if (material == "-4")
|
||||
{
|
||||
TextureID = -4;
|
||||
m_material = -4;
|
||||
iFlags |= (Opacity < 1.0) ? 8 : 0x10; // zmienna tekstura 4
|
||||
}
|
||||
else
|
||||
{ // jeśli tylko nazwa pliku, to dawać bieżącą ścieżkę do tekstur
|
||||
TextureNameSet(texture);
|
||||
if( texture.find_first_of( "/\\" ) == texture.npos ) {
|
||||
texture.insert( 0, Global::asCurrentTexturePath );
|
||||
Name_Material(material);
|
||||
if( material.find_first_of( "/\\" ) == material.npos ) {
|
||||
material.insert( 0, Global::asCurrentTexturePath );
|
||||
}
|
||||
TextureID = GfxRenderer.Fetch_Texture( texture );
|
||||
m_material = GfxRenderer.Fetch_Material( material );
|
||||
// renderowanie w cyklu przezroczystych tylko jeśli:
|
||||
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
|
||||
// 2. tekstura ma przezroczystość
|
||||
iFlags |=
|
||||
( ( ( Opacity < 1.0 )
|
||||
&& ( GfxRenderer.Texture(TextureID).has_alpha ) ) ?
|
||||
&& ( ( m_material != NULL )
|
||||
&& ( GfxRenderer.Material( m_material ).has_alpha ) ) ) ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
};
|
||||
@@ -591,10 +592,10 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
return iNumVerts; // do określenia wielkości VBO
|
||||
};
|
||||
|
||||
int TSubModel::TriangleAdd(TModel3d *m, texture_handle tex, int tri)
|
||||
int TSubModel::TriangleAdd(TModel3d *m, material_handle tex, int tri)
|
||||
{ // dodanie trójkątów do submodelu, używane przy tworzeniu E3D terenu
|
||||
TSubModel *s = this;
|
||||
while (s ? (s->TextureID != tex) : false)
|
||||
while (s ? (s->m_material != tex) : false)
|
||||
{ // szukanie submodelu o danej teksturze
|
||||
if (s == this)
|
||||
s = Child;
|
||||
@@ -603,15 +604,15 @@ int TSubModel::TriangleAdd(TModel3d *m, texture_handle tex, int tri)
|
||||
}
|
||||
if (!s)
|
||||
{
|
||||
if (TextureID <= 0)
|
||||
if (m_material <= 0)
|
||||
s = this; // użycie głównego
|
||||
else
|
||||
{ // dodanie nowego submodelu do listy potomnych
|
||||
s = new TSubModel();
|
||||
m->AddTo(this, s);
|
||||
}
|
||||
s->TextureNameSet(GfxRenderer.Texture(tex).name);
|
||||
s->TextureID = tex;
|
||||
s->Name_Material(GfxRenderer.Material(tex).name);
|
||||
s->m_material = tex;
|
||||
s->eType = GL_TRIANGLES;
|
||||
}
|
||||
if (s->iNumVerts < 0)
|
||||
@@ -672,7 +673,7 @@ void TSubModel::DisplayLists()
|
||||
glVertex3dv(&Vertices[i].Point.x);
|
||||
*/
|
||||
glNormal3fv(glm::value_ptr(Vertices[i].normal));
|
||||
glTexCoord2fv(glm::value_ptr(Vertices[i].texture));
|
||||
glTexCoord2fv(glm::value_ptr(Vertices[i].material));
|
||||
glVertex3fv(glm::value_ptr(Vertices[i].position));
|
||||
};
|
||||
glEnd();
|
||||
@@ -806,8 +807,8 @@ int TSubModel::FlagsCheck()
|
||||
int i = 0;
|
||||
if (Child)
|
||||
{ // Child jest renderowany po danym submodelu
|
||||
if (Child->TextureID) // o ile ma teksturę
|
||||
if (Child->TextureID != TextureID) // i jest ona inna niż rodzica
|
||||
if (Child->m_material) // o ile ma teksturę
|
||||
if (Child->m_material != m_material) // i jest ona inna niż rodzica
|
||||
Child->iFlags |= 0x80; // to trzeba sprawdzać, jak z teksturami jest
|
||||
i = Child->FlagsCheck();
|
||||
iFlags |= 0x00FF0000 & ((i << 16) | (i) | (i >> 8)); // potomny, rodzeństwo i dzieci
|
||||
@@ -825,8 +826,8 @@ int TSubModel::FlagsCheck()
|
||||
if (Next)
|
||||
{ // Next jest renderowany po danym submodelu (kolejność odwrócona
|
||||
// po wczytaniu T3D)
|
||||
if (TextureID) // o ile dany ma teksturę
|
||||
if ((TextureID != Next->TextureID) ||
|
||||
if (m_material) // o ile dany ma teksturę
|
||||
if ((m_material != Next->m_material) ||
|
||||
(i & 0x00800000)) // a ma inną albo dzieci zmieniają
|
||||
iFlags |= 0x80; // to dany submodel musi sobie ją ustawiać
|
||||
i = Next->FlagsCheck();
|
||||
@@ -1085,9 +1086,9 @@ TSubModel::convert( TGroundNode &Groundnode ) const {
|
||||
Groundnode.Ambient = f4Ambient;
|
||||
Groundnode.Diffuse = f4Diffuse;
|
||||
Groundnode.Specular = f4Specular;
|
||||
Groundnode.TextureID = TextureID;
|
||||
Groundnode.m_material = m_material;
|
||||
Groundnode.iFlags = (
|
||||
( true == GfxRenderer.Texture( TextureID ).has_alpha ) ?
|
||||
( true == GfxRenderer.Material( m_material ).has_alpha ) ?
|
||||
0x20 :
|
||||
0x10 );
|
||||
|
||||
@@ -1379,10 +1380,10 @@ void TSubModel::serialize(std::ostream &s,
|
||||
sn_utils::ls_int32(s, iNumVerts);
|
||||
sn_utils::ls_int32(s, tVboPtr);
|
||||
|
||||
if (TextureID <= 0)
|
||||
sn_utils::ls_int32(s, TextureID);
|
||||
if (m_material <= 0)
|
||||
sn_utils::ls_int32(s, m_material);
|
||||
else
|
||||
sn_utils::ls_int32(s, (int32_t)get_container_pos(textures, pTexture));
|
||||
sn_utils::ls_int32(s, (int32_t)get_container_pos(textures, m_materialname));
|
||||
|
||||
sn_utils::ls_float32(s, fVisible);
|
||||
sn_utils::ls_float32(s, fLight);
|
||||
@@ -1727,27 +1728,29 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
||||
pName = "";
|
||||
if (iTexture > 0)
|
||||
{ // obsługa stałej tekstury
|
||||
auto const textureindex = static_cast<std::size_t>( iTexture );
|
||||
if( textureindex < t->size() ) {
|
||||
pTexture = t->at( textureindex );
|
||||
if( pTexture.find_last_of( "/\\" ) == std::string::npos )
|
||||
pTexture.insert( 0, Global::asCurrentTexturePath );
|
||||
TextureID = GfxRenderer.Fetch_Texture( pTexture );
|
||||
auto const materialindex = static_cast<std::size_t>( iTexture );
|
||||
if( materialindex < t->size() ) {
|
||||
m_materialname = t->at( materialindex );
|
||||
if( m_materialname.find_last_of( "/\\" ) == std::string::npos ) {
|
||||
m_materialname = Global::asCurrentTexturePath + m_materialname;
|
||||
}
|
||||
m_material = GfxRenderer.Fetch_Material( m_materialname );
|
||||
if( ( iFlags & 0x30 ) == 0 ) {
|
||||
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
|
||||
iFlags |=
|
||||
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
||||
iFlags |= (
|
||||
( ( m_material != NULL )
|
||||
&& ( GfxRenderer.Material( m_material ).has_alpha ) ) ?
|
||||
0x20 :
|
||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorLog( "Bad model: reference to non-existent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ) );
|
||||
TextureID = NULL;
|
||||
m_material = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
TextureID = iTexture;
|
||||
m_material = iTexture;
|
||||
|
||||
b_aAnim = b_Anim; // skopiowanie animacji do drugiego cyklu
|
||||
|
||||
|
||||
20
Model3d.h
20
Model3d.h
@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "dumb3d.h"
|
||||
#include "Float3d.h"
|
||||
#include "VBO.h"
|
||||
#include "Texture.h"
|
||||
#include "material.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
TSubModel *Next { nullptr };
|
||||
TSubModel *Child { nullptr };
|
||||
geometry_handle m_geometry { NULL, NULL }; // geometry of the submodel
|
||||
texture_handle TextureID { NULL }; // numer tekstury, -1 wymienna, 0 brak
|
||||
material_handle m_material { NULL }; // numer tekstury, -1 wymienna, 0 brak
|
||||
bool bWire { false }; // nie używane, ale wczytywane
|
||||
float Opacity { 1.0f };
|
||||
float f_Angle { 0.0f };
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||
TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy
|
||||
int iVisible{ 1 }; // roboczy stan widoczności
|
||||
std::string pTexture; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
std::string m_materialname; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
std::string pName; // robocza nazwa
|
||||
private:
|
||||
int SeekFaceNormal( std::vector<unsigned int> const &Masks, int const Startface, unsigned int const Mask, glm::vec3 const &Position, vertex_array const &Vertices );
|
||||
@@ -151,7 +151,7 @@ private:
|
||||
|
||||
public:
|
||||
static size_t iInstance; // identyfikator egzemplarza, który aktualnie renderuje model
|
||||
static texture_handle const *ReplacableSkinId;
|
||||
static material_handle const *ReplacableSkinId;
|
||||
static int iAlpha; // maska bitowa dla danego przebiegu
|
||||
static double fSquareDist;
|
||||
static TModel3d *pRoot;
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
void NextAdd(TSubModel *SubModel);
|
||||
TSubModel * NextGet() { return Next; };
|
||||
TSubModel * ChildGet() { return Child; };
|
||||
int TriangleAdd(TModel3d *m, texture_handle tex, int tri);
|
||||
int TriangleAdd(TModel3d *m, material_handle tex, int tri);
|
||||
/*
|
||||
basic_vertex * TrianglePtr(int tex, int pos, glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular );
|
||||
*/
|
||||
@@ -186,13 +186,13 @@ public:
|
||||
};
|
||||
void InitialRotate(bool doit);
|
||||
void BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
|
||||
void ReplacableSet(texture_handle const *r, int a)
|
||||
void ReplacableSet(material_handle const *r, int a)
|
||||
{
|
||||
ReplacableSkinId = r;
|
||||
iAlpha = a;
|
||||
};
|
||||
void TextureNameSet( std::string const &Name );
|
||||
void NameSet( std::string const &Name );
|
||||
void Name_Material( std::string const &Name );
|
||||
void Name( std::string const &Name );
|
||||
// Ra: funkcje do budowania terenu z E3D
|
||||
int Flags() { return iFlags; };
|
||||
void UnFlagNext() { iFlags &= 0x00FFFFFF; };
|
||||
@@ -203,8 +203,8 @@ public:
|
||||
return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; }
|
||||
inline float3 Translation2Get() {
|
||||
return *(fMatrix->TranslationGet()) + Child->Translation1Get(); }
|
||||
int GetTextureId() {
|
||||
return TextureID; }
|
||||
material_handle GetMaterial() {
|
||||
return m_material; }
|
||||
void ParentMatrix(float4x4 *m);
|
||||
float MaxY( float4x4 const &m );
|
||||
void AdjustDist();
|
||||
|
||||
25
PyInt.cpp
25
PyInt.cpp
@@ -291,21 +291,16 @@ void TPythonScreenRenderer::updateTexture()
|
||||
sprintf(buff, "Sending texture id: %d w: %d h: %d", _textureId, width, height);
|
||||
WriteLog(buff);
|
||||
#endif // _PY_INT_MORE_LOG
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
GfxRenderer.Bind(_textureId);
|
||||
/*
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
||||
*/
|
||||
GfxRenderer.Bind_Material(_textureId);
|
||||
// setup texture parameters
|
||||
if( GLEW_VERSION_1_4 ) {
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 );
|
||||
}
|
||||
else {
|
||||
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
}
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0 );
|
||||
// build texture
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData );
|
||||
|
||||
@@ -457,7 +452,7 @@ void TPythonScreens::init(cParser &parser, TModel3d *model, std::string const &n
|
||||
WriteLog( "Python Screen: submodel " + subModelName + " not found - Ignoring screen" );
|
||||
return; // nie ma takiego sub modelu w danej kabinie pomijamy
|
||||
}
|
||||
auto textureId = subModel->GetTextureId();
|
||||
auto textureId = subModel->GetMaterial();
|
||||
if (textureId <= 0)
|
||||
{
|
||||
WriteLog( "Python Screen: invalid texture id " + std::to_string(textureId) + " - Ignoring screen" );
|
||||
|
||||
@@ -454,7 +454,7 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
|
||||
void TSegment::Render()
|
||||
{
|
||||
vector3 pt;
|
||||
GfxRenderer.Bind(0);
|
||||
GfxRenderer.Bind_Material( NULL );
|
||||
|
||||
if (bCurve)
|
||||
{
|
||||
|
||||
40
Sound.cpp
40
Sound.cpp
@@ -244,50 +244,14 @@ bool TSoundsManager::Init(HWND hWnd) {
|
||||
pDS = nullptr;
|
||||
pDSNotify = nullptr;
|
||||
|
||||
HRESULT hr; //=222;
|
||||
LPDIRECTSOUNDBUFFER pDSBPrimary = nullptr;
|
||||
|
||||
// Create IDirectSound using the primary sound device
|
||||
hr = DirectSoundCreate(NULL, &pDS, NULL);
|
||||
auto hr = ::DirectSoundCreate(NULL, &pDS, NULL);
|
||||
if (hr != DS_OK) {
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Set coop level to DSSCL_PRIORITY
|
||||
// if( FAILED( hr = pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) ) );
|
||||
// return ;
|
||||
pDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);
|
||||
|
||||
// Get the primary buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
if (!Global::bInactivePause) // jeśli przełączony w tło ma nadal działać
|
||||
dsbd.dwFlags |= DSBCAPS_GLOBALFOCUS; // to dźwięki mają być również słyszalne
|
||||
dsbd.dwBufferBytes = 0;
|
||||
dsbd.lpwfxFormat = NULL;
|
||||
|
||||
if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set primary buffer format to 22kHz and 16-bit output.
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = 44100;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat( &wfx ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pDSBPrimary);
|
||||
pDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
123
Texture.cpp
123
Texture.cpp
@@ -506,18 +506,15 @@ opengl_texture::load_TGA() {
|
||||
return;
|
||||
}
|
||||
|
||||
resource_state
|
||||
bool
|
||||
opengl_texture::bind() {
|
||||
|
||||
if( false == is_ready ) {
|
||||
|
||||
create();
|
||||
if( data_state != resource_state::good ) {
|
||||
return data_state;
|
||||
}
|
||||
if( ( false == is_ready )
|
||||
&& ( false == create() ) ) {
|
||||
return false;
|
||||
}
|
||||
::glBindTexture( GL_TEXTURE_2D, id );
|
||||
return data_state;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -645,40 +642,7 @@ opengl_texture::set_filtering() {
|
||||
switch( trait ) {
|
||||
|
||||
case '#': { sharpen = true; break; }
|
||||
/*
|
||||
// legacy filter modes. TODO, TBD: get rid of them?
|
||||
// let's just turn them off and see if anyone notices.
|
||||
case '4': {
|
||||
// najbliższy z tekstury
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
||||
break;
|
||||
}
|
||||
case '5': {
|
||||
//średnia z tekstury
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
break;
|
||||
}
|
||||
case '6': {
|
||||
// najbliższy z mipmapy
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST );
|
||||
break;
|
||||
}
|
||||
case '7': {
|
||||
//średnia z mipmapy
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
|
||||
break;
|
||||
}
|
||||
case '8': {
|
||||
// najbliższy z dwóch mipmap
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR );
|
||||
break;
|
||||
}
|
||||
case '9': {
|
||||
//średnia z dwóch mipmap
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
break;
|
||||
}
|
||||
*/
|
||||
default: { break; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,9 +682,27 @@ opengl_texture::downsize( GLuint const Format ) {
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
texture_manager::assign_units( GLint const Helper, GLint const Shadows, GLint const Normals, GLint const Diffuse ) {
|
||||
|
||||
m_units[ 0 ].unit = Helper;
|
||||
m_units[ 1 ].unit = Shadows;
|
||||
m_units[ 2 ].unit = Normals;
|
||||
m_units[ 3 ].unit = Diffuse;
|
||||
}
|
||||
|
||||
void
|
||||
texture_manager::unit( GLint const Textureunit ) {
|
||||
|
||||
if( m_activeunit == Textureunit ) { return; }
|
||||
|
||||
m_activeunit = Textureunit;
|
||||
::glActiveTexture( Textureunit );
|
||||
}
|
||||
|
||||
// ustalenie numeru tekstury, wczytanie jeśli jeszcze takiej nie było
|
||||
texture_handle
|
||||
texture_manager::create( std::string Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
|
||||
texture_manager::create( std::string Filename, bool const Loadnow ) {
|
||||
|
||||
if( Filename.find( '|' ) != std::string::npos )
|
||||
Filename.erase( Filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
||||
@@ -801,11 +783,7 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
|
||||
auto texture = new opengl_texture();
|
||||
texture->name = filename;
|
||||
if( ( Filter > 0 ) && ( Filter < 10 ) ) {
|
||||
// temporary. TODO, TBD: check how it's used and possibly get rid of it
|
||||
traits += std::to_string( ( Filter < 4 ? Filter + 4 : Filter ) );
|
||||
}
|
||||
if( Filename.find('#') !=std::string::npos ) {
|
||||
if( Filename.find('#') != std::string::npos ) {
|
||||
// temporary code for legacy assets -- textures with names beginning with # are to be sharpened
|
||||
traits += '#';
|
||||
}
|
||||
@@ -830,33 +808,37 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
};
|
||||
|
||||
void
|
||||
texture_manager::bind( texture_handle const Texture ) {
|
||||
texture_manager::bind( std::size_t const Unit, texture_handle const Texture ) {
|
||||
|
||||
m_textures[ Texture ].second = m_garbagecollector.timestamp();
|
||||
|
||||
if( ( Texture != 0 ) && ( Texture == m_activetexture ) ) {
|
||||
if( Texture == m_units[ Unit ].texture ) {
|
||||
// don't bind again what's already active
|
||||
return;
|
||||
}
|
||||
// TODO: do binding in texture object, add support for other types
|
||||
if( Texture != 0 ) {
|
||||
// TBD, TODO: do binding in texture object, add support for other types than 2d
|
||||
if( m_units[ Unit ].unit == NULL ) { return; }
|
||||
unit( m_units[ Unit ].unit );
|
||||
if( Texture != NULL ) {
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
||||
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
||||
m_activetexture = Texture;
|
||||
m_units[ Unit ].texture = Texture;
|
||||
#else
|
||||
if( texture( Texture ).bind() == resource_state::good ) {
|
||||
m_activetexture = Texture;
|
||||
if( true == texture( Texture ).bind() ) {
|
||||
m_units[ Unit ].texture = Texture;
|
||||
}
|
||||
else {
|
||||
// TODO: bind a special 'error' texture on failure
|
||||
::glBindTexture( GL_TEXTURE_2D, NULL );
|
||||
m_units[ Unit ].texture = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
m_activetexture = 0;
|
||||
::glBindTexture( GL_TEXTURE_2D, NULL );
|
||||
m_units[ Unit ].texture = NULL;
|
||||
}
|
||||
// all done
|
||||
return;
|
||||
@@ -879,7 +861,9 @@ void
|
||||
texture_manager::update() {
|
||||
|
||||
if( m_garbagecollector.sweep() > 0 ) {
|
||||
m_activetexture = -1;
|
||||
for( auto &unit : m_units ) {
|
||||
unit.texture = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,21 +927,10 @@ texture_manager::find_in_databank( std::string const &Texturename ) const {
|
||||
std::string
|
||||
texture_manager::find_on_disk( std::string const &Texturename ) const {
|
||||
|
||||
{
|
||||
std::ifstream file( Texturename );
|
||||
if( true == file.is_open() ) {
|
||||
// success
|
||||
return Texturename;
|
||||
}
|
||||
}
|
||||
// if we fail make a last ditch attempt in the default textures directory
|
||||
{
|
||||
std::ifstream file( szTexturePath + Texturename );
|
||||
if( true == file.is_open() ) {
|
||||
// success
|
||||
return szTexturePath + Texturename;
|
||||
}
|
||||
}
|
||||
// no results either way, report failure
|
||||
return "";
|
||||
return(
|
||||
FileExists( Texturename ) ? Texturename :
|
||||
FileExists( szTexturePath + Texturename ) ? szTexturePath + Texturename :
|
||||
"" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
25
Texture.h
25
Texture.h
@@ -31,7 +31,7 @@ struct opengl_texture {
|
||||
// methods
|
||||
void
|
||||
load();
|
||||
resource_state
|
||||
bool
|
||||
bind();
|
||||
bool
|
||||
create();
|
||||
@@ -85,12 +85,17 @@ public:
|
||||
texture_manager();
|
||||
~texture_manager() { delete_textures(); }
|
||||
|
||||
texture_handle
|
||||
create( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
||||
void
|
||||
bind( texture_handle const Texture );
|
||||
assign_units( GLint const Helper, GLint const Shadows, GLint const Normals, GLint const Diffuse );
|
||||
void
|
||||
unit( GLint const Textureunit );
|
||||
texture_handle
|
||||
create( std::string Filename, bool const Loadnow = true );
|
||||
// binds specified texture to specified texture unit
|
||||
void
|
||||
bind( std::size_t const Unit, texture_handle const Texture );
|
||||
opengl_texture &
|
||||
texture( texture_handle const Texture ) { return *(m_textures[ Texture ].first); }
|
||||
texture( texture_handle const Texture ) const { return *(m_textures[ Texture ].first); }
|
||||
// performs a resource sweep
|
||||
void
|
||||
update();
|
||||
@@ -108,6 +113,11 @@ private:
|
||||
|
||||
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||
|
||||
struct texture_unit {
|
||||
GLint unit { NULL };
|
||||
texture_handle texture { NULL }; // current (most recently bound) texture
|
||||
};
|
||||
|
||||
// methods:
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
texture_handle
|
||||
@@ -123,7 +133,8 @@ private:
|
||||
texturetimepointpair_sequence m_textures;
|
||||
index_map m_texturemappings;
|
||||
garbage_collector<texturetimepointpair_sequence> m_garbagecollector { m_textures, 600, 60, "texture" };
|
||||
texture_handle m_activetexture { 0 }; // last i.e. currently bound texture
|
||||
std::array<texture_unit, 4> m_units;
|
||||
GLint m_activeunit { NULL };
|
||||
};
|
||||
|
||||
// reduces provided data image to half of original size, using basic 2x2 average
|
||||
@@ -182,3 +193,5 @@ downsample( std::size_t const Width, std::size_t const Height, char *Imagedata )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
60
Track.cpp
60
Track.cpp
@@ -483,20 +483,20 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
{
|
||||
parser->getTokens();
|
||||
*parser >> str; // railtex
|
||||
TextureID1 = (
|
||||
m_material1 = (
|
||||
str == "none" ?
|
||||
NULL :
|
||||
GfxRenderer.Fetch_Texture( str ) );
|
||||
GfxRenderer.Fetch_Material( str ) );
|
||||
parser->getTokens();
|
||||
*parser >> fTexLength; // tex tile length
|
||||
if (fTexLength < 0.01)
|
||||
fTexLength = 4; // Ra: zabezpiecznie przed zawieszeniem
|
||||
parser->getTokens();
|
||||
*parser >> str; // sub || railtex
|
||||
TextureID2 = (
|
||||
m_material2 = (
|
||||
str == "none" ?
|
||||
NULL :
|
||||
GfxRenderer.Fetch_Texture( str ) );
|
||||
GfxRenderer.Fetch_Material( str ) );
|
||||
parser->getTokens(3);
|
||||
*parser >> fTexHeight1 >> fTexWidth >> fTexSlope;
|
||||
if (iCategoryFlag & 4)
|
||||
@@ -547,15 +547,15 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
SwitchExtension->Segments[0]->Init(p1, p2, segsize); // kopia oryginalnego toru
|
||||
}
|
||||
else if (iCategoryFlag & 2)
|
||||
if (TextureID1 && fTexLength)
|
||||
if (m_material1 && fTexLength)
|
||||
{ // dla drogi trzeba ustalić proporcje boków nawierzchni
|
||||
float w, h;
|
||||
GfxRenderer.Bind(TextureID1);
|
||||
GfxRenderer.Bind_Material(m_material1);
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
if (h != 0.0)
|
||||
fTexRatio1 = w / h; // proporcja boków
|
||||
GfxRenderer.Bind(TextureID2);
|
||||
GfxRenderer.Bind_Material(m_material2);
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
if (h != 0.0)
|
||||
@@ -1205,7 +1205,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
{
|
||||
case tt_Table: // obrotnica jak zwykły tor, tylko animacja dochodzi
|
||||
case tt_Normal:
|
||||
if (TextureID2)
|
||||
if (m_material2)
|
||||
{ // podsypka z podkładami jest tylko dla zwykłego toru
|
||||
vector6 bpts1[8]; // punkty głównej płaszczyzny nie przydają się do robienia boków
|
||||
if (fTexLength == 4.0) // jeśli stare mapowanie
|
||||
@@ -1275,7 +1275,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
|
||||
}
|
||||
}
|
||||
if (TextureID1)
|
||||
if (m_material1)
|
||||
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
|
||||
vertex_array vertices;
|
||||
if( ( Bank != 0 ) && ( true == Geometry1.empty() ) ) {
|
||||
@@ -1296,7 +1296,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
}
|
||||
break;
|
||||
case tt_Switch: // dla zwrotnicy dwa razy szyny
|
||||
if( TextureID1 || TextureID2 )
|
||||
if( m_material1 || m_material2 )
|
||||
{ // iglice liczone tylko dla zwrotnic
|
||||
vector6 rpts3[24], rpts4[24];
|
||||
for (i = 0; i < 12; ++i)
|
||||
@@ -1326,7 +1326,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
vertex_array vertices;
|
||||
if( TextureID1 ) {
|
||||
if( m_material1 ) {
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength );
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
@@ -1339,7 +1339,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( m_material2 ) {
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength );
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
@@ -1356,7 +1356,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
else
|
||||
{ // lewa działa lepiej niż prawa
|
||||
vertex_array vertices;
|
||||
if( TextureID1 ) {
|
||||
if( m_material1 ) {
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
@@ -1369,7 +1369,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( m_material2 ) {
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
@@ -1394,7 +1394,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
case tt_Normal: // drogi proste, bo skrzyżowania osobno
|
||||
{
|
||||
vector6 bpts1[4]; // punkty głównej płaszczyzny przydają się do robienia boków
|
||||
if (TextureID1 || TextureID2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
if (m_material1 || m_material2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
{ // double max=2.0*(fHTW>fHTW2?fHTW:fHTW2); //z szerszej strony jest 100%
|
||||
double max = fTexRatio1 * fTexLength; // test: szerokość proporcjonalna do długości
|
||||
double map1 = max > 0.0 ? fHTW / max : 0.5; // obcięcie tekstury od strony 1
|
||||
@@ -1413,13 +1413,13 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
bpts1[ 1 ] = vector6( -fHTW, 0.0, 0.5 + map1, 0.0, 1.0, 0.0 );
|
||||
}
|
||||
}
|
||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
if (m_material1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
{ // tworzenie trójkątów nawierzchni szosy
|
||||
vertex_array vertices;
|
||||
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
}
|
||||
if (TextureID2)
|
||||
if (m_material2)
|
||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||
vector6
|
||||
rpts1[6],
|
||||
@@ -1574,7 +1574,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
nullptr :
|
||||
SwitchExtension->vPoints; // zmienna robocza, NULL gdy tablica punktów już jest wypełniona
|
||||
vector6 bpts1[4]; // punkty głównej płaszczyzny przydają się do robienia boków
|
||||
if (TextureID1 || TextureID2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
if (m_material1 || m_material2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
{ // double max=2.0*(fHTW>fHTW2?fHTW:fHTW2); //z szerszej strony jest 100%
|
||||
double max = fTexRatio1 * fTexLength; // test: szerokość proporcjonalna do długości
|
||||
double map1 = max > 0.0 ? fHTW / max : 0.5; // obcięcie tekstury od strony 1
|
||||
@@ -1592,7 +1592,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
// problem ze skrzyżowaniami jest taki, że teren chce się pogrupować wg tekstur, ale zaczyna od nawierzchni
|
||||
// sama nawierzchnia nie wypełni tablicy punktów, bo potrzebne są pobocza
|
||||
// ale pobocza renderują się później, więc nawierzchnia nie załapuje się na renderowanie w swoim czasie
|
||||
if( TextureID2 )
|
||||
if( m_material2 )
|
||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||
vector6
|
||||
rpts1[6],
|
||||
@@ -1651,7 +1651,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
rpts2[5] = vector6(bpts1[3].x - side2, bpts1[3].y - fTexHeight2, 0.484375 - map2l); // lewy brzeg lewego chodnika
|
||||
}
|
||||
}
|
||||
bool render = ( TextureID2 != 0 ); // renderować nie trzeba, ale trzeba wyznaczyć punkty brzegowe nawierzchni
|
||||
bool render = ( m_material2 != 0 ); // renderować nie trzeba, ale trzeba wyznaczyć punkty brzegowe nawierzchni
|
||||
vertex_array vertices;
|
||||
if (SwitchExtension->iRoads == 4)
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
||||
@@ -1707,7 +1707,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||
}
|
||||
|
||||
if( TextureID1 ) {
|
||||
if( m_material1 ) {
|
||||
vertex_array vertices;
|
||||
// jeśli podana tekstura nawierzchni
|
||||
// we start with a vertex in the middle...
|
||||
@@ -1759,7 +1759,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
case tt_Normal: // drogi proste, bo skrzyżowania osobno
|
||||
{
|
||||
vector6 bpts1[4]; // punkty głównej płaszczyzny przydają się do robienia boków
|
||||
if (TextureID1 || TextureID2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
if (m_material1 || m_material2) // punkty się przydadzą, nawet jeśli nawierzchni nie ma
|
||||
{ // double max=2.0*(fHTW>fHTW2?fHTW:fHTW2); //z szerszej strony jest 100%
|
||||
double max = (iCategoryFlag & 4) ?
|
||||
0.0 :
|
||||
@@ -1784,13 +1784,13 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
|
||||
bpts1[1] = vector6(-fHTW, 0.0, 0.5 + map1);
|
||||
}
|
||||
}
|
||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
if (m_material1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
{ // tworzenie trójkątów nawierzchni szosy
|
||||
vertex_array vertices;
|
||||
Segment->RenderLoft(vertices, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
}
|
||||
if (TextureID2)
|
||||
if (m_material2)
|
||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||
vertex_array vertices;
|
||||
vector6 rpts1[6],
|
||||
@@ -2105,8 +2105,8 @@ TTrack * TTrack::RaAnimate()
|
||||
}
|
||||
}
|
||||
// skip the geometry update if no geometry for this track was generated yet
|
||||
if( ( ( TextureID1 != 0 )
|
||||
|| ( TextureID2 != 0 ) )
|
||||
if( ( ( m_material1 != 0 )
|
||||
|| ( m_material2 != 0 ) )
|
||||
&& ( ( false == Geometry1.empty() )
|
||||
|| ( false == Geometry2.empty() ) ) ) {
|
||||
// iglice liczone tylko dla zwrotnic
|
||||
@@ -2143,13 +2143,13 @@ TTrack * TTrack::RaAnimate()
|
||||
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
if( TextureID1 ) {
|
||||
if( m_material1 ) {
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( m_material2 ) {
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
@@ -2157,13 +2157,13 @@ TTrack * TTrack::RaAnimate()
|
||||
}
|
||||
}
|
||||
else { // lewa działa lepiej niż prawa
|
||||
if( TextureID1 ) {
|
||||
if( m_material1 ) {
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( m_material2 ) {
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
|
||||
10
Track.h
10
Track.h
@@ -13,7 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "GL/glew.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Segment.h"
|
||||
#include "Texture.h"
|
||||
#include "material.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -142,8 +142,8 @@ private:
|
||||
/*
|
||||
GLuint DisplayListID = 0;
|
||||
*/
|
||||
texture_handle TextureID1 = 0; // tekstura szyn albo nawierzchni
|
||||
texture_handle TextureID2 = 0; // tekstura automatycznej podsypki albo pobocza
|
||||
material_handle m_material1 = 0; // tekstura szyn albo nawierzchni
|
||||
material_handle m_material2 = 0; // tekstura automatycznej podsypki albo pobocza
|
||||
typedef std::vector<geometry_handle> geometryhandle_sequence;
|
||||
geometryhandle_sequence Geometry1; // geometry chunks textured with texture 1
|
||||
geometryhandle_sequence Geometry2; // geometry chunks textured with texture 2
|
||||
@@ -257,8 +257,8 @@ public:
|
||||
GLuint TextureGet(int i) {
|
||||
return (
|
||||
i ?
|
||||
TextureID1 :
|
||||
TextureID2 ); };
|
||||
m_material1 :
|
||||
m_material2 ); };
|
||||
bool IsGroupable();
|
||||
int TestPoint(vector3 *Point);
|
||||
void MovedUp1(float const dh);
|
||||
|
||||
@@ -225,6 +225,9 @@
|
||||
<ClCompile Include="translation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="material.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Globals.h">
|
||||
@@ -440,6 +443,9 @@
|
||||
<ClInclude Include="translation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="material.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="maszyna.rc">
|
||||
|
||||
143
material.cpp
Normal file
143
material.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
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/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "material.h"
|
||||
#include "renderer.h"
|
||||
#include "usefull.h"
|
||||
#include "globals.h"
|
||||
|
||||
bool
|
||||
opengl_material::deserialize( cParser &Input, bool const Loadnow ) {
|
||||
|
||||
bool result { false };
|
||||
while( true == deserialize_mapping( Input, Loadnow ) ) {
|
||||
result = true; // once would suffice but, eh
|
||||
}
|
||||
|
||||
has_alpha = (
|
||||
texture1 != NULL ?
|
||||
GfxRenderer.Texture( texture1 ).has_alpha :
|
||||
false );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// imports member data pair from the config file
|
||||
bool
|
||||
opengl_material::deserialize_mapping( cParser &Input, bool const Loadnow ) {
|
||||
|
||||
if( false == Input.getTokens( 2, true, "\n\r\t;, " ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if( name.rfind( '\\' ) != std::string::npos ) {
|
||||
path = name.substr( 0, name.rfind( '\\' ) + 1 );
|
||||
}
|
||||
|
||||
std::string key, value;
|
||||
Input
|
||||
>> key
|
||||
>> value;
|
||||
|
||||
if( key == "texture1:" ) { texture1 = GfxRenderer.Fetch_Texture( path + value, Loadnow ); }
|
||||
else if( key == "texture2:" ) { texture2 = GfxRenderer.Fetch_Texture( path + value, Loadnow ); }
|
||||
|
||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||
}
|
||||
|
||||
|
||||
// create material object from data stored in specified file.
|
||||
// NOTE: the deferred load parameter is passed to textures defined by material, the material itself is always loaded immediately
|
||||
material_handle
|
||||
material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
||||
|
||||
auto filename { Filename };
|
||||
|
||||
if( filename.find( '|' ) != std::string::npos )
|
||||
filename.erase( filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
||||
|
||||
if( filename.rfind( '.' ) != std::string::npos ) {
|
||||
// we can get extension for .mat or, in legacy files, some image format. just trim it and set it to material file extension
|
||||
filename.erase( filename.rfind( '.' ) );
|
||||
}
|
||||
filename += ".mat";
|
||||
|
||||
for( char &c : filename ) {
|
||||
// change forward slashes to windows ones. NOTE: probably not strictly necessary, but eh
|
||||
c = ( c == '/' ? '\\' : c );
|
||||
}
|
||||
if( filename.find( '\\' ) == std::string::npos ) {
|
||||
// jeśli bieżaca ścieżka do tekstur nie została dodana to dodajemy domyślną
|
||||
filename = szTexturePath + filename;
|
||||
}
|
||||
|
||||
// try to locate requested material in the databank
|
||||
auto const databanklookup = find_in_databank( filename );
|
||||
if( databanklookup != npos ) {
|
||||
return databanklookup;
|
||||
}
|
||||
// if this fails, try to look for it on disk
|
||||
opengl_material material;
|
||||
material.name = filename;
|
||||
auto const disklookup = find_on_disk( filename );
|
||||
if( disklookup != "" ) {
|
||||
cParser materialparser( disklookup, cParser::buffer_FILE );
|
||||
if( false == material.deserialize( materialparser, Loadnow ) ) {
|
||||
// deserialization failed but the .mat file does exist, so we give up at this point
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if there's no .mat file, this could be legacy method of referring just to diffuse texture directly, make a material out of it in such case
|
||||
material.texture1 = GfxRenderer.Fetch_Texture( Filename, Loadnow );
|
||||
if( material.texture1 == NULL ) {
|
||||
// if there's also no texture, give up
|
||||
return NULL;
|
||||
}
|
||||
material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha;
|
||||
}
|
||||
|
||||
material_handle handle = m_materials.size();
|
||||
m_materials.emplace_back( material );
|
||||
m_materialmappings.emplace( material.name, handle );
|
||||
return handle;
|
||||
};
|
||||
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
material_handle
|
||||
material_manager::find_in_databank( std::string const &Materialname ) const {
|
||||
|
||||
auto lookup = m_materialmappings.find( Materialname );
|
||||
if( lookup != m_materialmappings.end() ) {
|
||||
return lookup->second;
|
||||
}
|
||||
// jeszcze próba z dodatkową ścieżką
|
||||
lookup = m_materialmappings.find( szTexturePath + Materialname );
|
||||
|
||||
return (
|
||||
lookup != m_materialmappings.end() ?
|
||||
lookup->second :
|
||||
npos );
|
||||
}
|
||||
|
||||
// checks whether specified file exists.
|
||||
// NOTE: this is direct copy of the method used by texture manager. TBD, TODO: refactor into common routine?
|
||||
std::string
|
||||
material_manager::find_on_disk( std::string const &Materialname ) const {
|
||||
|
||||
return(
|
||||
FileExists( Materialname ) ? Materialname :
|
||||
FileExists( szTexturePath + Materialname ) ? szTexturePath + Materialname :
|
||||
"" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
64
material.h
Normal file
64
material.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 "texture.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef int material_handle;
|
||||
|
||||
// a collection of parameters for the rendering setup.
|
||||
// for modern opengl this translates to set of attributes for the active shaders,
|
||||
// for legacy opengl this is basically just texture(s) assigned to geometry
|
||||
struct opengl_material {
|
||||
|
||||
texture_handle texture1 { NULL }; // primary texture, typically diffuse+apha
|
||||
texture_handle texture2 { NULL }; // secondary texture, typically normal+reflection
|
||||
|
||||
bool has_alpha { false }; // alpha state, calculated from presence of alpha in texture1
|
||||
std::string name;
|
||||
// methods:
|
||||
bool
|
||||
deserialize( cParser &Input, bool const Loadnow );
|
||||
private:
|
||||
// imports member data pair from the config file
|
||||
bool
|
||||
deserialize_mapping( cParser &Input, bool const Loadnow );
|
||||
};
|
||||
|
||||
class material_manager {
|
||||
|
||||
public:
|
||||
material_manager() { m_materials.emplace_back( opengl_material() ); } // empty bindings for null material
|
||||
|
||||
material_handle
|
||||
create( std::string const &Filename, bool const Loadnow );
|
||||
opengl_material const &
|
||||
material( material_handle const Material ) const { return m_materials[ Material ]; }
|
||||
|
||||
private:
|
||||
// types
|
||||
typedef std::vector<opengl_material> material_sequence;
|
||||
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||
// methods:
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
material_handle
|
||||
find_in_databank( std::string const &Materialname ) const;
|
||||
// checks whether specified file exists. returns name of the located file, or empty string.
|
||||
std::string
|
||||
find_on_disk( std::string const &Materialname ) const;
|
||||
// members:
|
||||
material_handle const npos { -1 };
|
||||
material_sequence m_materials;
|
||||
index_map m_materialmappings;
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -120,6 +120,7 @@ geometry_bank::vertices( geometry_handle const &Geometry ) const {
|
||||
|
||||
GLuint opengl_vbogeometrybank::m_activebuffer { NULL }; // buffer bound currently on the opengl end, if any
|
||||
unsigned int opengl_vbogeometrybank::m_activestreams { stream::none }; // currently enabled data type pointers
|
||||
std::vector<GLint> opengl_vbogeometrybank::m_activetexturearrays; // currently enabled texture coord arrays
|
||||
|
||||
// create() subclass details
|
||||
void
|
||||
@@ -274,12 +275,19 @@ opengl_vbogeometrybank::bind_streams( stream_units const &Units, unsigned int co
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
if( Streams & stream::texture ) {
|
||||
::glClientActiveTexture( Units.texture );
|
||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 24 );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
for( auto unit : Units.texture ) {
|
||||
::glClientActiveTexture( unit );
|
||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( basic_vertex ), static_cast<char *>( nullptr ) + 24 );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
m_activetexturearrays = Units.texture;
|
||||
}
|
||||
else {
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
for( auto unit : Units.texture ) {
|
||||
::glClientActiveTexture( unit );
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
m_activetexturearrays.clear(); // NOTE: we're simplifying here, since we always toggle the same texture coord sets
|
||||
}
|
||||
|
||||
m_activestreams = Streams;
|
||||
@@ -291,9 +299,13 @@ opengl_vbogeometrybank::release_streams() {
|
||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
for( auto unit : m_activetexturearrays ) {
|
||||
::glClientActiveTexture( unit );
|
||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
|
||||
m_activestreams = stream::none;
|
||||
m_activetexturearrays.clear();
|
||||
}
|
||||
|
||||
// opengl display list based variant of the geometry bank
|
||||
@@ -331,7 +343,7 @@ opengl_dlgeometrybank::draw_( geometry_handle const &Geometry, stream_units cons
|
||||
for( auto const &vertex : chunk.vertices ) {
|
||||
if( Streams & stream::normal ) { ::glNormal3fv( glm::value_ptr( vertex.normal ) ); }
|
||||
else if( Streams & stream::color ) { ::glColor3fv( glm::value_ptr( vertex.normal ) ); }
|
||||
if( Streams & stream::texture ) { ::glMultiTexCoord2fv( Units.texture, glm::value_ptr( vertex.texture ) ); }
|
||||
if( Streams & stream::texture ) { for( auto unit : Units.texture ) { ::glMultiTexCoord2fv( unit, glm::value_ptr( vertex.texture ) ); } }
|
||||
if( Streams & stream::position ) { ::glVertex3fv( glm::value_ptr( vertex.position ) ); }
|
||||
}
|
||||
::glEnd();
|
||||
|
||||
@@ -46,7 +46,7 @@ unsigned int const color_streams { stream::position | stream::color | stream::te
|
||||
|
||||
struct stream_units {
|
||||
|
||||
GLint texture { GL_TEXTURE0 }; // unit associated with main texture data stream. TODO: allow multiple units per stream
|
||||
std::vector<GLint> texture { GL_TEXTURE0 }; // unit associated with main texture data stream. TODO: allow multiple units per stream
|
||||
};
|
||||
|
||||
typedef std::vector<basic_vertex> vertex_array;
|
||||
@@ -207,6 +207,7 @@ private:
|
||||
// members:
|
||||
static GLuint m_activebuffer; // buffer bound currently on the opengl end, if any
|
||||
static unsigned int m_activestreams;
|
||||
static std::vector<GLint> m_activetexturearrays;
|
||||
GLuint m_buffer { NULL }; // id of the buffer holding data on the opengl end
|
||||
std::size_t m_buffercapacity{ 0 }; // total capacity of the last established buffer
|
||||
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
||||
|
||||
257
renderer.cpp
257
renderer.cpp
@@ -98,9 +98,10 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
glEnable( GL_CULL_FACE ); // Cull back-facing triangles
|
||||
glShadeModel( GL_SMOOTH ); // Enable Smooth Shading
|
||||
|
||||
glActiveTexture( m_diffusetextureunit );
|
||||
m_geometry.units().texture = m_diffusetextureunit;
|
||||
m_geometry.units().texture = std::vector<GLint>{ m_normaltextureunit, m_diffusetextureunit };
|
||||
m_textures.assign_units( m_helpertextureunit, m_shadowtextureunit, m_normaltextureunit, m_diffusetextureunit ); // TODO: add reflections unit
|
||||
UILayer.set_unit( m_diffusetextureunit );
|
||||
Active_Texture( m_diffusetextureunit );
|
||||
|
||||
::glDepthFunc( GL_LEQUAL );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
@@ -215,7 +216,7 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
|
||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
|
||||
::glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
|
||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
::glBindTexture( GL_TEXTURE_2D, NULL );
|
||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||
::glGenTextures( 1, &m_shadowdebugtexture );
|
||||
::glBindTexture( GL_TEXTURE_2D, m_shadowdebugtexture );
|
||||
@@ -577,24 +578,12 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
|
||||
case rendermode::pickscenery: {
|
||||
// TODO: scissor test for pick modes
|
||||
// projection
|
||||
if( true == m_framebuffersupport ) {
|
||||
auto const angle = Global::FieldOfView / Global::ZoomFactor;
|
||||
auto const height = std::max( 1.0f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE );
|
||||
camera.projection() *=
|
||||
glm::perspective(
|
||||
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.0f, (float)Global::iWindowHeight ) / ( Global::iWindowWidth / EU07_PICKBUFFERSIZE ),
|
||||
0.1f * Global::ZoomFactor,
|
||||
Config.draw_range * Global::fDistanceFactor );
|
||||
}
|
||||
else {
|
||||
camera.projection() *=
|
||||
glm::perspective(
|
||||
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.f, (float)Global::iWindowHeight ),
|
||||
0.1f * Global::ZoomFactor,
|
||||
Config.draw_range * Global::fDistanceFactor );
|
||||
}
|
||||
camera.projection() *=
|
||||
glm::perspective(
|
||||
glm::radians( Global::FieldOfView / Global::ZoomFactor ),
|
||||
std::max( 1.f, (float)Global::iWindowWidth ) / std::max( 1.f, (float)Global::iWindowHeight ),
|
||||
0.1f * Global::ZoomFactor,
|
||||
Config.draw_range * Global::fDistanceFactor );
|
||||
// modelview
|
||||
camera.position() = Global::pCameraPosition;
|
||||
World.Camera.SetMatrix( viewmatrix );
|
||||
@@ -674,17 +663,20 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
||||
// helper texture unit.
|
||||
// darkens previous stage, preparing data for the shadow texture unit to select from
|
||||
if( m_helpertextureunit >= 0 ) {
|
||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
||||
// setup reflection texture unit
|
||||
::glActiveTexture( m_helpertextureunit );
|
||||
Bind( m_reflectiontexture ); // TBD, TODO: move to reflection unit setup
|
||||
|
||||
Active_Texture( m_helpertextureunit );
|
||||
|
||||
if( ( true == Reflections )
|
||||
|| ( ( true == Global::RenderShadows ) && ( true == Shadows ) ) ) {
|
||||
m_textures.bind( textureunit::helper, m_reflectiontexture );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
/*
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||
glEnable( GL_TEXTURE_GEN_S );
|
||||
glEnable( GL_TEXTURE_GEN_T );
|
||||
*/
|
||||
}
|
||||
else {
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
||||
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
|
||||
::glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, glm::value_ptr( m_shadowcolor ) ); // TODO: dynamically calculated shadow colour, based on sun height
|
||||
|
||||
@@ -698,14 +690,24 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS );
|
||||
}
|
||||
else {
|
||||
::glActiveTexture( m_helpertextureunit );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
/*
|
||||
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE ); // pass the previous stage colour down the chain
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
|
||||
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE ); // pass the previous stage alpha down the chain
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS );
|
||||
}
|
||||
|
||||
if( true == Reflections ) {
|
||||
::glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||
::glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
|
||||
::glEnable( GL_TEXTURE_GEN_S );
|
||||
::glEnable( GL_TEXTURE_GEN_T );
|
||||
}
|
||||
else {
|
||||
::glDisable( GL_TEXTURE_GEN_S );
|
||||
::glDisable( GL_TEXTURE_GEN_T );
|
||||
::glDisable( GL_TEXTURE_GEN_R );
|
||||
::glDisable( GL_TEXTURE_GEN_Q );
|
||||
*/
|
||||
}
|
||||
}
|
||||
// shadow texture unit.
|
||||
@@ -715,7 +717,8 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
||||
&& ( true == Shadows )
|
||||
&& ( m_shadowcolor != colors::white ) ) {
|
||||
|
||||
::glActiveTexture( m_shadowtextureunit );
|
||||
Active_Texture( m_shadowtextureunit );
|
||||
// NOTE: shadowmap isn't part of regular texture system, so we use direct bind call here
|
||||
::glBindTexture( GL_TEXTURE_2D, m_shadowtexture );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
// s
|
||||
@@ -745,7 +748,7 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
||||
}
|
||||
else {
|
||||
// turn off shadow map tests
|
||||
::glActiveTexture( m_shadowtextureunit );
|
||||
Active_Texture( m_shadowtextureunit );
|
||||
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
::glDisable( GL_TEXTURE_GEN_S );
|
||||
@@ -754,9 +757,35 @@ opengl_renderer::setup_units( bool const Diffuse, bool const Shadows, bool const
|
||||
::glDisable( GL_TEXTURE_GEN_Q );
|
||||
}
|
||||
}
|
||||
// reflections/normals texture unit
|
||||
// NOTE: comes after diffuse stage in the operation chain
|
||||
if( m_normaltextureunit >= 0 ) {
|
||||
|
||||
Active_Texture( m_normaltextureunit );
|
||||
|
||||
if( true == Reflections ) {
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ); // blend between object colour and env.reflection
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0 );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE ); // alpha channel of the normal map controls reflection strength
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA );
|
||||
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE ); // pass the previous stage alpha down the chain
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS );
|
||||
}
|
||||
else {
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
}
|
||||
// diffuse texture unit.
|
||||
// NOTE: diffuse texture mapping is never fully disabled, alpha channel information is always included
|
||||
::glActiveTexture( m_diffusetextureunit );
|
||||
Active_Texture( m_diffusetextureunit );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
if( true == Diffuse ) {
|
||||
// default behaviour, modulate with previous stage
|
||||
::glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
|
||||
@@ -788,14 +817,15 @@ void
|
||||
opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool const Reflections ) {
|
||||
// helper texture unit.
|
||||
if( m_helpertextureunit >= 0 ) {
|
||||
if( ( true == Global::RenderShadows )
|
||||
&& ( true == Shadows )
|
||||
&& ( m_shadowcolor != colors::white ) ) {
|
||||
::glActiveTexture( m_helpertextureunit );
|
||||
if( ( true == Reflections )
|
||||
|| ( ( true == Global::RenderShadows )
|
||||
&& ( true == Shadows )
|
||||
&& ( m_shadowcolor != colors::white ) ) ) {
|
||||
Active_Texture( m_helpertextureunit );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
else {
|
||||
::glActiveTexture( m_helpertextureunit );
|
||||
Active_Texture( m_helpertextureunit );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
}
|
||||
@@ -803,25 +833,35 @@ opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool cons
|
||||
if( m_shadowtextureunit >= 0 ) {
|
||||
if( ( true == Global::RenderShadows ) && ( true == Shadows ) ) {
|
||||
|
||||
::glActiveTexture( m_shadowtextureunit );
|
||||
Active_Texture( m_shadowtextureunit );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
else {
|
||||
|
||||
::glActiveTexture( m_shadowtextureunit );
|
||||
Active_Texture( m_shadowtextureunit );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
}
|
||||
// normal/reflection texture unit
|
||||
if( true == Reflections ) {
|
||||
|
||||
Active_Texture( m_normaltextureunit );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
else {
|
||||
Active_Texture( m_normaltextureunit );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
// diffuse texture unit.
|
||||
// NOTE: toggle actually disables diffuse texture mapping, unlike setup counterpart
|
||||
if( true == Diffuse ) {
|
||||
|
||||
::glActiveTexture( m_diffusetextureunit );
|
||||
Active_Texture( m_diffusetextureunit );
|
||||
::glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
else {
|
||||
|
||||
::glActiveTexture( m_diffusetextureunit );
|
||||
Active_Texture( m_diffusetextureunit );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
}
|
||||
@@ -829,10 +869,9 @@ opengl_renderer::switch_units( bool const Diffuse, bool const Shadows, bool cons
|
||||
void
|
||||
opengl_renderer::setup_shadow_color( glm::vec4 const &Shadowcolor ) {
|
||||
|
||||
::glActiveTexture( m_helpertextureunit );
|
||||
Active_Texture( m_helpertextureunit );
|
||||
::glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, glm::value_ptr( Shadowcolor ) ); // in-shadow colour multiplier
|
||||
::glActiveTexture( m_diffusetextureunit );
|
||||
|
||||
Active_Texture( m_diffusetextureunit );
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -854,7 +893,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Bind( NULL );
|
||||
Bind_Material( NULL );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_DEPTH_TEST );
|
||||
::glDepthMask( GL_FALSE );
|
||||
@@ -903,7 +942,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
auto const &modelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||
// sun
|
||||
{
|
||||
Bind( m_suntexture );
|
||||
Bind_Texture( m_suntexture );
|
||||
::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 );
|
||||
@@ -924,7 +963,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
}
|
||||
// moon
|
||||
{
|
||||
Bind( m_moontexture );
|
||||
Bind_Texture( m_moontexture );
|
||||
glm::vec3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||
|
||||
@@ -1032,21 +1071,48 @@ opengl_renderer::Vertices( geometry_handle const &Geometry ) const {
|
||||
return m_geometry.vertices( Geometry );
|
||||
}
|
||||
|
||||
// texture methods
|
||||
texture_handle
|
||||
opengl_renderer::Fetch_Texture( std::string const &Filename, std::string const &Dir, int const Filter, bool const Loadnow ) {
|
||||
// material methods
|
||||
material_handle
|
||||
opengl_renderer::Fetch_Material( std::string const &Filename, bool const Loadnow ) {
|
||||
|
||||
return m_textures.create( Filename, Dir, Filter, Loadnow );
|
||||
return m_materials.create( Filename, Loadnow );
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Bind( texture_handle const Texture ) {
|
||||
// temporary until we separate the renderer
|
||||
m_textures.bind( Texture );
|
||||
opengl_renderer::Bind_Material( material_handle const Material ) {
|
||||
|
||||
auto const &material = m_materials.material( Material );
|
||||
m_textures.bind( textureunit::normals, material.texture2 );
|
||||
m_textures.bind( textureunit::diffuse, material.texture1 );
|
||||
}
|
||||
|
||||
opengl_material const &
|
||||
opengl_renderer::Material( material_handle const Material ) const {
|
||||
|
||||
return m_materials.material( Material );
|
||||
}
|
||||
|
||||
// texture methods
|
||||
void
|
||||
opengl_renderer::Active_Texture( GLint const Textureunit ) {
|
||||
|
||||
return m_textures.unit( Textureunit );
|
||||
}
|
||||
|
||||
texture_handle
|
||||
opengl_renderer::Fetch_Texture( std::string const &Filename, bool const Loadnow ) {
|
||||
|
||||
return m_textures.create( Filename, Loadnow );
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Bind_Texture( texture_handle const Texture ) {
|
||||
|
||||
m_textures.bind( textureunit::diffuse, Texture );
|
||||
}
|
||||
|
||||
opengl_texture const &
|
||||
opengl_renderer::Texture( texture_handle const Texture ) {
|
||||
opengl_renderer::Texture( texture_handle const Texture ) const {
|
||||
|
||||
return m_textures.texture( Texture );
|
||||
}
|
||||
@@ -1431,7 +1497,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
::glLineWidth( static_cast<float>( linewidth ) );
|
||||
}
|
||||
|
||||
GfxRenderer.Bind( NULL );
|
||||
GfxRenderer.Bind_Material( NULL );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - m_renderpass.camera.position();
|
||||
@@ -1464,7 +1530,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
Bind( Node->TextureID );
|
||||
Bind_Material( Node->m_material );
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color: {
|
||||
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
||||
@@ -1784,12 +1850,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
#endif
|
||||
// material configuration:
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
if( Submodel->m_material < 0 ) { // zmienialne skóry
|
||||
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// ...colors...
|
||||
::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub
|
||||
@@ -1839,12 +1905,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// scenery picking and shadow both use enforced colour and no frills
|
||||
// material configuration:
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
if( Submodel->m_material < 0 ) { // zmienialne skóry
|
||||
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// main draw call
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
@@ -1857,12 +1923,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
m_pickcontrolsitems.emplace_back( Submodel );
|
||||
::glColor3fv( glm::value_ptr( pick_color( m_pickcontrolsitems.size() ) ) );
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
if( Submodel->m_material < 0 ) { // zmienialne skóry
|
||||
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// main draw call
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
@@ -1902,7 +1968,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// material configuration:
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
|
||||
|
||||
Bind( NULL );
|
||||
Bind_Material( NULL );
|
||||
::glPointSize( std::max( 3.f, 5.f * distancefactor * anglefactor ) );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], lightlevel * anglefactor );
|
||||
::glDisable( GL_LIGHTING );
|
||||
@@ -1941,7 +2007,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// material configuration:
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
|
||||
|
||||
Bind( NULL );
|
||||
Bind_Material( NULL );
|
||||
::glDisable( GL_LIGHTING );
|
||||
|
||||
// main draw call
|
||||
@@ -1976,20 +2042,20 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
void
|
||||
opengl_renderer::Render( TTrack *Track ) {
|
||||
|
||||
if( ( Track->TextureID1 == 0 )
|
||||
&& ( Track->TextureID2 == 0 ) ) {
|
||||
if( ( Track->m_material1 == 0 )
|
||||
&& ( Track->m_material2 == 0 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color: {
|
||||
Track->EnvironmentSet();
|
||||
if( Track->TextureID1 != 0 ) {
|
||||
Bind( Track->TextureID1 );
|
||||
if( Track->m_material1 != 0 ) {
|
||||
Bind_Material( Track->m_material1 );
|
||||
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
|
||||
}
|
||||
if( Track->TextureID2 != 0 ) {
|
||||
Bind( Track->TextureID2 );
|
||||
if( Track->m_material2 != 0 ) {
|
||||
Bind_Material( Track->m_material2 );
|
||||
m_geometry.draw( std::begin( Track->Geometry2 ), std::end( Track->Geometry2 ) );
|
||||
}
|
||||
Track->EnvironmentReset();
|
||||
@@ -1997,12 +2063,12 @@ opengl_renderer::Render( TTrack *Track ) {
|
||||
}
|
||||
case rendermode::pickscenery:
|
||||
case rendermode::shadows: {
|
||||
if( Track->TextureID1 != 0 ) {
|
||||
Bind( Track->TextureID1 );
|
||||
if( Track->m_material1 != 0 ) {
|
||||
Bind_Material( Track->m_material1 );
|
||||
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
|
||||
}
|
||||
if( Track->TextureID2 != 0 ) {
|
||||
Bind( Track->TextureID2 );
|
||||
if( Track->m_material2 != 0 ) {
|
||||
Bind_Material( Track->m_material2 );
|
||||
m_geometry.draw( std::begin( Track->Geometry2 ), std::end( Track->Geometry2 ) );
|
||||
}
|
||||
break;
|
||||
@@ -2141,7 +2207,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
auto const color { Node->hvTraction->wire_color() };
|
||||
::glColor4f( color.r, color.g, color.b, linealpha );
|
||||
|
||||
Bind( NULL );
|
||||
Bind_Material( NULL );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - m_renderpass.camera.position();
|
||||
@@ -2217,7 +2283,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
::glLineWidth( static_cast<float>(linewidth) );
|
||||
}
|
||||
|
||||
GfxRenderer.Bind( NULL );
|
||||
GfxRenderer.Bind_Material( NULL );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - m_renderpass.camera.position();
|
||||
@@ -2242,7 +2308,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
// setup
|
||||
::glColor3fv( glm::value_ptr( Node->Diffuse ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
Bind_Material( Node->m_material );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - m_renderpass.camera.position();
|
||||
@@ -2423,12 +2489,12 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
}
|
||||
#endif
|
||||
// textures...
|
||||
if( Submodel->TextureID < 0 ) { // zmienialne skóry
|
||||
Bind( Submodel->ReplacableSkinId[ -Submodel->TextureID ] );
|
||||
if( Submodel->m_material < 0 ) { // zmienialne skóry
|
||||
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ] );
|
||||
}
|
||||
else {
|
||||
// również 0
|
||||
Bind( Submodel->TextureID );
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// ...colors...
|
||||
::glColor3fv( glm::value_ptr(Submodel->f4Diffuse) ); // McZapkie-240702: zamiast ub
|
||||
@@ -2495,7 +2561,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
// setup
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT );
|
||||
|
||||
Bind( m_glaretexture );
|
||||
Bind_Texture( m_glaretexture );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
@@ -2585,9 +2651,8 @@ opengl_renderer::Update_Pick_Control() {
|
||||
if( true == m_framebuffersupport ) {
|
||||
// ::glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
|
||||
pickbufferpos = glm::ivec2{
|
||||
mousepos.x * EU07_PICKBUFFERSIZE / Global::iWindowWidth,
|
||||
mousepos.y * EU07_PICKBUFFERSIZE / Global::iWindowHeight
|
||||
};
|
||||
mousepos.x * EU07_PICKBUFFERSIZE / std::max( 1, Global::iWindowWidth ),
|
||||
mousepos.y * EU07_PICKBUFFERSIZE / std::max( 1, Global::iWindowHeight ) };
|
||||
}
|
||||
else {
|
||||
// ::glReadBuffer( GL_BACK );
|
||||
|
||||
42
renderer.h
42
renderer.h
@@ -11,7 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "openglgeometrybank.h"
|
||||
#include "texture.h"
|
||||
#include "material.h"
|
||||
#include "lightarray.h"
|
||||
#include "dumb3d.h"
|
||||
#include "frustum.h"
|
||||
@@ -73,13 +73,6 @@ struct opengl_technique {
|
||||
|
||||
};
|
||||
|
||||
// a collection of parameters for the rendering setup.
|
||||
// for modern opengl this translates to set of attributes for the active shaders,
|
||||
// for legacy opengl this is basically just texture(s) assigned to geometry
|
||||
struct opengl_material {
|
||||
|
||||
};
|
||||
|
||||
// simple camera object. paired with 'virtual camera' in the scene
|
||||
class opengl_camera {
|
||||
|
||||
@@ -175,13 +168,22 @@ public:
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
vertex_array const &
|
||||
Vertices( geometry_handle const &Geometry ) const;
|
||||
// texture methods
|
||||
texture_handle
|
||||
Fetch_Texture( std::string const &Filename, std::string const &Dir = szTexturePath, int const Filter = -1, bool const Loadnow = true );
|
||||
// material methods
|
||||
material_handle
|
||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true );
|
||||
void
|
||||
Bind( texture_handle const Texture );
|
||||
Bind_Material( material_handle const Material );
|
||||
opengl_material const &
|
||||
Material( material_handle const Material ) const;
|
||||
// texture methods
|
||||
void
|
||||
Active_Texture( GLint const Textureunit );
|
||||
texture_handle
|
||||
Fetch_Texture( std::string const &Filename, bool const Loadnow = true );
|
||||
void
|
||||
Bind_Texture( texture_handle const Texture );
|
||||
opengl_texture const &
|
||||
Texture( texture_handle const Texture );
|
||||
Texture( texture_handle const Texture ) const;
|
||||
// light methods
|
||||
void
|
||||
Disable_Lights();
|
||||
@@ -215,6 +217,13 @@ private:
|
||||
pickscenery
|
||||
};
|
||||
|
||||
enum textureunit {
|
||||
helper = 0,
|
||||
shadows,
|
||||
normals,
|
||||
diffuse
|
||||
};
|
||||
|
||||
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
||||
|
||||
struct renderpass_config {
|
||||
@@ -292,6 +301,7 @@ private:
|
||||
// members
|
||||
GLFWwindow *m_window { nullptr };
|
||||
geometrybank_manager m_geometry;
|
||||
material_manager m_materials;
|
||||
texture_manager m_textures;
|
||||
opengllight_array m_lights;
|
||||
|
||||
@@ -316,9 +326,10 @@ private:
|
||||
#endif
|
||||
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
||||
|
||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||
int m_helpertextureunit { GL_TEXTURE0 };
|
||||
int m_diffusetextureunit { GL_TEXTURE2 };
|
||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||
int m_normaltextureunit { GL_TEXTURE2 };
|
||||
int m_diffusetextureunit{ GL_TEXTURE3 };
|
||||
|
||||
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
||||
std::chrono::steady_clock::time_point m_drawstart; // cached start time of previous frame
|
||||
@@ -327,6 +338,7 @@ private:
|
||||
float m_drawtimeshadowpass { 0.f };
|
||||
double m_updateaccumulator { 0.0 };
|
||||
std::string m_debuginfo;
|
||||
std::string m_pickdebuginfo;
|
||||
|
||||
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
glm::vec4 m_shadowcolor { 0.5f, 0.5f, 0.5f, 1.f };
|
||||
|
||||
@@ -216,7 +216,7 @@ ui_layer::render_background() {
|
||||
if( m_background == 0 ) return;
|
||||
// NOTE: we limit/expect the background to come with 4:3 ratio.
|
||||
// TODO, TBD: if we expose texture width or ratio from texture object, this limitation could be lifted
|
||||
GfxRenderer.Bind( m_background );
|
||||
GfxRenderer.Bind_Texture( m_background );
|
||||
auto const height { 768.0f };
|
||||
auto const &texture = GfxRenderer.Texture( m_background );
|
||||
float const width = (
|
||||
@@ -239,7 +239,7 @@ ui_layer::render_texture() {
|
||||
::glColor4f( 1.f, 1.f, 1.f, 1.f );
|
||||
::glDisable( GL_BLEND );
|
||||
|
||||
GfxRenderer.Bind( NULL );
|
||||
GfxRenderer.Bind_Texture( NULL );
|
||||
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
||||
|
||||
auto const size = 512.f;
|
||||
@@ -254,6 +254,8 @@ ui_layer::render_texture() {
|
||||
|
||||
glEnd();
|
||||
|
||||
::glBindTexture( GL_TEXTURE_2D, NULL );
|
||||
|
||||
::glEnable( GL_BLEND );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user