glTFist das lizenzgebührenfreie File Format von Khronos für die umfassende und effiziente Übertragung und das Laden von 3D-Szenen und -Modellen, das in der Branche als "JPEG/PNG of 3D" bekannt ist. Mit PBR können Entwickler und Künstler einen hohen Grad von wirklichkeitsgetreuen Fotorealismus erzielen, indem sie Parameter rendern, die den realen physikalischen Eigenschaften von Materialien in 3D-Assets entsprechend externe Assets in eigeen OpenGL Application zu laden . Diese neuen Erweiterungen für Clear-Coat-Shading, Transmission und Sheen (Glanz) bauen auf den vorhandenen PBR-Funktionen von glTF 2.0 auf und bilden zusammen mit weiteren bevorstechenden Erweiterungen ein leistungsstarkes, interoperables, physikalisch basiertes Materialmodell (PBR) für das glTF-Transmission-Ökosystem. Leider fehlt noch ein entsprechendes Format um Textilien (Clothes) , die z. B. in Marvelous Designer definiert und animiert werden, dynamisch-physikalisch in Echtzeit ebenso leistungsstark darzustellen und auf alle möglichen Plattformen zu übertragen es in eigene Applicationen einfach zu importieren.
Mit anderen Worten soll es dadurch leichter werden externe Assets, die. z. B. in Substance Painter, Cinema 4D, 3DSMax, Blender usw. hergestellt und mittels glTF exportiert wurden in Anwendungen großer Engiens wie Unreal, Unity usw. zu importieren und physikalisch fotorealistisch darzustellen, sofern neben den Materialein auch die erforderlichen Shader, Konverter (Parser JSON Files) usw. vorhanden sind. Ansonsten sind diese Formate und Application völlig nutzlos für eigene OpenGL Engines den sinnlosen Datennmüll nur zu vermehren World-Editoren, Terrain-Builder usw. anzubieten die keine richtigen Exporter, Konverter und alle Notwenige mitbrirngen die PBR Materialen in eigene OpenGL Runtime Engines zu implementieren und zu rendern. Das glTF Format findet Anwendung z. B. in WebGL, Three.js oder Babylon.js. Unreal, Unity usw..


