Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

16.06.2010, 14:31

Texturen erstellen mit OpenGL/ Direct3D9

Hallo,
ich arbeite nun schon recht lange mit OpenGL, mit Direct3D9 noch nicht ganz so lange, und ich muss sagen, Texturen 100%ig korrekt zu erstellen, ist gar nicht so einfach.
Zumindest wenn man in seiner eigenen 3D Engine ein möglist großes Spektrum an Texture-Typen bereit stellen will, sprich 1D/2D/3D Texturen, Tiefen Texturen, CubeMaps usw.
Mit OpenGL komme ich da schon ganz gut mit zurecht, aber mein Direct3D9 VideoDriver will noch nicht so ganz.
z.B. wirft folgender Code immer einen Fehler aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
IDirect3DTexture9* d3dTexture = 0;

D3DFORMAT d3dFormat = D3DFMT_D32; // Format fuer eine Depth-Texture
DWORD d3dUsage = D3DUSAGE_DEPTHSTENCIL;
bool MipMaps = true;
int Width = 256, Height = 256;

HRESULT d3dError = pDirect3DDevice_->CreateTexture(
    Width
    Height,
    MipMaps ? 0 : 1,
    d3dUsage | (MipMaps ? D3DUSAGE_AUTOGENMIPMAP : 0),
    d3dFormat,
    D3DPOOL_MANAGED,
    &d3dTexture,
    0
);

if (d3dError)
    MessageBox(0, TEXT("Could not create Direct3D9 texture"), TEXT("Error"), MB_OK | MB_ICONERROR); // Kommt leider immer, wenn ich ein anderes Format as "D3DFMT_A8R8G8B8" nehme :-(

Kann mir erst mal einer sagen, warum das nicht funktioniert? (später frag ich auch noch mehr zu OpenGL :-D)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »LukasBanana« (16.06.2010, 15:13)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

16.06.2010, 15:43

Du kannst mit D3D9 nicht so einfach eine Textur mit dem Format eines Depth Buffers erstellen. Das geht dort nur mit treiberspezifischem FOURCC. Vor allem aber kannst du eine Textur nicht als Depth Buffer verwenden. Dazu brauchst du eine DepthStencil Surface die du entsprechend mit CreateDepthStencil Surface erstellst. Außerdem würd ich mir überlegen ob du D3DUSAGE_AUTOGENMIPMAP wirklich immer haben willst (meistens nämlich wohl eher nicht) und ob du wirklich immer nur einen Mip Level willst...

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

17.06.2010, 11:43

Nun gut, wie sieht es dann mit OpenGL aus? (Die Fragen habe ich in den Kommentaren geschrieben)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
glTexImage2D(
    GL_TEXTURE_2D,
    0, // (MIP-Level)
    GL_DEPTH_COMPONENT, // Hier setzte ich normaler Weise immer nur 1, 2, 3 oder 4 ein. Wann muss man hier die GL macros verwenden??
    Width,
    Height,
    0, // (Border)
    GL_LUMINANCE, // Was muss ich hier als Format nehmen, damit ich eine TiefenTexture bekommen??
    GL_UNSIGNED_BYTE,
    ImageBuffer // (unisgned char* ImageBuffer)
);

Wie in den Kommentaren beschrieben, schreibe ich in das "InternalFormat" normaler Weise immer nur wie viel Byte ein Pixel groß ist (1, 2, 3, oder 4).
Ab wann wird es wichtig, dass man die OpenGL macros (z.B. GL_RGB oder GL_DEPTH_COMPONENT) verwendet?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

17.06.2010, 12:09

Ab wann wird es wichtig, dass man die OpenGL macros (z.B. GL_RGB oder GL_DEPTH_COMPONENT) verwendet?

Das sollte man eigentlich immer machen da man nur so wirklich Kontrolle über die Formate hat (eigentlich wäre sogar GL_RGB noch zu wenig, normalerweise würde man z.B. GL_RGBA8 verwenden). Das internal Format ist das Format in dem die Textur im Grafikspeicher abgelegt wird, der Parameter format ist nur das Format in dem die Daten in dem übergebenen Buffer sind.
Als internal Format würde ich in deinem obigen Fall GL_DEPTH_COMPONENT16 oder GL_DEPTH_COMPONENT24 verwenden (je nachdem welche Genauigkeit du willst) und als Format GL_DEPTH_COMPONENT.
Wenn du vorhast diese Textur als Depth Buffer zu verwenden dann musst du dazu Frame Buffer Objects verwenden.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (17.06.2010, 12:16)


LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

5

17.06.2010, 12:27

Welches InternalFormat muss ich dann nehmen wenn ich für Format GL_COLOR_INDEX oder GL_RED nehme? Das finde ich nämlich nicht in der List für InternalFormat

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

17.06.2010, 12:34

Hast du wirklich vor indizierte Farben zu verwenden? Wenn ja, warum? Aber gut, da müsste ich jetzt selbst googlen da ich das ehrlich gesagt noch nie verwendet hab. Ich würde mal schätzen dass man diesem Fall aber wohl einfach eine 1 nimmt...

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (17.06.2010, 12:43)


LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

7

17.06.2010, 12:47

Ich möchte einfach möglichst viele PixelFormate in meiner 3D Engine zur Verfügung stellen =)
Gibt's auch sowas wie eine Stencil Texture? In Direct3D9 gibt's das afaik. Ich vermute mal, dass das auch wirgendwie über GL_DEPTH_COMPONENT läuft.

Edit by dot: sry hab statt dem Zitat den Bearbeiten Button erwischt -.-

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (17.06.2010, 13:04)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

17.06.2010, 13:05

Ich möchte einfach möglichst viele PixelFormate in meiner 3D Engine zur Verfügung stellen =)

Dann sei dir verraten dass es sich bei indizierten Farben um so Zeug handelt wie z.B. das was früher mal als "256 Farben" herumgegeistert ist. Wenn ich das hier grad richtig interpretier dann unterstützen Grafikkarten die jünger sind als eine GeForce 6 (2004) das nichtmal mehr.
Wenn du nicht grad für Voodoo 2 class Hardware programmierst ist das total uninteressant...
Also glaub mir: Das brauchst du nicht.

Gibt's auch sowas wie eine Stencil Texture? In Direct3D9 gibt's das afaik. Ich vermute mal, dass das auch wirgendwie über GL_DEPTH_COMPONENT läuft.

Dass es sowas in D3D9 geben soll hör ich ehrlich gesagt zum ersten Mal und da es in D3D9 nichtmal Depth Texturen gibt würd ich mal stark davon ausgehen dass es erst recht keine Stencil Texturen gibt. Mir sind auch keine Driverhacks diesbezüglich bekannt, wobei ich das jetzt auch noch nie gebraucht hätte...
Laut dem obigen Link unterstützen NVIDIA Karten ab GeForce 8 scheinbar Texturen mit einem DepthStencil Format. Wie man das dann verwendet hab ich zugegebenermaßen keine Ahnung.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

9

17.06.2010, 13:21

Ok, danke schon mal für deine Hilfe :-).

Aber noch mal zu den OpenGL DepthTextures. Hier ist mein Code, der leider nicht funktioniert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GLuint DepthTexID;
glGenTextures(1, &DepthTexID);
glBindTexture(GL_TEXTURE_2D, DepthTexID);
glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0 // Float da Tiefen-Informationen in 4 byte floating-point genauer sind und 0 als ImageBuffer da es ja als FrameBufferObject genutzt wird
);

glGenFramebuffersEXT(1, &FrameBufferID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FrameBufferID);

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, DepthTexID, 0); // Das funktioniert bei mir nur mit GL_COLOR_ATTACHMENT0_EXT
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, DepthBufferID);

glGenRenderbuffersEXT(1, &DepthBufferID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthBufferID);

glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, Width, Height);

Ich seh nur eine schwarze (also leere) Texture und bekomme in meinem LogFile immer irgendwelche Fehlermeldungen.
Je nach dem was ich weglasse oder nicht "attache".

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

17.06.2010, 14:00

Hm ok. Also erstmal: Deine Grafikkarte unterstützt vermutlich sowieso nur GL_DEPTH_COMPONENT24 d.h. auch wenn du da 32bit angibst wird er nur einen 24bit DepthBuffer verwenden. Dann gehst du scheinbar davon aus dass DepthBuffer floating point Formate sind. Das ist nicht der Fall. Aber nachdem du sowieso keine Daten angegeben hast sollte das GL_FLOAT dort nicht weiter stören.
Ich gehe mal davon aus dass deine Textur korrekt erstellt wird!?
Was genau geht denn mit dem Depth Attachement nicht?
Und für was erzeugst du dann den Renderbuffer wenn du doch schon eine Depth Texture hast?

Werbeanzeige