Registriert: Fr Mai 14, 2004 18:56 Beiträge: 804 Wohnort: GER/OBB/TÖL-WOR/Greiling
Code:
procedure SceneRender(map:TMap);
var i,k:integer;
value:integer;
HM:THeightMap;
begin
setlength(HM,map.HeightMap.Width);//
for i:=0tohigh(HM)do// Heightmap-Array initialisieren
setlength(HM[i],map.HeightMap.Height);//
for i:=0to map.HeightMap.Widthdo
for k :=0to map.HeightMap.Heightdo
begin
value:=map.HeightMap.Canvas.Pixels[i,k];
HM[i,k]:=hextoint(copy(inttohex(value,6),0,2))div10;// HIER DER FEHLER
//^Rot-Wert wird zur Höhe^
end;
glbegin(GL_TRIANGLE_STRIP);
glvertex3i(0,HM[0,0],0);
glvertex3i(0,HM[0,1],1);
glvertex3i(1,HM[1,1],1);
for i:=1tohigh(HM)do//hier natürlich auch fehler.....
for k:=0tohigh(HM[0])div2do//nur alle 2 zeilen neuen tri-strip!
begin
glvertex3i(i,HM[i,k],k);
glvertex3i(i+1,HM[i+1,k+1],k+1);// ...wegen dem i+1 hier.
end;
glend;
end;
ich benutze diese prozedur, um eine heightmap aus den rot-werten eines Bitmap zu laden.
sobald ich sie aufrufe, wirft er mit eine access violation in der oben markierten zeile vor(die selbstgeschriebene hextoint-funktion funktioniert, hab ich ausgiebig getestet.). es muss ja so sein, dass mein array HM noch nicht lang genug ist. aber ich initialisiere ihn ja in den drei zeilen ganz am anfang. sogar mit einem element overhead. wo liegt mein fehler bzw. gibt es einen?
mfg
luke
edit:attachment gelöscht, weil problem behoben.
_________________
"User Error. Replace User and hit Continue."
Zuletzt geändert von luketheduke am Di Feb 22, 2005 15:46, insgesamt 1-mal geändert.
Registriert: Fr Nov 12, 2004 14:58 Beiträge: 76 Wohnort: Aachen
Servus,
wenn THeightMap lediglich ein Dynamisches 2D Array ist, dann ist der Fehler relativ einfach: Du läufst genau um eines über Deine Array-Grenze hinaus.
Code:
setlength(HM,map.HeightMap.Width);//
for i:=0tohigh(HM)do// Heightmap-Array initialisieren
setlength(HM[i],map.HeightMap.Height);//
Hier funktioniert es, weil Du mit High(HM) die obere Grenze abfragst.
Code:
for i:=0to map.HeightMap.Widthdo
for k :=0to map.HeightMap.Heightdo
begin
value:=map.HeightMap.Canvas.Pixels[i,k];
HM[i,k]:=hextoint(copy(inttohex(value,6),0,2))div10;// HIER DER FEHLER
//^Rot-Wert wird zur Höhe^
end;
Hier funktioniert es nicht mehr. Dein Array geht ja nur (per Definition der Dynamischen Arrays) von 0..Width-1 resp. Height-1, da Du ja Width resp. Height Elemente anforderst.
Damit es also funktioniert, mußt Du Deine Schleife wie folgt schreiben:
Code:
for i :=0to map.HeightMap.Width-1do
for k :=0to map.HeigtMap.Height-1do
[...]
oder Du arbeitest wieder mit Low(HM) resp. High(HM) wie oben auch schon.
Grüße
Wolf
_________________ Ein Schiff im Hafen ist sicher. Aber dafür werden Schiffe nicht gebaut. (Engl. Sprichwort)
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Genau. Blechwolf war schneller. Ich habe aber noch ein paar andere Sachen.
Das initialisieren des 2D Array kannst du auch mittels SetLength(HM, Width, Height); erledigen. Geht einfacher und wahrscheinlich auch noch schneller.
Das Extrahieren des Rotanteiles mittels Stringoperationen ist die wohl schlechteste Möglichkeit das zu machen. Also lass das!
Viel einfacher ist er in dem du einfach den entsprechenden Wert aus dem Integer extrahierst. Das geht in dem du die Methode GetRValue aufrufst oder in dem du Value and $FF machst. Das Ergebnis ist ein Byte welches nur die letzten 8 Bits beinhält. Dazu sind absolut keine Stringoperationen nötig.
PS: Das Div 10 bei der Höhe würde ich weglassen und anstelle die Ausgabe in OpenGL um den Faktor 10 kleiner machen. Dabei hast du dann eine höhere Genauigkeit und die Größe bleibt auch gleich.
Registriert: Fr Mai 14, 2004 18:56 Beiträge: 804 Wohnort: GER/OBB/TÖL-WOR/Greiling
aaahh....... *Anfängerfehler *
EDIT: es geht jetzt sogar... hatte übrigens das ganze nochmal in der oben markierten zeile.
EDIT2: jetzt bräuchte ich noch was, damit ich die dreiecke umranden kann. geht das einfach? ich kann auf jeden fall gl_lines oder so hernehmen. aber das ist ja blöd, wenn ich dann ne komplette renderschleife brauch.
edit3: ich habs einfach gemacht. und siehe da - das erste brauchbare ergebnis!
danke für alles!
EDIT4: @lossy: ausgabe um 10 kleiner machen: das heisst, im glvertex-befehl durch 10 teilen? oder glscale?
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Registriert: Fr Mai 14, 2004 18:56 Beiträge: 804 Wohnort: GER/OBB/TÖL-WOR/Greiling
*sry für doppelpost*
ich steh grad auf dem schlauch....
nochmal mein rendervorgang:
Code:
glbegin(GL_TRIANGLE_STRIP);
glcolor3f(0,1,0);
glvertex3i(0,HM[0,0],0);
glvertex3i(0,HM[0,1],1);
glvertex3i(1,HM[1,1],1);
for i:=1tohigh(HM)-1do
for k:=0tohigh(HM[0])div2do//nur alle 2 zeilen neuen tri-strip!
begin
glcolor3f(0,HM[i,k]/2.55,0);
glvertex3i(i,HM[i,k],k);
glvertex3i(i+1,HM[i+1,k+1],k+1);
end;
glend;
damit wird natürlich nur die hälfte meiner karte gerendert,. wie schaffe ich es jetzt, durch mein ganzes array zu kommen, ohne irgendwelche kalamitäten?
wenn ich das div 2 einfach weglasse, geht es ja auch nicht.
ps: im guten alten QBasic hätt mich das nur ein kleines
zwei möglichkeiten: die for schleeifen durch while schleifen ersetzen oder beim zugriff aufs array die zugriffsvariable mit 2 multiplizieren. schneller sit die variante mit dem while.
Registriert: Fr Mai 14, 2004 18:56 Beiträge: 804 Wohnort: GER/OBB/TÖL-WOR/Greiling
while: schon mal versucht. da muss ich aber soviel hirnen . am besten from the scrap neumachen, den code im ersten post umschreiben schaff ich sowieso nicht....
mit zwei multiplizieren: schon probiert, aber wohl n bisschen zu dilettantisch -> eine Accessviolation nach der anderen.
und ich sehe dem programm sogar bei kurzem ansehen an, warum dem so ist...
glvertex3i(i+1,HM[i+1,k+1],k+1);
wenn du immer auch auf die nexten vertices zugreifst, dann darfst du nicht mit deiner for schleife bis zu den letzten vertices hintergehen, weil du dann immernoch eines weiter nach vorne greifst - und damit raus aus den arraygrenzen. also bei den schleifen noch einen weiteren index abziehen. sonst kann man, wenn man das noch nicht aus dem stehgreif sieht, auch den debugger benutzen. und damit es nicht jedesmal erklärt werden muss, habe ich einst auch mal ein tutorial dazu geschrieben: http://www.delphigl.com/script/do_show. ... r&action=2 schaus dir an, evtl kommst du danach besser zurecht.
edit: und noch ein kleiner tipp zum übersetzen von for in while:
Code:
for i := a to b do
ist
Code:
i := a;
while i <= b do
begin
...
i := i + 1;
end;
udn mit zweiersteps entsprechend i := i + 1 in i := i + 2 wechseln.
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.