Borland C++ Builder 6 Code (verwendet Microsoft Agent Technologie):
Download Quellcode: http://spaceglobe.diskstation.eu/Pictures1/PhobosDemo.zip
Borland C++ Builder 6 Code (Tie und low polygon plastischer Marsglobus 3ds File Format):
http://spaceglobe.diskstation.eu/Pictures1/BCB6TieDemo3DS.zip
- Code: Select all
/*******************************************************************************
* ______ ______ ________ ____ ___ _____ ___ ____ __ ____ *
* / ___/| \\___ \ / > / \ / \| | / \| | / \ *
* \____\ | ( )_/ / ( ) \ / / \ ( )/ \ ( )_/| |_ _| ( ) || \___\ ( )/ *
* /____ > | / (____ / \ \ \ \ \ > | _ _ /\ __/| ( )_)\ \ *
* \/ |_/ \/ \__\ \/ \/ \/ \/ \/ \/ *
* *
* *
* Project Name: Triaxial ellipsoids *
* Author: Horst Schumacher *
* Description: This program shows Tessellation *
* nd morphographic mapping of triaxial ellipsoid Phobos *
* Copyright (c) by http://www.spaceglobe.de *
* *
* Keyboard allocation: *
* *
* Numpad + : Zoom In *
* Numpad - : Zoom Out *
* *
* Arrow key left: pan the image Left *
* Arrow key right: pan the image right *
* *
* Tie Ship in Phobos.exe: Arrow key Up: TIE forward *
* Arrow key Down: TIE backward *
* *
* Press F5 key: Roll Tie about the Z-axis - press the arrow key up or down *
* Press F6 key: Yaw Tie about the Y-axis - press the arrow key up or down *
* Press F7 key: Pitch Tie about the X-axis - press the arrow key up or down *
* *
* Arrow key down: Down *
* Hold the Left mouse key to rotate the planet. *
* Hold the Right mouse key to drag the image. *
* *
* F1 key: wireframe/solid - press F5/F6/F7 to move the TIE *
* - press arrow key up or down *
* F2 and F6 key: rotate the pilots cabin *
* F3 key: hold the left mouse key and drag to fly around the Imperial TIE *
* Interceptor find the ship: scrolling the centre of Mars exact into the *
* middle of screen) *
* F4 key: hold the left mouse key and drag to fly around the Voyager *
* (find the ship: scrolling the centre of Mars exact into the middle of screen)*
* *
********************************************************************************/
#include <vcl.h>
#include <mmsystem.h>
#pragma hdrstop
#include "PhobosTex.h"
#include "phobosdata.h"
#include <fastmath.h>
#include <float.h>
#include <dsound.h> //DirectSound SDK Path
#include <math.h>
#include <windows.h>
#include <stdio.h>
#include <gl/glaux.h>
#include <mem.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> //DirectInput SDK Path
#define Mars 1000
#define Phobos 1100
#define Star 1200
#define DegToRad(x)((x)*(3.14159265/180.0))
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MSAgent"
#pragma resource "*.dfm"
TForm1 *Form1;
HWND hWnd = 0;
//DirectInput
LPDIRECTINPUT8 lpDI=NULL;
LPDIRECTINPUTDEVICE8 lpDIKeyboard=NULL;
bool bKeyboard[256];
//ZeroMemory(&bKeyboard, sizeof(bKeyboard));
//DirectSound
IDirectSound *lpds=NULL;
IDirectSoundBuffer *lpdsTie=NULL,*lpdsLogo=NULL;
//LPDIRECTSOUND lpds=NULL;
//LPDIRECTSOUNDBUFFER lpdsTie=NULL,lpdsLogo=NULL;
GLbyte Texture1[2048*1024*3]; //Textur SkyDome
GLuint textMars=0,textPhobos=0,textStar=0;
Model *pModel = NULL; //Model I Voyager
Model *pModel1 = NULL; // Model II Imperial TIE Interceptor with pilot (Featured in the STAR WARS trilogy by LucasFilm Ltd.)
const float frad = 0.017453293;
const float frad2=57.29578;
const float quad1 = 1.57079633;
const float PI = 3.14159265;
const float DPI = 6.2831853;
const float DPIv = 1.0/6.2831853;
const float PIv = 1.0/3.14159265;
bool flag = false;
bool flag1 = false;
bool flag2 = false;
bool flag3 = false;
int Zeit=0;
GLfloat m[16];
float dx=0,dy=0,dz=0,gas=0.1;
float roll,pitch,head;
void gosub(void);
void forward(void);
void backward(void);
void Fail(char* szMsg);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
_control87(MCW_EM,MCW_EM);
Application->OnIdle = IdleLoop;
HRESULT hr;
//DirectInput Object anlegen
hr=DirectInput8Create(HInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,(LPVOID*)&lpDI,NULL);
if (FAILED(hr))
Application->MessageBox("DirectInputCreate failed", "OK", MB_OK );
lpDI->CreateDevice(GUID_SysKeyboard, &lpDIKeyboard, NULL);
lpDIKeyboard->SetDataFormat(&c_dfDIKeyboard);
lpDIKeyboard->SetCooperativeLevel(Form1->Handle, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
lpDIKeyboard->Acquire();
MSAgent1->Connected=true;
Agent1=new TAgentCharacters;
AgentNr=Agent1->Load("Merlin");
agent = new TAgentCharacter;
agent=Agent1->Character(AgentNr);
agent->LanguageID=MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN);
}
//----------------------------------------------------------------------------
float rot=0,fbf=-6,fl=0,fr=0,fx1=0,fy1=0,fx2=0,fy2=0,fLookx=0,fLooky=0,fxp1=0,fyp1=0,fxp2=0,fyp2=0;
float i,K,w,e,a,M,M1,E,x,y,z,r,vp,X,Y,Z,r1,vp1,X1,Y1,Z1,b,le;
GLfloat SunPos[] = {67117.0f, 0.0f, 0.0f, 1.0f};
HRESULT hr;
void __fastcall TForm1::IdleLoop(TObject*, bool& done)
{
done = false;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
rot+=0.03;
if (rot>360)
rot=0;
hr=lpDIKeyboard->GetDeviceState(sizeof(bKeyboard),(LPVOID)&bKeyboard);
if FAILED(hr)
{
lpDIKeyboard->Acquire();
}
if (bKeyboard[DIK_LEFT])
{
fl-=0.04f;
}
else if (bKeyboard[DIK_RIGHT])
{
fl+=0.04f;
}
if (bKeyboard[DIK_UP])
{
forward();
}
else if (bKeyboard[DIK_DOWN])
{
backward();
}
if (bKeyboard[DIK_ADD])
{
fbf+=0.05f;
if (abs(fbf)>10)
fbf+=4;
}
else if (bKeyboard[DIK_SUBTRACT])
{
fbf-=0.05f;
if (abs(fbf)>10)
fbf-=4;
}
if (bKeyboard[DIK_F5])
{
roll+=3;
}
if (bKeyboard[DIK_F6])
{
pitch+=3;
}
if (bKeyboard[DIK_F7])
{
head+=3;
}
// Transform in world coordinates
glPushMatrix();
glTranslatef(0,0,-35);
glRotatef(fLookx,0,1,0);
glRotatef(-fLooky,1,0,0);
glRotatef(-rot,0,1,0);
glCallList((GLint)Star); //SkyDome
glPopMatrix();
gosub();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, SunPos);
glDisable(GL_COLOR_MATERIAL);
// FEDERATION INTREPID CLASS STAR SHIP AS SEEN ON STAR TREK VOYAGER
// Bahnelemente elliptischer Mars-Orbit
i=DegToRad(50.1); //inclination Bahnneigung gegen den Marsäquator
K=DegToRad(100.23); //ascending node aufsteigender Bahnknoten
w=DegToRad(34); //argument of periares marsnächster Bahnpunkt
e=0.3; //eccentricity
a=2.3; //semimajor axis große Halbachse der Bahn in Marsradien
M+=0.001; //mean anomaly mittl. Bahngeschwindigkeit
if (M>M_PI*2)
M=0;
E=M; //E eccentric anomaly
for (int i1=0;i1<5;i1++);
E=E+(M+e*sin(E)-E)/(1-e*cos(E)); //Equation of Kepler
vp=atan(sqrt((1+e)/(1-e))*tan(E/2))*2; //true Anomaly
r=a*(1-e*cos(E)); //radius vector Entf. vom Marszentrum in Marsradien
X=r*(cos(w+vp)*sin(K)+sin(w+vp)*cos(i)*cos(K));
Y=r*sin(w+vp)*sin(i);
Z=r*(cos(w+vp)*cos(K)-sin(w+vp)*cos(i)*sin(K));
glCullFace(GL_BACK);
glPushMatrix();
glTranslatef(X,Y,Z);
glRotatef(270,1,0,0);
glRotatef(90,0,0,1);
glRotatef(rot,0,0,1);
glScalef(0.04,0.04,0.04);
pModel->draw(); //STAR TREK
glPopMatrix();
// Imperial TIE Interceptor with pilot
//Bahnelemente elliptischer Mars-Orbit
i=DegToRad(10.1); //inclination Bahnneigung gegen den Marsäquator
K=DegToRad(200.23); //ascending node aufsteigender Bahnknoten
w=DegToRad(340); //argument of periares marsnächster Bahnpunkt
e=0.001; //eccentricity
a=3.3; //semimajor axis große Halbachse der Bahn in Marsradien
M1+=0.001; //mean anomaly mittl. Bahngeschwindigkeit
if (M1>M_PI*2)
M1=0;
E=M1; //E eccentric anomaly
for (int i1=0;i1<5;i1++);
E=E+(M1+e*sin(E)-E)/(1-e*cos(E)); //Equation of Kepler
vp=atan(sqrt((1+e)/(1-e))*tan(E/2))*2; //true Anomaly
r=a*(1-e*cos(E)); //radius vector Entf. vom Marszentrum in Marsradien
r1=r;
X1=r*(cos(w+vp)*sin(K)+sin(w+vp)*cos(i)*cos(K));
Y1=r*sin(w+vp)*sin(i);
Z1=r*(cos(w+vp)*cos(K)-sin(w+vp)*cos(i)*sin(K));
glPushMatrix();
glTranslatef(X1+dx,Y1+dy,Z1+dz);
glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(pitch, 0.0, 1.0, 0.0);
glRotatef(head, 1.0, 0.0, 0.0);
glRotatef(270,1,0,0);
glRotatef(0,0,0,1);
if (flag1==true)
glScalef(0.1,0.1,0.1);
else
glScalef(0.005,0.005,0.005);
pModel1->draw(); //STAR WARS
glPopMatrix();
//----------------------------------
glEnable(GL_COLOR_MATERIAL);
glColor3ub(255, 255, 255);
GLfloat PlanAmbiente[] = {0.0f,0.0f,0.0f,0.0f };
GLfloat sphereShine[] = {128.0f};
GLfloat sphereSpec[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat emi[] = {0.2, 0.1f, 0.4f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, PlanAmbiente);
glMaterialfv(GL_FRONT, GL_SPECULAR, sphereSpec);
glMaterialfv(GL_FRONT, GL_SHININESS, sphereShine);
glMaterialfv(GL_FRONT, GL_EMISSION, emi);
glEnable(GL_TEXTURE_2D);
glRotatef(rot,0,1,0);
glCallList((GLint)Mars); //The Red Planet
glTranslatef(-4,0,0);
glColor3ub(255, 255, 255);
GLfloat PlanAmbiente1[] = {0.0f,0.0f,0.0f,1.0f };
GLfloat sphereShine1[] = {100.0f};
GLfloat sphereSpec1[] = {1.0f, 0.8f, 0.8f, 1.0f};
GLfloat emi1[] = {0.1, 0.1f, 0.1f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, PlanAmbiente1);
glMaterialfv(GL_FRONT, GL_SPECULAR, sphereSpec1);
glMaterialfv(GL_FRONT, GL_SHININESS, sphereShine1);
glMaterialfv(GL_FRONT, GL_EMISSION, emi1);
glEnable(GL_COLOR_MATERIAL);
glCullFace(GL_FRONT);
glCallList((GLint)Phobos); //Phobos
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glFlush();
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SetPixelFormatDescriptor()
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,0,0,0,0,0,0,0,
32,
0,0,
PFD_MAIN_PLANE,
0,0,0,
};
PixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, PixelFormat, &pfd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
hdc = GetDC(Handle);
SetPixelFormatDescriptor();
hrc = wglCreateContext(hdc);
if(hrc == NULL)
ShowMessage("CreateContext failed.");
wglMakeCurrent(hdc,hrc);
if(wglMakeCurrent(hdc, hrc) == false)
ShowMessage("MakeCurrent context failed.");
pModel = new MilkshapeModel(); //LOAD MODEL I Yoyager
if ( pModel->loadModelData( "Modelle\\Voyager.ms3d" ) == false )
{
MessageBox( NULL, "Couldn't load the model", "Error", MB_OK | MB_ICONERROR );
return;
}
pModel->reloadTextures();
pModel1 = new MilkshapeModel(); //LOAD MODEL II Imperial TIE Interceptor with pilot
if (pModel1->loadModelData( "Modelle\\TIE.ms3d" ) == false )
{
MessageBox( NULL, "Couldn't load the model", "Error", MB_OK | MB_ICONERROR );
return;
}
pModel1->reloadTextures();
if (MarsSphere == NULL)
{
HDC dc=GetDC(0);
stream1 = new TMemoryStream;
stream1->SetSize(int(sizeof(BITMAPINFOHEADER)
+Image1->Picture->Bitmap->Height
*((long)(Image1->Picture->Bitmap->Width+4) * 3)));
BITMAPINFOHEADER *bmap1;
bmap1 = (BITMAPINFOHEADER*)stream1->Memory;
bmap1->biSize = sizeof (BITMAPINFOHEADER);
bmap1->biWidth = Image1->Picture->Bitmap->Width;
bmap1->biHeight = Image1->Picture->Bitmap->Height;
bmap1->biPlanes = 1;
bmap1->biBitCount = 24;
bmap1->biCompression = BI_RGB;
bmap1->biSizeImage = 0;
bmap1->biXPelsPerMeter = 10000;
bmap1->biYPelsPerMeter = 10000;
bmap1->biClrUsed =0;
bmap1->biClrImportant =0;
MarsSphere = (char*)stream1->Memory +sizeof (BITMAPINFOHEADER);
int I=GetDIBits(dc, Image1->Picture->Bitmap->Handle,
0,Image1->Picture->Bitmap->Height,MarsSphere,(BITMAPINFO*)stream1->Memory, DIB_RGB_COLORS);
int j=0;
char s;
for (j=0;j< Image1->Picture->Bitmap->Height*(Image1->Picture->Bitmap->Width+4) * 3;j+=3)
{
s=*((char*)MarsSphere+j);
*((char*)MarsSphere+j) = *((char*)MarsSphere+j+2);
*((char*)MarsSphere+j+2)=s;
}
}
if (PhobosSphere == NULL)
{
HDC dc=GetDC(0);
stream2 = new TMemoryStream;
stream2->SetSize(int(sizeof(BITMAPINFOHEADER)
+ Image2->Picture->Bitmap->Height*((long)(Image2->Picture->Bitmap->Width+4) * 3)));
BITMAPINFOHEADER *bmap2;
bmap2 = (BITMAPINFOHEADER*)stream2->Memory;
bmap2->biSize = sizeof (BITMAPINFOHEADER);
bmap2->biWidth = Image2->Picture->Bitmap->Width;
bmap2->biHeight = Image2->Picture->Bitmap->Height;
bmap2->biPlanes = 1;
bmap2->biBitCount = 24;
bmap2->biCompression = BI_RGB;
bmap2->biSizeImage = 0;
bmap2->biXPelsPerMeter = 10000;
bmap2->biYPelsPerMeter = 10000;
bmap2->biClrUsed =0;
bmap2->biClrImportant =0;
PhobosSphere = (char*)stream2->Memory +sizeof (BITMAPINFOHEADER);
int I=GetDIBits(dc, Image2->Picture->Bitmap->Handle,
0,Image2->Picture->Bitmap->Height,PhobosSphere,(BITMAPINFO*)stream2->Memory, DIB_RGB_COLORS);
int j;
char s;
for (j=0;j< Image2->Picture->Bitmap->Height*(Image2->Picture->Bitmap->Width+4) * 3;j+=3)
{
s=*((char*)PhobosSphere+j);
*((char*)PhobosSphere+j) = *((char*)PhobosSphere+j+2);
*((char*)PhobosSphere+j+2)=s;
}
}
glGenTextures(1, &textMars);
glBindTexture(GL_TEXTURE_2D,textMars);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,3,1024,512,0,GL_RGB,GL_UNSIGNED_BYTE,MarsSphere);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
float fn1=0,fn2=0,fR=1,fB1=0,fB2=0,fL1=0;
float ff = 1.0/147.7; //Abplattung Rotationsellipsoid: Erde=1/298.257,
// Mars 1/147.7, Satun=1/10.2
float ee=2*ff-ff*ff;
int i=0,i1=0,ilb=72; //Breiten- und Längenaufteilung
glNewList((GLuint)Mars,GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, textMars);
for (i=0;i<ilb/2;i++)
{
fB1=i*DPI/ilb-quad1;
fB2=(i+1)*DPI/ilb-quad1;
glBegin(GL_QUAD_STRIP); //QUAD oder TRIANGLE Tessellation
for (i1=0;i1<=ilb;i1++)
{
fL1=-i1*DPI/ilb;
fn1=fR/sqrt(1-ee*pow(sin(fB1),2)); //Flattening
fn2=fR/sqrt(1-ee*pow(sin(fB2),2));
v[0]=_fm_cos(fL1)*_fm_cos(fB2); //X fB1,fL1,fn1 Polarkoordinaten in
v[1]=_fm_sin(fB2)*(1-ee); //Y kart. Koordinaten
v[2]=_fm_sin(fL1)*_fm_cos(fB2); //Z
s[0]=fn2*v[0];
s[1]=fn2*v[1];
s[2]=fn2*v[2];
glNormal3dv(v);
glTexCoord2f(i1/(float)ilb,2*(i+1)/(float)ilb);glVertex3dv(s);
v[0]=cos(fL1)*_fm_cos(fB1);
v[1]=sin(fB1)*(1-ee);
v[2]=sin(fL1)*_fm_cos(fB1);
t[0]=fn1*v[0];
t[1]=fn1*v[1];
t[2]=fn1*v[2];
glNormal3dv(v);
glTexCoord2f(i1/(float)ilb,2*i/(float)ilb);glVertex3dv(t);
}
}
glEnd();
glEndList();
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &textPhobos);
glBindTexture(GL_TEXTURE_2D, textPhobos);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3,512,512, GL_RGB, GL_UNSIGNED_BYTE,PhobosSphere);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
float RA=1,RA1=1,RA2=1,fLong1=0,fLong2=0,fLat1=0,fLat2=0;
const int LatTeil = 36; //Breiten- und Längenaufteilung (Phobos 5 Grad)
const int LongTeil = 72;
int il=-37,i2=0,BSpart=0,LSpart=1;
float scale=1.0/30;
glNewList((GLuint)Phobos,GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, textPhobos);
glBegin(GL_TRIANGLE_STRIP); //TRIANGLE Tessellation
for (LSpart=1;LSpart<=LongTeil;LSpart++){
il+=37; //Increment in Länge
i2=il+37;
fLong1=frad*phobosdata[il][0];
fLong2=frad*phobosdata[i2][0];
for (BSpart=0;BSpart<=LatTeil;BSpart++)
{
fLat1=frad*phobosdata[BSpart][1];
fLat2=frad*phobosdata[BSpart+1][1];
RA=scale*phobosdata[il+BSpart][2];
RA1=scale*phobosdata[i2+BSpart+1][2];
RA2=scale*phobosdata[i2+BSpart][2];
v1[0]=_fm_cos(fLong1)*_fm_cos(fLat1); //X
v1[1]=_fm_sin(fLat1); //Y
v1[2]=_fm_sin(fLong1)*_fm_cos(fLat1); //Z
s[0]=RA*v1[0];
s[1]=RA*v1[1];
s[2]=RA*v1[2];
v2[0]=_fm_cos(fLong2)*_fm_cos(fLat2);
v2[1]=_fm_sin(fLat2);
v2[2]=_fm_sin(fLong2)*_fm_cos(fLat2);
t[0]=RA1*v2[0];
t[1]=RA1*v2[1];
t[2]=RA1*v2[2];
v3[0]=_fm_cos(fLong2)*_fm_cos(fLat1);
v3[1]=_fm_sin(fLat1);
v3[2]=_fm_sin(fLong2)*_fm_cos(fLat1);
u[0]=RA2*v3[0];
u[1]=RA2*v3[1];
u[2]=RA2*v3[2];
glNormal3dv(v1);
glTexCoord2f((PI-fLong1)*DPIv,(fLat1 + quad1)*PIv);glVertex3dv(s); //TRIANGLE
glNormal3dv(v3);
glTexCoord2f((PI-fLong2)*DPIv,(fLat1 + quad1)*PIv);glVertex3dv(u);
glNormal3dv(v1);
glTexCoord2f((PI-fLong1)*DPIv,(fLat1 + quad1)*PIv);glVertex3dv(s);
glNormal3dv(v2);
glTexCoord2f((PI-fLong2)*DPIv,(fLat2 + quad1)*PIv);glVertex3dv(t);
}
}
glEnd();
glEndList();
{
GLbyte *a;
for (int i=0;i<1024;i++){
(void*) a = Image3->Picture->Bitmap->ScanLine[i];
for (int j=0; j<2048; j++){
Texture1[((i*2048+j)*3) ] = a[j*3+2];
Texture1[((i*2048+j)*3)+1] = a[j*3+1];
Texture1[((i*2048+j)*3)+2] = a[j*3+0];
}};
};
glGenTextures(1, &textStar);
glBindTexture(GL_TEXTURE_2D,textStar);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,3,2048,1024,0,GL_RGB,GL_UNSIGNED_BYTE,Texture1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glNewList((GLuint)Star,GL_COMPILE);
glBindTexture(GL_TEXTURE_2D,textStar);
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
GLUquadricObj* SkyDome;
SkyDome =gluNewQuadric();
gluQuadricTexture(SkyDome,GL_TRUE);
//gluQuadricDrawStyle(SkyDome,GLU_LINE);
glRotatef(90,1,0,0);
glRotatef(180-37,1,0,0); //Mars Nordpol unterhalb des Sternbildes Cehpheus
gluSphere(SkyDome,60,36,36); //Mars-Nordpol AR 318 Grad Deklin. +53 Grad
gluDeleteQuadric(SkyDome);
glDisable(GL_TEXTURE_2D);
glEndList();
glMatrixMode(GL_MODELVIEW);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
TResourceStream *AStream3 = new TResourceStream ((int)HInstance,"ID_MO", "ANICURSOR1");
try
{
Screen->Cursors[crArrow]= CreateIconFromResource ((PBYTE)(AStream3->Memory),(DWORD)(AStream3->Size),false,0x00030000);
Screen->Cursor = (Controls::TCursor)crArrow;
}
__finally
{
delete AStream3;
}
// mmsystem.h Resource tiesound.rc
//PlaySound("ID_TIE",HANDLE(HInstance),SND_ASYNC | SND_RESOURCE);
HWND hwnd = Form1->Handle;
//DirectSound Object anlegen
if (FAILED(DirectSoundCreate(NULL,&lpds,NULL)))
Fail("DirectSoundCreate failed");
//Kooperationsebene setzen
if (FAILED(lpds->SetCooperativeLevel(hwnd,DSSCL_NORMAL)))
Fail("SetCooperativeLevel failed");
DSBUFFERDESC dsbdesc;
HRSRC hrsrc;
HGLOBAL hD;
DWORD *pD;
void *pData1=0, *pData2=0;
DWORD dwBuff1,dwBuff2;
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_STATIC;
hrsrc = FindResource(HInstance, "ROME", "WAVE");
hD = LoadResource(HInstance, hrsrc);
pD = (DWORD *)LockResource(hD);
dsbdesc.dwBufferBytes = *(pD+10);
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)(pD+5);
lpds->CreateSoundBuffer(&dsbdesc, &lpdsTie, NULL);
lpdsTie->Lock(0, dsbdesc.dwBufferBytes, &pData1, &dwBuff1,&pData2, &dwBuff2,0);
memcpy(pData1, (LPBYTE)(pD+11),dwBuff1);
if (dwBuff2 != 0)
memcpy(pData2, (LPBYTE)(pD+11)+ dwBuff1, dwBuff2);
lpdsTie->Unlock(pData1, dwBuff1, pData2, dwBuff2);
hrsrc = FindResource(HInstance, "logo", "WAVE");
hD = LoadResource(HInstance, hrsrc);
pD = (DWORD *)LockResource(hD);
dsbdesc.dwBufferBytes = *(pD+10);
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)(pD+5);
lpds->CreateSoundBuffer(&dsbdesc, &lpdsLogo, NULL);
lpdsLogo->Lock(0, dsbdesc.dwBufferBytes, &pData1, &dwBuff1,&pData2, &dwBuff2,0);
memcpy(pData1, (LPBYTE)(pD+11),dwBuff1);
if (dwBuff2 != 0)
memcpy(pData2, (LPBYTE)(pD+11)+dwBuff1, dwBuff2);
lpdsLogo->Unlock(pData1, dwBuff1, pData2, dwBuff2);
lpdsTie->Play(0, 0, DSBPLAY_LOOPING);
// MSAgent1->Characters->Load("merlin","C:\\Windows\\msagent\\chars\\merlin.acs");
//agent = MSAgent1->Characters->Character("merlin");
}
//---------------------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hrc);
if (!(stream1 == NULL)) {stream1->Free();};
if (!(stream2 == NULL)) {stream2->Free();};
lpdsTie->Release();
lpdsTie=NULL;
lpDIKeyboard->Unacquire();
lpDIKeyboard->Release();
lpDIKeyboard = NULL;
lpDI->Release();
lpDI = NULL;
Agent1->Unload(AgentNr);
delete Agent1;
MSAgent1->Connected=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
wglMakeCurrent(hdc, hrc);
GLfloat fw1 = ClientWidth;
GLfloat fh1 = ClientHeight;
if(fh1 == 0)
fh1 = 1;
GLdouble fwh;
glViewport(0, 0,fw1, fh1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
fwh = (fw1*1.0) / (fh1*1.0);
gluPerspective(60,fwh,0.1,100000.0);
glMatrixMode(GL_MODELVIEW);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if (Shift.Contains(ssLeft))
{
fx1=X;
fy1=Y;
fx2=fLookx;
fy2=fLooky;
}
if (Shift.Contains(ssRight))
{
fxp1=X;
fyp1=Y;
fxp2=fl;
fyp2=fr;
}
}
//---------------------------------------------------------------------------
float delta;
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
//-----------------------
//Besser: DirectInput ermöglicht mehrere Tastendrücke gleichzeitig
//----------------------
switch (Key)
{
// case VK_UP:
// forward();
// break;
// case VK_DOWN:
// backward();
// break;
// case VK_LEFT:
// fl-=0.05f;
// break;
// case VK_RIGHT:
// fl+=0.05f;
// break;
//case VK_ADD:
// fbf+=0.05f;
// break;
// case VK_SUBTRACT:
// fbf-=0.05f;
// break;
// case VK_F5:
// roll+=3;
// break;
// case VK_F6:
// pitch+=3;
// break;
// case VK_F7:
// head+=3;
// break;
case VK_F1:
flag=!flag;
lpdsLogo->SetCurrentPosition(0); //DirectSound logo.wav
lpdsLogo->Play(0, 0, 0);
if (flag)
{
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
flag1=false;
flag2=false;
flag3=false;
}
else
{
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
break;
case VK_F2:
flag1=!flag1;
if (flag1)
{
flag2=false;
flag3=false;
}
break;
case VK_F3:
flag2=!flag2;
if (flag2)
{
flag1=false;
flag3=false;
}
break;
case VK_F4:
flag3=!flag3;
if (flag3)
{
flag1=false;
flag2=false;
}
break;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if (Shift.Contains(ssLeft))
{
Screen->Cursor=crNone;
fLookx=fx2+(X-fx1)*0.5;
fLooky=fy2+(Y-fy1)*0.5;
}
if (Shift.Contains(ssRight))
{
Screen->Cursor=crNone;
fl=(X-fxp1)*0.02+fxp2;
fr=(Y-fyp1)*0.02+fyp2;
}
if (Shift.Contains(ssRight)==false && Shift.Contains(ssLeft)==false)
Screen->Cursor=crArrow;
}
//---------------------------------------------------------------------------
AUX_RGBImageRec *LoadBMP(const char *Filename)
{
FILE *File=NULL;
if (!Filename)
{
return NULL;
}
File=fopen(Filename,"r");
if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}
//--------------------------------------------------------------------------
GLuint LoadGLTexture( const char *filename )
{
AUX_RGBImageRec *image;
image=LoadBMP( filename );
GLuint texture=0;
if ( image != NULL && image->data != NULL )
{
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3,image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,image->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
free(image->data);
free(image);
}
return texture;
}
//----------------------------------------------------------------------------
void gosub(void)
{
if (flag1==false && flag2==false && flag3==false)
{
gluLookAt(fl,fr,fbf,fl,fr,fbf+0.00001,0,1,0);
glRotatef(fLookx,0,1,0);
glRotatef(fLooky,1,0,0);
}
if (flag1==true)
{
b=fLooky/700;
le=fLookx/700;
x=0.055*cos(b)*sin(le)*r1;
y=0.055*sin(b)*r1;
z=0.055*cos(b)*cos(le)*r1;
gluLookAt(X1-x+dx,Y1-y+dy,Z1-z+dz,x,y,y,0,1,0);
}
if (flag2==true)
{
b=fLooky/100;
le=fLookx/100;
x=1*cos(b)*sin(le);
y=1*sin(b);
z=1*cos(b)*cos(le);
gluLookAt(X1+dx-x,Y1+dy-y,Z1+dz-z,x,y,z,0,1,0);
}
if (flag3==true)
{
b=fLooky/100;
le=fLookx/100;
x=1*cos(b)*sin(le);
y=1*sin(b);
z=1*cos(b)*cos(le);
gluLookAt(X-x,Y-y,Z-z,x,y,z,0,1,0);
}
}
//-----------------------------------------------------------------------------
void forward(void)
{
// Transform in local ship coordinates
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(pitch, 0.0, 1.0, 0.0);
glRotatef(head, 1.0, 0.0, 0.0);
// Current transform matrix requests
glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPopMatrix();
dx+=gas*m[8];
dy+=gas*m[9];
dz+=gas*m[10];
}
//-----------------------------------------------------------------------------
void backward(void)
{
// Transform in local ship coordinates
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(pitch, 0.0, 1.0, 0.0);
glRotatef(head, 1.0, 0.0, 0.0);
// Current transform matrix requests
glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPopMatrix();
dx-=gas*m[8];
dy-=gas*m[9];
dz-=gas*m[10];
}
//-----------------------------------------------------------------------------
void Fail(char* szMsg)
{
MessageBox(hWnd,szMsg,"",MB_OK);
exit(-1);
}
//-----------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString Text="Herzlich Willkommen!";
agent->Hide();
agent->Show();
agent->MoveToXY(600,300,false);
agent->Play("Greet");
agent->Play("GestureRight");
agent->Speak(Text);
}
//---------------------------------------------------------------------------
Photorealistischer Marsglobus plastisch nach Messungen der Mars Orbiter Laser Altimeter ( MOLA) der NASA.
Download Quelllcode Visual C++ .Net 2003:
http://spaceglobe.diskstation.eu/Pictures1/MarsGlobusVCNet1.zip

Screenshot.
Untergang der Sonne auf dem Planeten Mars (Foto NASA).

Planetare Atmosphäre mittels Texture-Shader gradients and Texture Cloud.

Code C++ Visual Studio 2019.

Code Dark Basic Pro oder neuer AppGameKit Classic/Studio.
Procedural Planets with physically based Light scattering:
C++ Code nach Porcedural Worlds von Sean O'Neil, Construct Developer for Maxis, Inc.