000
13.04.2007, 19:52
Pyro Phoenix
|
Ich versuche grade vergeblich, mir ein 3 Dimensionales Struct Array auf dem Heap zu reservieren ...
Hat jemand ne Idee, wie das geht ?
€dit: Ein Eindimensionales Struckt Array ist mit dem Code kein Problem .. Aber bei 2D fangen die Probleme an
#include <stdio.h> #include <stdlib.h>
typedef struct { unsigned char colIndex; } s_frameData;
s_frameData *p_frameData = NULL;
int main ( void ) { FILE *stream;
if ( ( stream = fopen ( "bhit.spr", "rb" ) ) == NULL ) { return 10; // Kann Datei nicht öffnen } else { fread ( &spriteHeader, sizeof ( d_spriteHeader ), 1, stream ); fread ( &spritePalette, sizeof ( d_spritePalette ), 1, stream ); fread ( &frameType, sizeof ( s_frameType ), 1, stream );
p_frameData = new s_frameData[spriteHeader.numFrames][spriteHeader.height][spriteHeader.width];
for ( int i = 0; (unsigned)i < spriteHeader.numFrames; i++) {
} }
return 0; }
Ergebnis:
error C2540: Kein konstanter Ausdruck als Feldgrenze error C2540: Kein konstanter Ausdruck als Feldgrenze error C2440: '=' : 'struct s_frameData (*)[1][1]' kann nicht in 'struct s_frameData *' konvertiert werden Die Typen, auf die verwiesen wird, sind nicht verwandt; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
--
Dieser Beitrag wurde am 13.04.2007 um 19:57 von Pyro Phoenix bearbeitet.
|
|
Profil || Suche
|
001
13.04.2007, 20:36
HammerBlade
|
Weil das so geht:
s_frameData ***p_frameData = new s_frameData**[spriteHeader.numFrames];
for (int i = 0; i < spriteHeader.numFrames; ++i) { s_frameData[i] = new s_frameData*[spriteHeader.height]; for (int j = 0; j < spriteHeader.height; ++j) { s_frameData[i][j] = new s_frameData[spriteHeader.width]; } }
Und in der Struktur musst du das auch wieder delete[]'ten.
for (int i = 0; i < spriteHeader.numFrames; ++i) { for (int j = 0; j < spriteHeader.height; ++j) { delete[] s_frameData[i][j]; } delete[] s_frameData[i]; }
delete[] s_frameData;
Edit: Ich nehme mal an, dass s_frameData genau ein Pixel in einem Spriteframe darstellt. Ist dir klar, dass es totaler Overkill ist für jedes Pixel ein struct einzeln zu allocaten? Denn an jedem Allocate hängt auch ein Teil Verwaltungsoverhead dran, so dass du da massiv Speicher für diesen Verwaltungsoverhead verschwendest.
Weiterhin nehme ich an du willst auf die Pixel der Frames per 's_frameData[frame][y][x]' zugreifen.
Ausserdem ist es ungünstig ein struct zu nehmen, wenn dort nur der eine uchar drin ist, da kann man auch gleich uchar nehmen, ausser es kommen noch mehr per-Pixel Informationen dazu.
Du solltest das anders machen, z.B. so:
// allocation s_frameData **p_frameData = new s_frameData*[spriteHeader.numFrames];
for (int i = 0; i < spriteHeader.numFrames; ++i) s_frameData[i] = new s_frameData[spriteHeader.height * spriteHeader.width];
// access pixel at <y>,<x> in frame <frame> s_frameData[frame][y * spriteHeader.width + x]
So ist jeder Frame ein Block Speicher und du spartst Verwaltungsoverhead.
Oder vielleicht sogar so:
// allocation s_frameData *p_frameData = new s_frameData[spriteHeader.numFrames * spriteHeader.height * spriteHeader.width];
// access pixel at <y>,<x> in frame <frame> s_frameData[frame * spriteHeader.height * spriteHeader.width + y * spriteHeader.width + x]
--
"Mit C++ (noch besser mit C) kann man sich _sehr_ leicht in den Fuss schiessen." - theDon Auspack und freu! - Auszug aus einer, aus dem japanischen übersetzten, Bedienugsanleitung für ein Spielzeugaquarium. -- Photon Audio Player | Majestic42.net | How To Ask Questions The Smart Way
Dieser Beitrag wurde am 13.04.2007 um 20:58 von HammerBlade bearbeitet.
|
|
Profil || Suche
|
002
13.04.2007, 22:39
Kriz
|
Als Anreiz: In meinem Java Package habe ich das Sprite so definiert:
Sprite (Sammelklasse):
- SpriteHeader - SpritePalette - SpriteFrames[]
Man kann ein Sprite entweder direkt instanzieren (muß es aber dann manuell initialisieren) oder man kann das Sprite mit den statischen Methoden create() oder load() wahlweise erzeugen lassen bzw. laden lassen. Dann werden alle Initialisierungen automatisiert.
Die einzelnen Unterklassen tauschen unter sich die jeweils benötigten Informationen aus, so daß am Ende ein Sprite instanziert worden ist, welches einen gültigen Header, eine gültige Palette und ein Array von gültigen Frames besitzt.
In C wäre dazu beispielsweise der Ansatz sinnvoll:
typedef struct { char *name; // Spritename spriteheader_t header; spritepalette_t palette; spriteframe_t *frames; } sprite_t; Im Java Package habe ich jeder Klasse noch ein ready-to-use Flag mitgegeben. Solange dieses Flag nicht true oder 1 ist, kann ein Objekt der Klasse nicht verwendet werden (z.B. fehlen noch Initialisierungen oder es wurden falsche Werte übergeben usw.). Beim Laden eines Sprites und nach erfolgreichem Testen der geladenen Bytes ist das Objekt dann ready-to-use, beim manuellen Initialisieren muß man eben alles richtig machen, ehe das Flag gesetzt wird. Es ist nämlich nicht sinnvoll, ein Sprite von Hand zu initialisieren und unfertige Objekte (Header, Palette oder einzelne Frames) an das Sprite zu übergeben. Das wird damit konsequent vermieden.
--
K:R-I)Z++ "CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp In memory of Voice ( 2005/03/30)
Dieser Beitrag wurde am 13.04.2007 um 22:40 von Kriz bearbeitet.
|
|
Profil || Suche
|
003
13.04.2007, 23:04
Pyro Phoenix
|
Ahhgrgh ... das is mir momentan noch bissel zu hoch Kannste mir das mal genauer erklären ? ICQ oder so ? (Also nur wenn du Lust & Zeit hast :D )
€dit:
Moment mal ... Mensch bin ich ein b00n :D
Ich bastel mir einfach nen uchar. Und mach mir ein Array draus ( frameData[frame][data] ). [frame] is klar. [data] berechne ich aus width * height ( x*y ). auf die jeweiligen Daten des Frames kann ich dann ganz easy per:
frameData[frame][ ( y * spriteHeader.width ) + x ]
Zugreifen.
Joah darauf muss man erst mal kommen :D
Was jetzt noch offen bleibt:
s_frameData **p_frameData = new s_frameData*[spriteHeader.numFrames];
Die Zeile versteh ich nich so ganz ...
--
Dieser Beitrag wurde am 13.04.2007 um 23:53 von Pyro Phoenix bearbeitet.
|
|
Profil || Suche
|
004
14.04.2007, 02:01
HammerBlade
|
Pyro Phoenix postete Joah darauf muss man erst mal kommen :D
Was jetzt noch offen bleibt:
s_frameData **p_frameData = new s_frameData*[spriteHeader.numFrames];
Die Zeile versteh ich nich so ganz ... Du brauchst einen dynamischen Array von dynamischen Arrays:
// allocation s_frameData **p_frameData = new s_frameData*[spriteHeader.numFrames];
for (int i = 0; i < spriteHeader.numFrames; ++i) s_frameData[i] = new s_frameData[spriteHeader.height * spriteHeader.width];
// access pixel at <y>,<x> in frame <frame> s_frameData[frame][y * spriteHeader.width + x]
Du brauchst also einen Pointer auf einen Array von Pointern. Du allocatest also zu erst einen Array von Pointer auf soviele s_frameData-Pointer wie du Frames hast. Dann allocatest du die Pixel jedes Frames und legste diesen Pointer dann jeweils im Array von Pointern ab.
Beim ** sagt das erste * aus, dass p_frameData ein Pointer sein soll, das zweite Sternchen gehört zum Type den die Elemente des Arrays haben soll (s_frameData Pointer).
--
"Mit C++ (noch besser mit C) kann man sich _sehr_ leicht in den Fuss schiessen." - theDon Auspack und freu! - Auszug aus einer, aus dem japanischen übersetzten, Bedienugsanleitung für ein Spielzeugaquarium. -- Photon Audio Player | Majestic42.net | How To Ask Questions The Smart Way
|
|
Profil || Suche
|
005
14.04.2007, 08:46
Pyro Phoenix
|
Aldah ... jetz bin isch voll krass Checkerbunny. Weissu ?
( Habs kapiert :D )
--
Dieser Beitrag wurde am 14.04.2007 um 08:48 von Pyro Phoenix bearbeitet.
|
|
Profil || Suche
|