Delphi2Cpp 라는 프로그램을 이용하면 델파이소스를 CPP로 바꿀 수 있답니다.
완벽하게는 되지 않지만 참고해서 쓰면 될것 같네요
#include <vcl.h>
#pragma hdrstop
#include "Unit3DS.h"
#include <sysutils.hpp>
#include "GL.h"
#include "Textures.h"
#include <math.hpp>
#include <System.hpp>
// Convert TColor to RGBA
typedef unsigned char unsignedchar;
typedef unsigned int unsignedint;
TVector4f __fastcall ColorToVector4f( const TColor aColor, float Alpha )
{
TVector4f result;
result.Red = double( ( aColor & 0xFF ) ) / 255;
result.Green = double( ( ( aColor >> 8 ) & 0xFF ) ) / 255;
result.Blue = double( ( ( aColor >> 16 ) & 0xFF ) ) / 255;
result.Alpha = Alpha;
return result;
}
// Convert RGBA to TColor
TColor __fastcall Vector4fToColor( const TVector4f aVector )
{
TColor result;
TByteColor C;
C = Color4fToByte( aVector );
result = Rgb( C.Red, C.Green, C.Blue );
return result;
}
TColor __fastcall RGBToColor( const unsignedchar R, const unsignedchar G, const unsignedchar B )
{
TColor result;
result = R;
result = result | ( G << 8 );
result = result | ( B << 16 );
return result;
}
/* TChunk */
__fastcall TChunk::TChunk( T3DModel* Model )
: FId(0),
FLength(0),
FBytesReaded(0),
FModel(Model),
FFileHandle(FModel->FFileHandle)
{
// inherited::Create();
}
__fastcall TChunk::~TChunk( )
{
// todo check: inherited::Destroy();
}
int __fastcall TChunk::GetBytesRemaining( )
{
int result = 0;
result = FLength - BytesReaded;
return result;
}
bool __fastcall TChunk::WaitForLength( )
{
bool result = false;
result = FBytesReaded < FLength;
return result;
}
void __fastcall TChunk::NexFilePosition( )
{
int NewPosition = 0;
NewPosition = BytesRemaining;
FileSeek( FFileHandle, NewPosition, 1 );
UpdateByteCounter( NewPosition );
}
void __fastcall TChunk::ProcessNextChunk( TChunk* PreviousChunk )
{
TChunk* NewChunk = NULL,* TempChunk = NULL;
unsigned int FileVersion = 0, MeshVersion = 0;
NewChunk = new TChunk( PreviousChunk->FModel );
while ( PreviousChunk->WaitForLength() )
{
NewChunk->read();
switch ( NewChunk->Id )
{
case M3D_VERSION:
{
NewChunk->ReadRemainingBuffer( &FileVersion );
if ( FileVersion > SUPPORTEDVERSION )
MessageBox( 0, "Unsupported file version.", "Warning", MB_OK );
}
break;
case MDATA:
{
TempChunk = new TChunk( PreviousChunk->FModel );
TempChunk->read();
TempChunk->ReadRemainingBuffer( &MeshVersion );
NewChunk->UpdateByteCounter( TempChunk->BytesReaded );
delete TempChunk;
ProcessNextChunk( NewChunk );
}
break;
case MAT_ENTRY:
/*# with FModel.AddMaterial do */
{
TMaterial* with0 = FModel->AddMaterial();
with0->ProcessNextMaterialChunk( NewChunk );
}
break;
// This holds the name of the object being read
case NAMED_OBJECT:
/*# with FModel.AddObject do */
{
T3DObject* with1 = FModel->AddObject();
{
with1->ObjectName = NewChunk->ReadObjectString();
with1->ProcessNextObjectChunk( NewChunk );
}
}
break;
case KFDATA:
NewChunk->NexFilePosition();
break;
default:
NewChunk->NexFilePosition();
}
PreviousChunk->UpdateByteCounter( NewChunk->BytesReaded );
}
delete NewChunk;
}
int __fastcall TChunk::read( )
{
int result = 0;
FBytesReaded = FileRead( FFileHandle, FId, 2 );
FBytesReaded = FBytesReaded + FileRead( FFileHandle, FLength, 4 );
result = FBytesReaded;
return result;
}
int __fastcall TChunk::ReadBuffer( void* Buffer, int Count )
{
int result = 0;
result = FileRead( FFileHandle, Buffer, Count );
FBytesReaded = FBytesReaded + result;
return result;
}
String __fastcall TChunk::ReadObjectString( )
{
String result;
int I = 0;
Char C = '\0';
SmallString<255> S;
I = 0;
C = '\xff'; // Initialization for "while"
while ( C != '\x00' )
{
FileRead( FFileHandle, C, 1 );
S[I + 1] = C;
I++;
}
result.SetLength( I - 1 );
Move( S[1], result[1], I - 1 );
UpdateByteCounter( I );
return result;
}
int __fastcall TChunk::ReadRemainingBuffer( void* Buffer )
{
int result = 0;
int I = 0;
I = BytesRemaining;
result = FileRead( FFileHandle, Buffer, I );
FBytesReaded = FBytesReaded + result;
return result;
}
void __fastcall TChunk::UpdateByteCounter( int Value )
{
FBytesReaded = FBytesReaded + Value;
}
// ************************** END TCHUNK **************************************
// ************************** TMATERIAL **************************************
/* TMaterial */
__fastcall TMaterial::TMaterial( )
: FHasTexture(false),
FGenTexture(0),
FDisableTexture(false),
FEnviromentMap(false),
FSphericalMap(false),
FAmbient(new TMaterialProperties( GL_FRONT, GL_AMBIENT )),
FEmission(new TMaterialProperties( GL_FRONT, GL_EMISSION )),
FSpecular(new TMaterialProperties( GL_FRONT, GL_SPECULAR )),
FDiffuse(new TMaterialProperties( GL_FRONT, GL_DIFFUSE )),
Shininess(0.0),
Transparency(0.0)
{
// inherited::Create();
}
__fastcall TMaterial::~TMaterial( )
{
delete FEmission;
delete FSpecular;
delete FDiffuse;
delete FAmbient;
// todo check: inherited::Destroy();
}
void __fastcall TMaterial::ReadColorChunk( TChunk* PreviousChunk, void* Buffer )
{
TChunk* TempChunk = NULL;
TempChunk = new TChunk( PreviousChunk->FModel );
TempChunk->read();
TempChunk->ReadRemainingBuffer( Buffer );
PreviousChunk->UpdateByteCounter( TempChunk->BytesReaded );
delete TempChunk;
}
void __fastcall TMaterial::ProcessNextMaterialChunk( TChunk* PreviousChunk )
{
TChunk* NewChunk = NULL;
int I = 0;
TByteColor Buffer;
WORD __Shininess = 0, __Transparency = 0;
NewChunk = new TChunk( PreviousChunk->FModel );
while ( PreviousChunk->WaitForLength() )
{
NewChunk->read();
switch ( NewChunk->Id )
{
case MAT_NAME:
{
I = NewChunk->BytesRemaining;
FMaterialName.SetLength( I );
NewChunk->ReadBuffer( &FMaterialName[1], I );
FMaterialName.SetLength( FMaterialName.Length( ) - 1 );
}
break;
case MAT_AMBIENT:
{
ReadColorChunk( NewChunk, &Buffer );
Ambient->Vector = ByteColorTo4f( Buffer );
}
break;
case MAT_DIFFUSE:
{
ReadColorChunk( NewChunk, &Buffer );
Diffuse->Vector = ByteColorTo4f( Buffer );
}
break;
case MAT_SPECULAR:
{
ReadColorChunk( NewChunk, &Buffer );
Specular->Vector = ByteColorTo4f( Buffer );
}
break;
case MAT_SHININESS:
{
ReadColorChunk( NewChunk, &__Shininess );
Shininess = 128 - ( __Shininess * 1.28 );
}
break;
case MAT_TRANSPARENCY:
{
ReadColorChunk( NewChunk, &__Transparency );
Transparency = 1 - ( double( __Transparency ) / 100 );
}
break;
case MAT_TEXMAP:
ProcessNextMaterialChunk( NewChunk );
break;
case MAT_MAPNAME:
{
I = NewChunk->BytesRemaining;
FMaterialFile.SetLength( I );
NewChunk->ReadBuffer( &FMaterialFile[1], I );
FMaterialFile.SetLength( FMaterialFile.Length( ) - 1 );
FHasTexture = LoadTexture( FMaterialFile, FGenTexture, false );
}
break;
default:
NewChunk->NexFilePosition();
}
PreviousChunk->UpdateByteCounter( NewChunk->BytesReaded );
}
delete NewChunk;
}
void __fastcall TMaterial::CopyFrom( TMaterial* Source )
{
FMaterialName = Source->MaterialName;
FMaterialFile = Source->MaterialFile;
Ambient->Vector = Source->Ambient->Vector;
Diffuse->Vector = Source->Diffuse->Vector;
Specular->Vector = Source->Specular->Vector;
Shininess = Source->Shininess;
FHasTexture = Source->HasTexture;
FGenTexture = Source->GenTexture;
}
void __fastcall TMaterial::SetMaterialColor( const TMaterialType MaterialType, const float R, const float G, const float B, const float Alpha )
{
switch ( MaterialType )
{
case mtAmbient:
Ambient->SetRGBA( R, G, B, Alpha );
break;
case mtDiffuse:
Diffuse->SetRGBA( R, G, B, Alpha );
break;
case mtSpecular:
Specular->SetRGBA( R, G, B, Alpha );
break;
}
}
void __fastcall TMaterial::EnviromentApply( )
{
if ( FEnviromentMap )
{
glTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
glEnable( GL_TEXTURE_GEN_T );
}
else
glDisable( GL_TEXTURE_GEN_T );
}
void __fastcall TMaterial::SphericalApply( )
{
if ( FSphericalMap )
{
glTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
glEnable( GL_TEXTURE_GEN_S );
}
else
glDisable( GL_TEXTURE_GEN_S );
}
bool __fastcall TMaterial::TextureActive( )
{
bool result = false;
result = FHasTexture && ( ! FDisableTexture );
return result;
}
void __fastcall TMaterial::SetMaterial( )
{
Ambient->Apply();
Diffuse->Apply();
Specular->Apply();
Emission->Apply();
glMaterialfv( GL_FRONT, GL_SHININESS, &Shininess );
EnviromentApply();
SphericalApply();
if ( TextureActive() )
{
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, FGenTexture );
}
else
glDisable( GL_TEXTURE_2D );
}
// ************************** END TMATERIAL ***********************************
// ************************** T3DOBJECT **************************************
__fastcall T3DObject::T3DObject( )
: FVisible(true),
FMaterial(new TMaterial),
FVertexCount(0),
FTexVertexCount(0),
FFaceCount(0),
FNormalCount(0),
FObjectIndex(0),
FSelected(false),
FRMode(0),
FRenderMode(rmTriangles),
FTransformList(new TTransformList),
Verts(DynamicArray<TVector3D>()),
Normals(DynamicArray<TVector3D>()),
TexVerts(DynamicArray<TVector2D>()),
Faces(DynamicArray<TFace>())
{
// inherited::Create();
RenderMode = rmTriangles;
}
__fastcall T3DObject::~T3DObject( )
{
Finalize( Verts );
Finalize( Normals );
Finalize( TexVerts );
Finalize( Faces );
glDeleteTextures( 1, FMaterial->FGenTexture );
delete FMaterial;
FTransformList->Free;
// todo check: inherited::Destroy();
}
void __fastcall T3DObject::ProcessNextObjectChunk( TChunk* PreviousChunk )
{
TChunk* NewChunk = NULL;
NewChunk = new TChunk( PreviousChunk->FModel );
while ( PreviousChunk->WaitForLength() )
{
NewChunk->read();
switch ( NewChunk->Id )
{
case N_TRI_OBJECT:
ProcessNextObjectChunk( NewChunk );
break;
case POINT_ARRAY:
ReadVertices( NewChunk );
break;
case FACE_ARRAY:
ReadVertexIndices( NewChunk );
break;
case MSH_MAT_GROUP:
ReadObjectMaterial( NewChunk );
break;
case TEX_VERTS:
ReadUVCoordinates( NewChunk );
break;
default:
NewChunk->NexFilePosition();
}
PreviousChunk->UpdateByteCounter( NewChunk->BytesReaded );
}
delete NewChunk;
}
void __fastcall T3DObject::ReadObjectMaterial( TChunk* PreviousChunk )
{
int I = 0;
TMaterial* SourceMaterial = NULL;
FMaterial->FMaterialName = PreviousChunk->ReadObjectString();
for ( int stop = PreviousChunk->FModel->MaterialCount - 1, I = 0; I <= stop; I++)
{
SourceMaterial = PreviousChunk->FModel->FMaterials[I];
if ( CompareStr( FMaterial->MaterialName, SourceMaterial->MaterialName ) == 0 )
{
FMaterial->CopyFrom( SourceMaterial );
Break;
}
}
PreviousChunk->NexFilePosition();
}
void __fastcall T3DObject::ReadUVCoordinates( TChunk* PreviousChunk )
{
PreviousChunk->ReadBuffer( &FTexVertexCount, 2 );
TexVerts.Length = FTexVertexCount;
PreviousChunk->ReadRemainingBuffer( &TexVerts[0] );
}
void __fastcall T3DObject::ReadVertexIndices( TChunk* PreviousChunk )
{
int I = 0, J = 0;
WORD Index = 0;
PreviousChunk->ReadBuffer( &FFaceCount, 2 );
Faces.Length = FFaceCount;
for ( int stop = FFaceCount - 1, I = 0; I <= stop; I++)
for ( int stop = 3, J = 0; J <= stop; J++)
{
PreviousChunk->ReadBuffer( &Index, sizeof( Index ) );
if ( J < 3 )
Faces[I].VertIndex[J] = Index;
}
}
void __fastcall T3DObject::ReadVertices( TChunk* PreviousChunk )
{
int I = 0;
float TempY = 0.0;
bool FirstVertice = false;
FirstVertice = false;
PreviousChunk->ReadBuffer( &FVertexCount, 2 );
Verts.Length = FVertexCount;
PreviousChunk->ReadRemainingBuffer( &Verts[0] );
for ( int stop = FVertexCount - 1, I = 0; I <= stop; I++)
{
TempY = Verts[I].Y;
Verts[I].Y = Verts[I].Z;
Verts[I].Z = - TempY;
if ( ! FirstVertice )
{
FMaxVector = Verts[I];
FMinVector = FMaxVector;
FirstVertice = true;
}
FMaxVector.X = Max( FMaxVector.X, Verts[I].X );
FMaxVector.Y = Max( FMaxVector.Y, Verts[I].Y );
FMaxVector.Z = Max( FMaxVector.Z, Verts[I].Z );
FMinVector.X = Min( FMinVector.X, Verts[I].X );
FMinVector.Y = Min( FMinVector.Y, Verts[I].Y );
FMinVector.Z = Min( FMinVector.Z, Verts[I].Z );
}
FMidVector = VectorSub( FMaxVector, FMinVector );
//VectorAdd(FMaxVector, 0.0);
//VectorAdd(FMinVector, -0.0);
}
void __fastcall T3DObject::AdjustNormals( )
{
TVector3D V1, V2, Normal;
DynamicArray< TVector3D > TempNormals;
TVector3D VPoly[ 3/*# range 0..2*/ ];
int I = 0, Shared = 0, J = 0;
TVector3D VSum, VZero;
TempNormals.Length = FaceCount;
Normals.Length = VertexCount;
for ( int stop = FaceCount - 1, I = 0; I <= stop; I++)
{
VPoly[0] = Verts[Faces[I].VertIndex[0]];
VPoly[1] = Verts[Faces[I].VertIndex[1]];
VPoly[2] = Verts[Faces[I].VertIndex[2]];
V1 = VectorSub( VPoly[0], VPoly[2] );
V2 = VectorSub( VPoly[2], VPoly[1] );
Normal = VectorCrossProduct( V1, V2 );
TempNormals[I] = Normal;
// VectorNormalize(Normal);
}
VectorClear( VSum );
VectorClear( VZero );
Shared = 0;
for ( int stop = VertexCount - 1, I = 0; I <= stop; I++)
{
for ( int stop = FaceCount - 1, J = 0; J <= stop; J++)
if ( ( Faces[J].VertIndex[0] == I ) || ( Faces[J].VertIndex[1] == I ) || ( Faces[J].VertIndex[2] == I ) )
{
VSum = VectorAdd( VSum, TempNormals[J] );
Shared++;
}
Normals[I] = VectorDivide( VSum, - Shared );
VectorNormalize( Normals[I] );
VSum = VZero;
Shared = 0;
}
Finalize( TempNormals );
}
void __fastcall T3DObject::Draw( )
{
int F = 0, iVertex = 0, PointIndex = 0;
FTransformList->Push();
if ( FSelected )
DrawBox();
Material->SetMaterial();
glPushName( FObjectIndex );
glBegin( FRMode );
for ( int stop = FaceCount - 1, F = 0; F <= stop; F++)
for ( int stop = 2, iVertex = 0; iVertex <= stop; iVertex++)
{
PointIndex = Faces[F].VertIndex[iVertex];
glNormal3f( Normals[PointIndex].X, Normals[PointIndex].Y, Normals[PointIndex].Z );
if ( Material->HasTexture )
glTexCoord2f( TexVerts[PointIndex].X, TexVerts[PointIndex].Y );
else
glColor3f( Material->Diffuse->Vector.Red, Material->Diffuse->Vector.Green, Material->Diffuse->Vector.Blue );
glVertex3f( Verts[PointIndex].X, Verts[PointIndex].Y, Verts[PointIndex].Z );
}
glEnd;
glPopName;
FTransformList->Pop();
}
void __fastcall T3DObject::DrawBox( )
//var OldLineWidth:Single;
{
//glGetFloatv(GL_LINE_WIDTH, @OldLineWidth);
glDisable( GL_TEXTURE_2D );
glDisable( GL_LIGHTING );
glColor3ub( 0, 255, 0 );
//glLineWidth(1);
glBegin( GL_LINE_STRIP );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z );
glEnd;
glBegin( GL_LINE_STRIP );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y - FMidVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y - FMidVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMaxVector.Y, FMaxVector.Z );
glEnd;
glBegin( GL_LINE_STRIP );
glVertex3f( FMaxVector.X, FMinVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMinVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMinVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMinVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X, FMinVector.Y, FMaxVector.Z );
glEnd;
glBegin( GL_LINE_STRIP );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y - FMidVector.Y, FMaxVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y - FMidVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y, FMaxVector.Z - FMidVector.Z );
glVertex3f( FMaxVector.X - FMidVector.X, FMaxVector.Y, FMaxVector.Z );
glEnd;
glEnable( GL_LIGHTING );
//glLineWidth(OldLineWidth);
}
void __fastcall T3DObject::SetRenderMode( const TRenderMode Value )
{
FRenderMode = Value;
switch ( FRenderMode )
{
case rmTriangles:
FRMode = GL_TRIANGLES;
break;
case rmLines:
FRMode = GL_LINES;
break;
case rmPoints:
FRMode = GL_POINTS;
break;
}
}
// ************************** END T3DOBJECT **********************************
// ************************** T3DMODEL ***************************************
/* T3DModel */
__fastcall T3DModel::T3DModel( )
: FFileHandle(0),
FRootChunk(NULL)
{
// inherited::Create();
}
__fastcall T3DModel::~T3DModel( )
{
Clear();
// todo check: inherited::Destroy();
}
void __fastcall T3DModel::Clear( )
{
int I = 0;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
delete Objects[I];
Finalize( Objects );
Finalize( FMaterials );
}
TMaterial* __fastcall T3DModel::AddMaterial( )
{
TMaterial* result = NULL;
int C = 0;
result = new TMaterial;
C = MaterialCount;
FMaterials.Length = C + 1;
FMaterials[C] = result;
return result;
}
T3DObject* __fastcall T3DModel::AddObject( )
{
T3DObject* result = NULL;
int C = 0, I = 0;
result = new T3DObject;
C = ObjectCount;
I = C + 1;
result->FObjectIndex = I;
Objects.Length = I;
Objects[C] = result;
return result;
}
int __fastcall T3DModel::GetMaterialCount( )
{
int result = 0;
result = FMaterials.Length;
return result;
}
int __fastcall T3DModel::GetObjectCount( )
{
int result = 0;
result = Objects.Length;
return result;
}
bool __fastcall T3DModel::LoadFromFile( const String FileName )
{
bool result = false;
Clear();
FRootChunk = new TChunk( this );
FFileHandle = FileOpen( FileName, fmOpenRead );
if ( FFileHandle < 0 )
{
result = false;
CleanUp();
return result;
}
FRootChunk->FileHandle = FFileHandle;
FRootChunk->read();
if ( FRootChunk->Id != M3DMAGIC )
{
result = false;
CleanUp();
return result;
}
FRootChunk->ProcessNextChunk( FRootChunk );
ComputeNormals();
CleanUp();
result = true;
return result;
}
void __fastcall T3DModel::CleanUp( )
{
int I = 0;
for ( int stop = MaterialCount - 1, I = 0; I <= stop; I++)
delete FMaterials[I];
Finalize( FMaterials );
delete FRootChunk;
FRootChunk = NULL;
FileClose( FFileHandle );
}
void __fastcall T3DModel::ComputeNormals( )
{
int I = 0;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
Objects[I]->AdjustNormals();
}
void __fastcall T3DModel::Draw( )
{
int I = 0;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
if ( Objects[I]->Visible )
Objects[I]->Draw();
}
T3DObject* __fastcall T3DModel::FindObject( const String aName )
{
T3DObject* result = NULL;
int I = 0;
result = NULL;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
if ( SameText( aName, Objects[I]->ObjectName ) )
{
result = Objects[I];
Break;
}
return result;
}
T3DObject* __fastcall T3DModel::Select( const int Index )
{
T3DObject* result = NULL;
int I = 0;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
Objects[I]->Selected = false;
if ( Index > 0 )
{
result = Objects[Index - 1];
result->Selected = true;
}
else
result = NULL;
return result;
}
void __fastcall T3DModel::VisibleAll( )
{
int I = 0;
for ( int stop = ObjectCount - 1, I = 0; I <= stop; I++)
Objects[I]->Visible = true;
}
/* TTransformation */
__fastcall TTransformation::TTransformation( )
: FX(0.0),
FY(0.0),
FAngle(0.0),
FZ(0.0),
FTransformType(ttRotate),
FEnabled(true)
{
// inherited::Create();
}
void __fastcall TTransformation::Apply( )
{
if ( FEnabled )
switch ( FTransformType )
{
case ttRotate:
glRotatef( FAngle, FX, FY, FZ );
break;
case ttTranslate:
glTranslatef( FX, FY, FZ );
break;
case ttScale:
glScalef( FX, FY, FZ );
break;
}
}
void __fastcall TTransformation::Restore( )
{
if ( FEnabled )
glPopMatrix;
}
/* TTransformList */
__fastcall TTransformList::TTransformList( )
: FEnabled(true)
{
inherited::Create();
}
__fastcall TTransformList::~TTransformList( )
{
int I = 0;
for ( int stop = Count - 1, I = 0; I <= stop; I++)
delete ((TTransformation*) Items[I] );
Clear;
// todo check: inherited::Destroy();
}
TTransformation* __fastcall TTransformList::AddTransform( )
{
TTransformation* result = NULL;
result = new TTransformation;
Add( result );
return result;
}
TTransformation* __fastcall TTransformList::AddTransformEx( const TTransformType _TransformType, const float _Angle, const float _X, const float _Y, const float _Z )
{
TTransformation* result = NULL;
result = new TTransformation;
/*# with Result do */
{
result->TransformType = _TransformType;
result->Angle = _Angle;
result->X = _X;
result->Y = _Y;
result->Z = _Z;
}
Add( result );
return result;
}
void __fastcall TTransformList::Push( )
{
int I = 0;
if ( FEnabled )
for ( int stop = Count - 1, I = 0; I <= stop; I++)
{
if ( I == 0 )
glPushMatrix;
((TTransformation*) Items[I] )->Apply();
}
}
void __fastcall TTransformList::Pop( )
{
int I = 0;
if ( FEnabled )
for ( int stop = 0, I = Count - 1; I >= stop; I--)
{
((TTransformation*) Items[I] )->Restore();
if ( I == 0 )
glPopMatrix;
}
}
/* TMaterialProperties */
__fastcall TMaterialProperties::TMaterialProperties( unsignedint glDefFace, unsignedint glDefType )
: FglDefFace(glDefFace),
FglDefType(glDefType)
{
// inherited::Create();
ZeroMemory( &FVector, sizeof( TVector4f ) );
}
__fastcall TMaterialProperties::~TMaterialProperties( )
{
// todo check: inherited::Destroy();
}
void __fastcall TMaterialProperties::SetRGBA( const float R, const float G, const float B, const float Alpha )
{
FVector.Red = R;
FVector.Green = G;
FVector.Blue = B;
FVector.Alpha = Alpha;
}
String __fastcall TMaterialProperties::ToString( )
{
String result;
/*# with FVector do */
result = Format( "R%.1f - G%.1f - B%.1f - A%.1f", ARRAYOFCONST(( Red, Green, Blue, Alpha )) );
return result;
}
void __fastcall TMaterialProperties::Apply( )
{
glMaterialfv( FglDefFace, FglDefType, &FVector );
}
TColor __fastcall TMaterialProperties::GetColor( )
{
TColor result;
result = Vector4fToColor( FVector );
return result;
}
void __fastcall TMaterialProperties::SetColor( const TColor Value )
{
float CurAlpha = 0.0;
CurAlpha = FVector.Alpha;
FVector = ColorToVector4f( Value, CurAlpha );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*$mode delphi*/
#ifndef Unit3DSH
#define Unit3DSH
#include <System.hpp>
#include <windows.hpp>
#include <classes.hpp>
#include "Vectors.h"
// Root Node
class T3DModel;
class T3DObject;
class TChunk;
struct TFace;
class TMaterial;
class TMaterialProperties;
class TTransformList;
class TTransformation;
typedef unsigned int unsignedint;
const int M3DMAGIC = 0x4D4D;
// Primary Blocks
const int M3D_VERSION = 0x0002; // File version
const int MDATA = 0x3D3D; // All the Object information
const int KFDATA = 0xB000; // Animation frames
// Definitions for MDATA
const int MAT_ENTRY = 0xAFFF; // Material information
const int NAMED_OBJECT = 0x4000; // Object data (vertices, faces ...)
// Definitions for MAT_ENTRY
const int MAT_NAME = 0xA000; // Material name
const int MAT_AMBIENT = 0xA010; // Ambient
const int MAT_DIFFUSE = 0xA020; // Diffuse
const int MAT_SPECULAR = 0xA030; // Specular
const int MAT_SHININESS = 0xA040; // Shininess
const int MAT_TRANSPARENCY = 0xA050; // Transparency
const int MAT_TEXMAP = 0xA200; // Texture information
const int MAT_MAPNAME = 0xA300; // Texture file name
const int N_TRI_OBJECT = 0x4100; // For each object ...
// Definitions for N_TRI_OBJECT
const int POINT_ARRAY = 0x4110; // Vertices
const int FACE_ARRAY = 0x4120; // Faces
const int MSH_MAT_GROUP = 0x4130; // Material for the object
const int TEX_VERTS = 0x4140; // Texture coordinates
const int SUPPORTEDVERSION = 0x03; // Vseri? m?ima de 3DS soportada
// -----------------------------------------------------------------------------
typedef int/*# range -0x7FFFFFFF-1..0x7FFFFFFF*/ TColor;
enum TMaterialType {mtAmbient,
mtDiffuse,
mtSpecular };
typedef int TVertexIndex [ 3/*# range 0..2*/ ];
struct TFace {
TVertexIndex VertIndex;
TVertexIndex CoordIndex;
};
enum TRenderMode {rmTriangles,
rmLines,
rmPoints };
enum TTransformType {ttRotate,
ttTranslate,
ttScale };
// This Class is used to apply one transformation to 3ds object. The instance
// is stored in TTransformList class
class TTransformation: public TObject {
typedef TObject inherited;
friend class T3DModel;
friend class T3DObject;
friend class TChunk;
friend class TMaterial;
friend class TMaterialProperties;
friend class TTransformList;
private:
float FX;
float FY;
float FAngle;
float FZ;
TTransformType FTransformType;
bool FEnabled;
public:
__fastcall TTransformation( );
void __fastcall Apply( );
void __fastcall Restore( );
__property float Angle = { read = FAngle, write = FAngle };
__property TTransformType TransformType = { read = FTransformType, write = FTransformType };
__property float X = { read = FX, write = FX };
__property float Y = { read = FY, write = FY };
__property float Z = { read = FZ, write = FZ };
__property bool Enabled = { read = FEnabled, write = FEnabled };
};
// Class to store the material properties. Ambient, diffuse, specular
// and emission are classes of TMaterialProperties
class TMaterialProperties: public TObject {
typedef TObject inherited;
friend class T3DModel;
friend class T3DObject;
friend class TChunk;
friend class TMaterial;
friend class TTransformList;
friend class TTransformation;
private:
TVector4f FVector;
unsigned int FglDefFace, FglDefType;
TColor __fastcall GetColor( );
void __fastcall SetColor( const TColor Value );
public:
__fastcall TMaterialProperties( unsignedint glDefFace, unsignedint glDefType );
__fastcall virtual ~TMaterialProperties( );
String __fastcall ToString( );
void __fastcall SetRGBA( const float R, const float G, const float B, const float Alpha );
void __fastcall Apply( );
__property TVector4f Vector = { read = FVector, write = FVector };
__property TColor Color = { read = GetColor, write = SetColor };
__property float Alpha = { read = FVector.Alpha, write = FVector.Alpha };
};
// List of TTransformation class
class TTransformList: public TList {
typedef TList inherited;
friend class T3DModel;
friend class T3DObject;
friend class TChunk;
friend class TMaterial;
friend class TMaterialProperties;
friend class TTransformation;
private:
bool FEnabled;
public:
__fastcall TTransformList( );
__fastcall virtual ~TTransformList( );
void __fastcall Push( );
void __fastcall Pop( );
__property bool Enabled = { read = FEnabled, write = FEnabled };
TTransformation* __fastcall AddTransform( );
TTransformation* __fastcall AddTransformEx( const TTransformType _TransformType, const float _Angle, const float _X, const float _Y, const float _Z );
};
// TChunk only used for loading the 3ds file. This class is destroyed after
// loading
class TChunk: public TObject {
typedef TObject inherited;
friend class T3DModel;
friend class T3DObject;
friend class TMaterial;
friend class TMaterialProperties;
friend class TTransformList;
friend class TTransformation;
private:
WORD FId;
int FLength;
int FBytesReaded;
T3DModel* FModel;
int FFileHandle;
int __fastcall GetBytesRemaining( );
public:
__fastcall TChunk( T3DModel* Model );
__fastcall virtual ~TChunk( );
int __fastcall read( );
int __fastcall ReadBuffer( void* Buffer, int Count );
int __fastcall ReadRemainingBuffer( void* Buffer );
void __fastcall ProcessNextChunk( TChunk* PreviousChunk );
void __fastcall NexFilePosition( );
String __fastcall ReadObjectString( );
bool __fastcall WaitForLength( );
void __fastcall UpdateByteCounter( int Value );
__property WORD Id = { read = FId };
__property int Length = { read = FLength };
__property int BytesReaded = { read = FBytesReaded };
__property int BytesRemaining = { read = GetBytesRemaining };
__property int FileHandle = { read = FFileHandle, write = FFileHandle };
};
// Store the complete material properties for each 3ds object
class TMaterial: public TObject {
typedef TObject inherited;
friend class T3DModel;
friend class T3DObject;
friend class TChunk;
friend class TMaterialProperties;
friend class TTransformList;
friend class TTransformation;
private:
String FMaterialName;
String FMaterialFile;
bool FHasTexture;
unsigned int FGenTexture;
bool FDisableTexture;
bool FEnviromentMap;
bool FSphericalMap;
TMaterialProperties* FAmbient;
TMaterialProperties* FEmission;
TMaterialProperties* FSpecular;
TMaterialProperties* FDiffuse;
// uTile: Single;
// vTile: Single;
// uOffset: Single;
// vOffset: Single;
void __fastcall SetMaterial( );
void __fastcall EnviromentApply( );
void __fastcall SphericalApply( );
bool __fastcall TextureActive( );
public:
float Shininess, Transparency;
__fastcall TMaterial( );
__fastcall virtual ~TMaterial( );
void __fastcall ProcessNextMaterialChunk( TChunk* PreviousChunk );
void __fastcall ReadColorChunk( TChunk* PreviousChunk, void* Buffer );
void __fastcall CopyFrom( TMaterial* Source );
void __fastcall SetMaterialColor( const TMaterialType MaterialType, const float R, const float G, const float B, const float Alpha );
__property bool HasTexture = { read = FHasTexture };
__property bool DisableTexture = { read = FDisableTexture, write = FDisableTexture };
__property bool EnviromentMap = { read = FEnviromentMap, write = FEnviromentMap };
__property bool SphericalMap = { read = FSphericalMap, write = FSphericalMap };
__property unsignedint GenTexture = { read = FGenTexture, write = FGenTexture };
__property String MaterialName = { read = FMaterialName };
__property String MaterialFile = { read = FMaterialFile };
__property TMaterialProperties* Ambient = { read = FAmbient };
__property TMaterialProperties* Diffuse = { read = FDiffuse };
__property TMaterialProperties* Specular = { read = FSpecular };
__property TMaterialProperties* Emission = { read = FEmission };
};
// This class stores the complete definition for each 3ds object. Is used to
// draw it in the scene also.
class T3DObject: public TObject {
typedef TObject inherited;
friend class T3DModel;
friend class TChunk;
friend class TMaterial;
friend class TMaterialProperties;
friend class TTransformList;
friend class TTransformation;
private:
bool FVisible;
String FObjectName;
TMaterial* FMaterial;
int FVertexCount, FTexVertexCount, FFaceCount, FNormalCount;
int FObjectIndex;
TVector3D FMaxVector, FMinVector, FMidVector;
bool FSelected;
unsigned int FRMode;
TRenderMode FRenderMode;
TTransformList* FTransformList;
void __fastcall SetRenderMode( const TRenderMode Value );
void __fastcall DrawBox( );
public:
DynamicArray< TVector3D > Verts;
DynamicArray< TVector3D > Normals;
DynamicArray< TVector2D > TexVerts;
DynamicArray< TFace > Faces;
__fastcall T3DObject( );
__fastcall virtual ~T3DObject( );
void __fastcall Draw( );
void __fastcall ProcessNextObjectChunk( TChunk* PreviousChunk );
void __fastcall ReadVertices( TChunk* PreviousChunk );
void __fastcall ReadVertexIndices( TChunk* PreviousChunk );
void __fastcall ReadObjectMaterial( TChunk* PreviousChunk );
void __fastcall ReadUVCoordinates( TChunk* PreviousChunk );
void __fastcall AdjustNormals( );
// procedure Transform(const Transformation:TTransformObject; const T, X, Y, Z:Single);
__property bool Visible = { read = FVisible, write = FVisible };
__property String ObjectName = { read = FObjectName, write = FObjectName };
__property TMaterial* Material = { read = FMaterial };
__property int VertexCount = { read = FVertexCount };
__property int TexVertexCount = { read = FTexVertexCount };
__property int FaceCount = { read = FFaceCount };
__property int NormalCount = { read = FNormalCount };
__property int ObjectIndex = { read = FObjectIndex };
__property TRenderMode RenderMode = { read = FRenderMode, write = SetRenderMode };
__property TTransformList* TransformList = { read = FTransformList };
__property bool Selected = { read = FSelected, write = FSelected };
};
// This class is the core of this unit. It is used to load, draw all and more
class T3DModel: public TObject {
typedef TObject inherited;
friend class T3DObject;
friend class TChunk;
friend class TMaterial;
friend class TMaterialProperties;
friend class TTransformList;
friend class TTransformation;
private:
DynamicArray< TMaterial* > FMaterials;
int FFileHandle;
TChunk* FRootChunk;
int __fastcall GetMaterialCount( );
int __fastcall GetObjectCount( );
void __fastcall CleanUp( );
void __fastcall ComputeNormals( );
public:
DynamicArray< T3DObject* > Objects;
__fastcall T3DModel( );
__fastcall virtual ~T3DModel( );
TMaterial* __fastcall AddMaterial( );
T3DObject* __fastcall AddObject( );
void __fastcall Clear( );
void __fastcall VisibleAll( );
bool __fastcall LoadFromFile( const String FileName );
T3DObject* __fastcall FindObject( const String aName );
T3DObject* __fastcall Select( const int Index );
void __fastcall Draw( );
__property int ObjectCount = { read = GetObjectCount };
__property int MaterialCount = { read = GetMaterialCount };
};
#endif // Unit3DSH