So habe ich schließlich einen Weg gefunden mittels Speichermanipulation 3D-Objekte zu erzeugen. Leider hat die Sache im Moment noch ein paar Haken.
Beispielsweise ist die Darstellung nur im Modus #PB_Camera_Wireframe korrekt. Ausserdem stürzt das fertige Programm immer sofort ab, obwohl es in PureBasic noch fehlerfrei läuft.
Die zugehörige Fehlerquelle habe ich bisher leider noch nicht finden können.
Code: Alles auswählen
Global Term.s
Global Function
MaxF=11 ;Maximale Anzahl der Funktionen
Function=Random(MaxF) ;Startfunktion per Zufall auswählen
Procedure.d Function(x.d,y.d)
Select Function
Case 0
Erg.d=Cos(Sqr(x*x+y*y))*8*Pow(0.9,x*x+y*y)
Term="f(x,y) = Cos(Sqr( x² + y² )) * 8 * 0,9^( x² + y² )"
Case 1
Erg.d=x*y/2
Term="f(x,y) = x * y / 2"
Case 2
Erg.d=Sqr(16-x*x-y*y)
Term="f(x,y) = Sqr( 16 - x² - y²)"
Case 3
Erg.d=x*x+y*y-4
Term="f(x,y) = x² + y² - 4"
Case 4
Erg.d=Cos(1/(x*y))
Term="f(x,y) = Cos( 1 / ( x * y ))"
Case 5
Erg.d=Sin(1/Sqr(x*x+y*y))
Term="f(x,y) = Sin( 1 / Sqr( x² + y² ))"
Case 6
Erg.d=Cos(x)*Sin(y)
Term="f(x,y) = Cos( x ) * Sin( y )"
Case 7
Erg.d=Cos(Sqr(x*x*y*y))
Term="f(x,y) = Cos(Sqr( x²y² ))"
Case 8
Erg.d=Log(Sqr(x*x*y*y)+0.125)
Term="f(x,y) = Log(Sqr( x²y² ) + 0,125 )"
Case 9
Erg.d=ATan(x*y)
Term="f(x,y) = ATan( x * y )"
Case 10
Erg.d=1/(Pow((Abs(x)-0.5),2)+Pow((Abs(y)-0.5),2)+0.125)
Term="f(x,y) = 1/( |x-0,5|² + |y-0,5|² + 0,125 )"
Case 11
Erg.d=Log(y+4)/Log(2)+Cos(x*#PI)
Term="f(x,y) = Log2( y + 4 ) + Cos( x * "+StrD(#PI,5)+" )"
EndSelect
ProcedureReturn Erg
EndProcedure
Procedure GetColor(Vertex.d) ;Prozedur zur Farbgebung der Scheitel
;Achtung: nicht RGB-, sondern BGR-codiert!!!! -> alle R- bzw. B-Werte vertauscht
Vertex=-Vertex
If Vertex>4
Color.l=RGB(Round(255-255/(Vertex-3),0),Round(255-255/(Vertex-3),0),255)
ElseIf Vertex<=4 And Vertex>=-4
Int.l =Round(255*(Vertex+4)/8,0)
Group.l=Round(Int/51,0)
Select Group
Case 0 ;magenta->blau
Color.l=RGB(255,0,255-5*Int)
Case 1 ;blau->cyan
Color.l=RGB(255,5*(Int-51),0)
Case 2 ;cyan->grün
Color.l=RGB(255-5*(Int-102),255,0)
Case 3 ;grün->gelb
Color.l=RGB(0,255,5*(Int-153))
Case 4 ;gelb->rot
Color.l=RGB(0,255-5*(Int-204),255)
EndSelect
ElseIf Vertex<-4
Color.l=RGB(Round(255/(-3-Vertex),0),0,Round(255/(-3-Vertex),0))
EndIf
ProcedureReturn Color
EndProcedure
Procedure Create3DData(Columns.l,Rows.l,MinX.d,MinY.d,MaxX.d,MaxY.d)
*Vertexes=AllocateMemory(16*(Columns+1)*(Rows+1)) ;Speicher für alle Scheiteldaten reservieren
PVertex=*Vertexes ;Pointer auf Anfang setzen
StepX.d=(MaxX-MinX)/Columns ;Schrittweite in X-Richtung
StepY.d=(MaxY-MinY)/Rows ;Schrittweite in Y-Richtung
For py=0 To Rows
For px=0 To Columns
x.d=MinX+StepX*px ;mathematisches x berechnen
y.d=MinY+StepY*py ;mathematisches y berechnen
Vertex.d=-Function(x,y) ;z=f(x,y) berechnen
Color=GetColor(Vertex) ;Scheitelfärbung vornehmen
PokeF(PVertex,(px*400/Columns)-200):PVertex+4 ;X-Koordinaten in Speicher schreiben
PokeF(PVertex, -50*Vertex ):PVertex+4 ;Z-Koordinaten in Speicher schreiben
PokeF(PVertex,(py*400/Rows) -200):PVertex+4 ;Y-Koordinaten in Speicher schreiben
PokeL(PVertex,Color):PVertex+4 ;Farbwert in Speicher schreiben
Next px
Next py
ProcedureReturn *Vertexes
EndProcedure
Columns=160 ;Spalten
Rows=160 ;Zeilen
p=0
Dim NBVertex(Columns,Rows)
For y=0 To Rows
For x=0 To Columns
NBVertex(x,y)=p
p+1
Next x
Next y
#Mesh=0
#Material=0
#Entity=0
#Camera=0
*CornerData=AllocateMemory(12*Columns*Rows) ;pro "Kästchen" 2 Dreiecke à 3 Word Daten -> 12 Bytes pro "Kästchen"
InitEngine3D()
InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0,0,0,600,450,"3D-Funktionen",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,600,450,0,0,0)
CreateMesh(#Mesh,(Columns+1)*(Rows+1))
CreateTexture(0,256,256)
SetMeshData(#Mesh,#PB_Mesh_Vertex|#PB_Mesh_Color,Create3DData(Columns,Rows,-4,-4,4,4),(Columns+1)*(Rows+1))
CData=0
Pointer=*CornerData
For y=0 To Rows-1
For x=0 To Columns-1
PokeW(Pointer,NBVertex(x ,y )):Pointer+2 ; *--*
PokeW(Pointer,NBVertex(x+1,y )):Pointer+2 ; | /
PokeW(Pointer,NBVertex(x ,y+1)):Pointer+2 ; *
CData+1
PokeW(Pointer,NBVertex(x+1,y )):Pointer+2 ; *
PokeW(Pointer,NBVertex(x ,y+1)):Pointer+2 ; / |
PokeW(Pointer,NBVertex(x+1,y+1)):Pointer+2 ; *--*
CData+1
Next x
Next y
SetMeshData(#Mesh,#PB_Mesh_Face,*CornerData,CData)
StartDrawing(TextureOutput(0))
Box(0,0,256,256,16777215)
StopDrawing()
CreateMaterial(#Material,TextureID(0))
CreateEntity(#Entity,MeshID(#Mesh),MaterialID(#Material))
MaterialAmbientColor(#Material,#PB_Material_AmbientColors)
MaterialSpecularColor(#Material,16777215)
CreateLight(0,16777215,0,0,0)
LightSpecularColor(0,16777215)
CreateCamera(#Camera,0,0,100,100)
CameraLocate(#Camera,0,0,707)
RotateCamera(#Camera,0,0,180)
CameraBackColor(#Camera,$000000)
CameraRenderMode(#Camera,#PB_Camera_Wireframe)
Fog($000000,1,500,1000)
chv=700
crl=0
cou=0
vrl=0
vou=0
Repeat
ExamineKeyboard()
event=WindowEvent()
ClearScreen(0)
If KeyboardPushed(#PB_Key_Left) ;Kamera links drehen
vrl+1:If vrl>359:vrl=0:EndIf
ElseIf KeyboardPushed(#PB_Key_Right) ;Kamera rechts drehen
vrl-1:If vrl<0:vrl=359:EndIf
EndIf
If KeyboardPushed(#PB_Key_Up) ;Kamera nach oben drehen
vou+1:If vou>359:vou=0:EndIf
ElseIf KeyboardPushed(#PB_Key_Down) ;Kamera nach unten drehen
vou-1:If vou<0:vou=359:EndIf
EndIf
If KeyboardPushed(#PB_Key_PageUp) ;Kamera höher verschieben
cou+10:If cou>1000:cou=1000:EndIf
ElseIf KeyboardPushed(#PB_Key_PageDown) ;Kamera niedriger verschieben
cou-10:If cou<-1000:cou=-1000:EndIf
EndIf
If KeyboardPushed(#PB_Key_A) ;Kamera nach links verschieben
crl-10:If crl<-1000:crl=-1000:EndIf
ElseIf KeyboardPushed(#PB_Key_D) ;Kamera nach rechts verschieben
crl+10:If crl>1000:crl=1000:EndIf
EndIf
If KeyboardPushed(#PB_Key_W) ;Kamera räumlich weiter in den Hintergrund
chv-10:If chv<-1000:chv=-1000:EndIf
ElseIf KeyboardPushed(#PB_Key_S) ;Kamera räumlich weiter in den Vordergrund
chv+10:If chv>1000:chv=1000:EndIf
EndIf
If KeyboardPushed(#PB_Key_L) ;Kamera zurücksetzen
chv=700
crl=0
cou=0
vrl=0
vou=0
EndIf
If KeyboardPushed(#PB_Key_O) ;Kamera auf Koordinatenursprung (0|0|0) setzen
chv=0
crl=0
cou=0
vrl=0
vou=0
EndIf
If KeyboardPushed(#PB_Key_C) ;Funktion wechseln
Function=Random(MaxF)
SetMeshData(#Mesh,#PB_Mesh_Vertex|#PB_Mesh_Color,Create3DData(Columns,Rows,-4,-4,4,4),(Columns+1)*(Rows+1))
EndIf
If KeyboardPushed(#PB_Key_K)
Function+1:If Function>MaxF:Function=0:EndIf
SetMeshData(#Mesh,#PB_Mesh_Vertex|#PB_Mesh_Color,Create3DData(Columns,Rows,-4,-4,4,4),(Columns+1)*(Rows+1))
EndIf
If KeyboardPushed(#PB_Key_J)
Function-1:If Function<0:Function=MaxF:EndIf
SetMeshData(#Mesh,#PB_Mesh_Vertex|#PB_Mesh_Color,Create3DData(Columns,Rows,-4,-4,4,4),(Columns+1)*(Rows+1))
EndIf
CameraLocate(#Camera,crl,cou,chv)
CameraLookAt(#Camera,crl,cou,chv-100)
RotateCamera(#Camera,vrl,vou,0)
LightLocate(0,crl,cou,chv)
RenderWorld()
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_Outlined)
FrontColor(16777215)
BackColor(0)
Box(06,09,290,41)
DrawText(10, 10,"Funktion "+Str(Function+1)+":")
DrawText(10, 30,Term)
Box(06,52,90,80)
DrawText(10, 53,"Kamera:")
DrawText(10, 73,"X: "+StrD(crl/50,1))
DrawText(10, 93,"Y: "+StrD(chv/50,1))
DrawText(10,113,"Z: "+StrD(cou/50,1))
Box(06,135,90,60)
DrawText(10,136,"Blickwinkel:")
DrawText(10,156,"X: "+Str(vou%360)+"°")
DrawText(10,176,"Z: "+Str(vrl%360)+"°")
Box(06,198,90,20)
DrawText(10,199,Str(Engine3DFrameRate(#PB_Engine3D_Current))+" FPS")
Box(299,200,2,50)
Box(275,224,50,2)
StopDrawing()
FlipBuffers()
Delay(15)
Until event=#PB_Event_CloseWindow