Ich hab keine Ahnung, was falsch läuft. Hab das ganze Ding schon mehrmals versucht zu debuggen aber irgendwann kann ich einfach nicht mehr pausieren :doubt:
heightmap.png ist eine Graustufenmap der Grösse 257x257 erstellt mit Earth Sculptor.
DIM terrainArray[1][1]
GF_LoadTerrain("heightmap.png",0)
WHILE TRUE
X_MAKE3D 1,100, 45
X_CAMERA 1,12,10, 0,0,0
X_ROTATION GETTIMERALL()/100, 0,1,0
//X_DRAWOBJ 0,0
SHOWSCREEN
WEND
// datei$ = Graustufen BMP,JPG oder PNG
// num = Nummer des 3D Objekts
// pCross = FALSE: Polygon Strip, TRUE: Crosshair
// qual = -2: 64x64, -1: 128x128, 0: 256x256, 1: 512x512, 2: 1024x1024, 3: 2048x2048
// tMin = niedrigster Punkt des Terrains
// tMax = höchster Punkt des Terrains
//
// Polygon Strip: Crosshair:
// A---C---E X---X---X
// | / | / | | \ | / |
// B---D---F X---X---X
// | / | / | | / | \ |
// X---X---X X---X---X
// ==> Polygon Strip hat die höhere Kompatibilität, Crosshair lässt sich besser optimieren, d.h.
// beim optimieren verliert ein Polygon Strip Patch den mittleren Heightpoint und spart 6 Polygone,
// während ein Crosshair Patch 4 Polygone spart aber den mittleren Heightpoint erhält!
// Polygon Strip: Crosshair:
// X-------X X-------X
// | / | | \ / |
// | / | | X |
// | / | | / \ |
// X-------X X-------X
//
// qual:
// -2 -> 8192 Polygone 1 -> 524288 Polygone = 8192 * 64
// -1 -> 32768 Polygone = 8192 * 4 2 -> 2097152 Polygone = 8192 * 256
// 0 -> 131072 Polygone = 8192 * 16 3 -> 8388608 Polygone = 8192 * 1024
// ==> das bedeutet 1 sehr hochaufgelöstes Terrain kostet soviel Leistung wie 1024 niedrig aufgelöste Terrains!
FUNCTION GF_LoadTerrain: datei$,num,pCross=0,qual=0,tMax=10
GLOBAL gfMode,gfMax,gfQ
LOCAL a,b,color
gfMax = tMax
gfMode = pCross
SELECT qual
CASE -2
gfQ = 65
CASE -1
gfQ = 129
CASE 1
gfQ = 513
CASE 2
gfQ = 1025
CASE 3
gfQ = 2049
DEFAULT
gfQ = 257
ENDSELECT
REDIM terrainArray[gfQ][gfQ]
LOADSPRITE datei$,0
STRETCHSPRITE 0,0,0,gfQ,gfQ
FOR a = 0 TO gfQ-1
FOR b = 0 TO gfQ-1
color = GETPIXEL(a,b)
terrainArray[a][b] = color/RGB(255,255,255)*gfMax
NEXT
NEXT
GF_CreateTerrain(num)
ENDFUNCTION
// Die Funktion, die das Terrain erst erstellt
@FUNCTION GF_CreateTerrain: num
X_OBJSTART num
FOR a = 0 TO gfQ-3 STEP 2
FOR b = 0 TO gfQ-3 STEP 2
GF_BuildPatch(num,a,b)
NEXT
NEXT
X_OBJEND
ENDFUNCTION
//Diese Funktion erstellt die einzelnen Patches bestehend aus je 8 Polygonen
@FUNCTION GF_BuildPatch: num,currentX,currentZ
X_OBJADDVERTEX currentX ,terrainArray[currentX][currentZ] ,currentZ ,currentX/gfQ ,currentZ/gfQ ,RGB(255,255,255)
X_OBJADDVERTEX currentX ,terrainArray[currentX][currentZ+1] ,currentZ+1,currentX/gfQ ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+1,terrainArray[currentX+1][currentZ] ,currentZ ,(currentX+1)/gfQ,currentZ/gfQ ,RGB(255,255,255)
X_OBJADDVERTEX currentX+1,terrainArray[currentX+1][currentZ+1],currentZ+1,(currentX+1)/gfQ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+2,terrainArray[currentX+2][currentZ] ,currentZ ,(currentX+2)/gfQ,currentZ/gfQ ,RGB(255,255,255)
X_OBJADDVERTEX currentX+2,terrainArray[currentX+2][currentZ+1],currentZ+1,(currentX+2)/gfQ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJNEWGROUP
X_OBJADDVERTEX currentX ,terrainArray[currentX][currentZ+1] ,currentZ+1,currentX/gfQ ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX ,terrainArray[currentX][currentZ+2] ,currentZ+2,currentX/gfQ ,(currentZ+2)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+1,terrainArray[currentX+1][currentZ+1],currentZ+1,(currentX+1)/gfQ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+1,terrainArray[currentX+1][currentZ+2],currentZ+2,(currentX+1)/gfQ,(currentZ+2)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+2,terrainArray[currentX+2][currentZ+1],currentZ+1,(currentX+2)/gfQ,(currentZ+1)/gfQ,RGB(255,255,255)
X_OBJADDVERTEX currentX+2,terrainArray[currentX+2][currentZ+2],currentZ+2,(currentX+2)/gfQ,(currentZ+2)/gfQ,RGB(255,255,255)
X_OBJNEWGROUP
ENDFUNCTION
[attachment deleted by admin]
Oh mann. Ich kapier bei deinem Code quasi 0.
Warum gibtst Du statt "qual" nicht einfach breite+höhe (Anzahl der Quads rechts/unten) an?
Dein Fehler ist aber warscheinlich hier:
color = GETPIXEL(a,b)
terrainArray[a] = color/RGB(255,255,255)*gfMax
height = bAND(color, 0x00ff00) / 255.0 * gfMax
Wieso sollte der Fehler dort liegen?
color/RGB(255)*gfMax skaliert den Wert von gfMax zwischen 0.0 und 1.0 (color ist ein Wert zwischen RGB(0,0,0) und RGB(255,255,255). Weiss (=RGB(255,255,255)) markiert die höchsten Punkte im Terrain, d.h. weiss muss 1.O * Maximale Höhe (=gfMax) sein).
Das Programm läuft solange gut, bis ich versuche das Terrain zusammenzusetzen.
Kommentier mal GF_CreateTerrain(num) in der Funktion GF_LoadTerrain aus. Sollte dann laufen, aber natürlich sieht man nix weil das Mesh nicht zusammengesetzt wird... :doubt:
Macht das bitte fertig. Vielleicht ist das die Lösung für mein Problem!!!!!!!!
Möchte das fertige Programm ungedingt ausprobieren!!!
Ich WILL es ja fertig machen, ich weiss nur nicht, wo der Fehler liegt. Ich würde das Problem beim Konstruieren des 3D Modells vermuten, aber ohne Hilfe komme ich da nicht weiter.
Nein, weiß = RGB(0xff, 0xff,0xff ) = 0xffffff
AAABER! Du kannst net linear interpolieren!
Grün = 0x00ff00, rot=0x0000ff
also darfst Du nur eine Farbkomponente ansehen. z.B. Grün.
Hmm, ok.
Aber es funktioniert trotzdem nicht =(
Ich vermute stark, dass es beim Erstellen des 3D Objekts hakt, aber ich weiss nicht wo :rant:
Sorry, ich hab' bei Deinem Code nicht durchgeblickt...
DIM terrainArray[1][1]
MakeHeightMap("heightmap.png",0, 9, 64, 1, 1)
WHILE TRUE
DRAWRECT 0,0,1000,1000,RGB(0x80, 0x80, 0xff)
X_MAKE3D 1,5000, 45
X_CAMERA 0,10,25, 0,5,0
X_AMBIENT_LT 1, RGB(255,255,255)
X_ROTATION GETTIMERALL()/10, 0,1,0
X_SETTEXTURE -1, -1
X_DRAWOBJ 0,0
SHOWSCREEN
WEND
// ------------------------------------------------------------- //
//! Makes a Heightmap from a grayscale image
// \param file$ - the file name
// \param id_ddd - object id to create
// \param max_height - hieght for pixel color RGB(0xff, 0xff, 0xff)
// \param resolution - number of "blocks" in x and y direction (should be modified better for non-square terrains?)
// \param sc - scale of X and Z for each tile (1 would be a resolution x resolution units map)
// \param ft - number of texture wraps for each tile (might be buggy, I didn't test)
// ------------------------------------------------------------- //
FUNCTION MakeHeightMap: file$, id_ddd, max_height=0, resolution=64, sc=1, ft=1
LOCAL mvx, mvy, x, y, col
LOCAL Height[]
LOADSPRITE file$, 0 // shoulod be dynamically or something...
// Make height - "field"
STRETCHSPRITE 0, 0,0,resolution, resolution
DIM Height[resolution][resolution]
FOR x=0 TO resolution-1
FOR y=0 TO resolution-1
Height[x][y] = bAND(GETPIXEL(x,y),0x00ff00)/0x00ff00*max_height
NEXT
NEXT
col=RGB(255,255,255)
mvx = sc * BOUNDS(Height[],0) / 2 // movement, so 0,0 is the center
mvy = sc * BOUNDS(Height[],1) / 2
X_AUTONORMALS 2 // smoooooooth
// now loop through each Height[] index and make a
// node for the mesh at that point
X_OBJSTART id_ddd
FOR x=0 TO BOUNDS(Height[],0)-2
X_OBJNEWGROUP
// x, 1
X_OBJADDVERTEX x*sc-mvx, Height[x][1], 1*sc-mvy, ft*x, ft, col
FOR y=1 TO BOUNDS(Height[],1)-2
// x+1, y
X_OBJADDVERTEX (x+1)*sc-mvx, Height[x+1][y], y*sc-mvy, ft*(x+1), ft*y, col
// x, y+1
X_OBJADDVERTEX x*sc-mvx, Height[x][y+1], (y+1)*sc-mvy, ft*x, ft*(y+1), col
NEXT
// x+1, y
X_OBJADDVERTEX (x+1)*sc-mvx, Height[x+1][y], y*sc-mvy, ft*(x+1), ft*y, col
NEXT
X_OBJEND
ENDFUNCTION // DRAWMAP
Danke Gernot. Dein Code funktioniert und ich werde versuchen darauf aufzubauen.
Denn leider skaliert das noch falsch. Das Terrain sieht nicht wirklich aus wie in Earth Sculptor, mal sehen was man da noch schrauben kann (max_heigt bringt gar nichts, ob jetzt 10,100 oder 100000, sieht immer gleich aus).
Und Bumpmapping funktioniert auf dem Terrain nicht (hab die Heightmap als Bumpmap benutzt, wenn man das macht, dass wird nur etwa 1/4 des Terrains angezeigt).
Uuuuuuund ich habe beim 3D Erstellungscode noch die Texturkoordinaten angepasst (ft und sc scheinen nicht wirklich etwas zu bewirken).
ABER VIELEN DANK! Dein Code ist ein super Startpunkt nachdem ich irgendwie gescheitert bin. :nw:
Edit: ok, Asche auf mein Haupt, max_heigt funktioniert wunderbar! Bumpmapping zwar tatsächlich nicht, aber max_height schon. Meine Höhenberechnung funktioniert übrigens auch :P
Hier mal ein Shot vom bisherigen Loader, der noch in weiten Teilen auf Gernots Code basiert:
[attachment deleted by admin]
Hammer geil Sebastian! :booze:
Haste da ne Shadowmap drauf?
Danke, aber vergiß nicht, Gernot auch zu loben!
Bzgl. Shadowmap: ja, Earthsculptor speichert die Textur und Shadowmap als eine Datei ab. Tests mit Stencilschatten kommen später, wenn ich den Loader soweit habe, dass er meinen Vorstellungen (;)) entspricht.
@Gernot und Sebastian
Macht ihr echt super, muß ich schon sagen. :good:
Cheers
Wow, schaut super aus!
Wann gibt's denn das schöne Ding zum runter laden? *hoff*
Schon längst, zumindest die interaktive demo (3d snippets)
Oh Mann, das ist genial!!! Danke! :nw:
Excellent stuff, danke! :D