Bytes aus DDS Image darstellen - Wie?



  • Hallo!

    Ich habe nun in meinem Code die Bytes des Mainimage einer DDS-Datei (DirectDrawSurface) ausgelesen und möchte diese auf dem Bildschirm darstellen. Kann mir jemand sagen, welche Möglichkeiten ich da habe?

    Vielen Dank schon mal im Voraus,
    veryxRV



  • Du hast jetzt eine DDS Datei und willst sie als Textur laden? Mit DirectX oder OpenGL? Für DirectX hat Micrsosoft sicher einen nativen Loader spendiert bei OpenGL muss man sich selbst drum kümmern. Hier aus meiner damaligen Engine der DDS Loader falls du was damit anfangen kannst:

    Strict
    
    Import Brl.EndianStream
    Import "..\Texture.bmx"
    Import "..\HardwareInfo.bmx"
    
    ' Signature
    Const DDD_DDS_MAGIC = $20534444
    
    ' DirectDraw Surface Desciption
    Const DDD_DDSD_CAPS        = $00000001
    Const DDD_DDSD_HEIGHT      = $00000002
    Const DDD_DDSD_WIDTH       = $00000004
    Const DDD_DDSD_PITCH       = $00000008
    Const DDD_DDSD_PIXELFORMAT = $00001000
    Const DDD_DDSD_MIPMAPCOUNT = $00020000
    Const DDD_DDSD_LINEARSIZE  = $00080000
    Const DDD_DDSD_DEPTH       = $00800000
    
    ' DirectDraw Pixel Format
    Const DDD_DDPF_ALPHAPIXELS = $00000001
    Const DDD_DDPF_FOURCC      = $00000004
    Const DDD_DDPF_RGB         = $00000040
    
    ' DirectDraw Four Character Code(Compression Methods)
    Const DDD_FOURCCC_DXT1 = $31545844
    Const DDD_FOURCCC_DXT3 = $33545844
    Const DDD_FOURCCC_DXT5 = $35545844
    
    ' DirectDraw Surface Capabilities
    Const DDD_DDSCAPS_COMPLEX = $00000008
    Const DDD_DDSCAPS_TEXTURE = $00001000
    Const DDD_DDSCAPS_MIPMAP  = $00400000
    
    ' DirectDraw Surface Capabilities 2
    Const DDD_DDSCAPS2_CUBEMAP           = $00000200
    Const DDD_DDSCAPS2_CUBEMAP_POSITIVEX = $00000400
    Const DDD_DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800
    Const DDD_DDSCAPS2_CUBEMAP_POSITIVEY = $00001000
    Const DDD_DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000
    Const DDD_DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000
    Const DDD_DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000
    Const DDD_DDSCAPS2_VOLUME            = $00200000
    
    ' DDS PixelFormats
    Const DDD_DDS_RGBA8888 = 1 ' -> GL_RGBA
    Const DDD_DDS_RGBA5551 = 2 ' -> GL_RGBA
    Const DDD_DDS_RGBA4444 = 3 ' -> GL_RGBA
    Const DDD_DDS_RGB888   = 4 ' -> GL_RGB
    Const DDD_DDS_RGB565   = 5 ' -> GL_RGB
    Const DDD_DDS_DXT1     = 6 ' -> GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
    Const DDD_DDS_DXT3     = 7 ' -> GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
    Const DDD_DDS_DXT5     = 8 ' -> GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
    
    ' DirectDraw PixelFormat
    Type TDDS_DDPIXELFORMAT
    	Field Size            : Int
    	Field Flags           : Int
    	Field FourCC          : Int
    	Field RGBBitCount     : Int
    	Field RBitMask        : Int
    	Field GBitMask        : Int
    	Field BBitMask        : Int
    	Field RGBAlphaBitMask : Int
    
    	Method Read(Stream:TStream)
    		Self.Size            = Stream.ReadInt()
    		Self.Flags           = Stream.ReadInt()
    		Self.FourCC          = Stream.ReadInt()
    		Self.RGBBitCount     = Stream.ReadInt()
    		Self.RBitMask        = Stream.ReadInt()
    		Self.RBitMask        = Stream.ReadInt()
    		Self.RBitMask        = Stream.ReadInt()
    		Self.RGBAlphaBitMask = Stream.ReadInt()
    	End Method
    End Type
    
    ' DirectDraw Capabilities
    Type TDDS_DDCAPS2
    	Field Caps1    : Int
    	Field Caps2    : Int
    	Field Reserved : Int[2]
    		Method Read(Stream:TStream)
    		Self.Caps1 = Stream.ReadInt()
    		Self.Caps2 = Stream.ReadInt()
    		Stream.Seek(Stream.Pos()+8)
    	End Method
    End Type
    
    ' DirectDraw SurfaceDescription
    Type TDDS_DDSURFACEDESC2
    	Field Size              : Int
    	Field Flags             : Int
    	Field Height            : Int
    	Field Width             : Int
    	Field PitchOrLinearSize : Int
    	Field Depth             : Int
    	Field MipMapCount       : Int
    	Field Reserved1         : Int[11]
    	Field PixelFormat       : TDDS_DDPIXELFORMAT
    	Field Caps              : TDDS_DDCAPS2
    	Field Reserved2         : Int
    
    	Method Read(Stream:TStream)
    		Self.Size              = Stream.ReadInt()
    		Self.Flags             = Stream.ReadInt()
    		Self.Height            = Stream.ReadInt()
    		Self.Width             = Stream.ReadInt()
    		Self.PitchOrLinearSize = Stream.ReadInt()
    		Self.Depth             = Stream.ReadInt()
    		Self.MipMapCount       = Stream.ReadInt()
    		Stream.Seek(Stream.Pos()+44)
    		Self.PixelFormat.Read(Stream)
    		Self.Caps.Read(Stream)
    		Stream.Seek(Stream.Pos()+4)
    	End Method
    
    	Method New()
    		Self.PixelFormat = New TDDS_DDPIXELFORMAT
    		Self.Caps        = New TDDS_DDCAPS2
    	End Method
    End Type
    
    Type TDDSLoader
    	Field Stream      : TStream
    	Field Texture     : TTexture
    	Field SurfaceDesc : TDDS_DDSURFACEDESC2
    	Field Width       : Int
    	Field Height      : Int
    	Field Size        : Int
    	Field Format      : Int
    	Field Components  : Int
    	Field Data        : Byte[]
    
    	Method CheckHeader:Int()
    		If (Self.SurfaceDesc.Size <> 124) Or .. 
    		   (Not Self.SurfaceDesc.Flags & (DDD_DDSD_WIDTH ..
    		                                  | DDD_DDSD_HEIGHT ..
    		                                  | DDD_DDSD_CAPS ..
    		                                  | DDD_DDSD_PIXELFORMAT)) Or ..
    		   (Self.SurfaceDesc.PitchOrLinearSize = 0) Or ..
    		   (Self.SurfaceDesc.PixelFormat.Size <> 32) Or ..
    		   (Not Self.SurfaceDesc.Caps.Caps1 & DDD_DDSCAPS_TEXTURE) Or ..
    		   (Self.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_VOLUME) Then
    
    			Return False
    		Else
    			Return True
    		EndIf 
    	End Method
    
    	Method GetPixelFormat:Int()
    		If Self.SurfaceDesc.PixelFormat.Flags & DDD_DDPF_RGB Then
    			' Uncompressed
    			If Self.SurfaceDesc.PixelFormat.Flags & DDD_DDPF_ALPHAPIXELS Then
    				' Alpha
    				If Self.SurfaceDesc.PixelFormat.RGBBitCount = 16 Then
    					If Self.SurfaceDesc.PixelFormat.RGBAlphaBitMask & $8000 Then
    						' RGBA5551
    						Self.Size       = Self.Width*Self.Height*2
    						Self.Components = GL_RGBA
    						Self.Format     = DDD_DDS_RGBA5551
    						Self.Data       = New Byte[Self.Width*Self.Height*4]
    						Return True
    					Else
    						' RGBA4444
    						Self.Size       = Self.Width*Self.Height*2
    						Self.Components = GL_RGBA
    						Self.Format     = DDD_DDS_RGBA4444
    						Self.Data       = New Byte[Self.Width*Self.Height*4]
    						Return True
    					EndIf
    				ElseIf Self.SurfaceDesc.PixelFormat.RGBBitCount = 32 Then
    					' RGBA8888
    					Self.Size       = Self.Width*Self.Height*4
    					Self.Components = GL_RGBA
    					Self.Format     = DDD_DDS_RGBA8888
    					Self.Data       = New Byte[Self.Width*Self.Height*4]
    					Return True
    				Else
    					Return False
    				EndIf
    			Else
    				' No Alpha
    				If Self.SurfaceDesc.PixelFormat.RGBBitCount = 16 Then
    					' RGB565
    					Self.Size       = Self.Width*Self.Height*2
    					Self.Components = GL_RGB
    					Self.Format     = DDD_DDS_RGB565
    					Self.Data       = New Byte[Self.Width*Self.Height*3]
    					Return True
    				ElseIf Self.SurfaceDesc.PixelFormat.RGBBitCount = 24	
    					' RGB888
    					Self.Size       = Self.Width*Self.Height*3
    					Self.Components = GL_RGB
    					Self.Format     = DDD_DDS_RGB888
    					Self.Data       = New Byte[Self.Width*Self.Height*3]
    					Return True
    				Else
    					Return False
    				EndIf
    			EndIf
    		ElseIf Self.SurfaceDesc.PixelFormat.Flags & DDD_DDPF_FOURCC
    			If Not THardwareInfo.S3TCSupport Then Return False
    
    			Select Self.SurfaceDesc.PixelFormat.FourCC
    				Case DDD_FOURCCC_DXT1
    					' DXT1
    					Self.Size       = Self.SurfaceDesc.PitchOrLinearSize
    					Self.Components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
    					Self.Format     = DDD_DDS_DXT1
    					Self.Data       = New Byte[Self.Size]
    					Return True
    
    				Case DDD_FOURCCC_DXT3
    					' DXT3
    					Self.Size       = Self.SurfaceDesc.PitchOrLinearSize
    					Self.Components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
    					Self.Format     = DDD_DDS_DXT3
    					Self.Data       = New Byte[Self.Size]
    					Return True
    
    				Case DDD_FOURCCC_DXT5
    					' DXT5
    					Self.Size       = Self.SurfaceDesc.PitchOrLinearSize
    					Self.Components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
    					Self.Format     = DDD_DDS_DXT5
    					Self.Data       = New Byte[Self.Size]
    					Return True
    
    				Default
    					Return False
    
    			End Select
    		Else
    			Return False
    		EndIf
    	End Method
    
    	Method ReadImage(Width:Int, Height:Int, Size:Int=0)
    		Local X:Int, Y:Int, RGBA:Int, Red:Byte, Green:Byte, Blue:Byte, Alpha:Byte
    		Local Offset:Int
    
    		Select Self.Format
    			Case DDD_DDS_RGBA8888
    				Offset = 0
    				For Y = 0 To Height-1
    					For X = 0 To Width-1
    						Self.Data[Offset+3] = Self.Stream.ReadByte()
    						Self.Data[Offset+2] = Self.Stream.ReadByte()
    						Self.Data[Offset+1] = Self.Stream.ReadByte()
    						Self.Data[Offset+0] = Self.Stream.ReadByte()
    
    						Offset :+ 4
    					Next
    				Next
    
    			Case DDD_DDS_RGBA5551
    				Offset = 0
    				For Y = 0 To Height-1
    					For X = 0 To Width-1
    						RGBA  = Self.Stream.ReadShort()
    						Red   = (RGBA Shl 10) & $003E
    						Green = (RGBA Shl  5) & $07C0
    						Blue  =  RGBA         & $F800
    						Alpha = (RGBA Shl 15) & $0001
    
    						Self.Data[Offset]   = Red
    						Self.Data[Offset+1] = Green
    						Self.Data[Offset+2] = Blue
    						Self.Data[Offset+3] = Alpha
    
    						Offset :+ 4
    					Next
    				Next
    
    			Case DDD_DDS_RGBA4444
    				Offset = 0
    				For Y = 0 To Height-1
    					For X = 0 To Width-1
    						RGBA  = Self.Stream.ReadShort()
    						Red   = (RGBA Shl  8) & $F000
    						Green = (RGBA Shl  4) & $0F00
    						Blue  =  RGBA         & $00F0
    						Alpha = (RGBA Shl 12) & $000F
    
    						Self.Data[Offset]   = Red
    						Self.Data[Offset+1] = Green
    						Self.Data[Offset+2] = Blue
    						Self.Data[Offset+3] = Alpha
    
    						Offset :+ 4
    					Next
    				Next
    
    			Case DDD_DDS_RGB888
    				Offset = 0
    				For Y = 0 To Height-1
    					For X = 0 To Width-1
    						Self.Data[Offset+2] = Self.Stream.ReadByte()
    						Self.Data[Offset+1] = Self.Stream.ReadByte()
    						Self.Data[Offset]   = Self.Stream.ReadByte()
    
    						Offset :+ 3
    					Next
    				Next
    
    			Case DDD_DDS_RGB565
    				Offset = 0
    				For Y = 0 To Height-1
    					For X = 0 To Width-1
    						RGBA  = Self.Stream.ReadShort()
    						Red   = (RGBA Shl 10) & $001F
    						Green = (RGBA Shl  5) & $03E0
    						Blue  =  RGBA         & $7C00
    
    						Self.Data[Offset]   = Red
    						Self.Data[Offset+1] = Green
    						Self.Data[Offset+2] = Blue
    
    						Offset :+ 3
    					Next
    				Next
    
    			Case DDD_DDS_DXT1
    				Self.Stream.Read(Self.Data, Size)
    
    			Case DDD_DDS_DXT3
    				Self.Stream.Read(Self.Data, Size)
    
    			Case DDD_DDS_DXT5
    				Self.Stream.Read(Self.Data, Size)
    		End Select
    	End Method
    
    	Method SetTexImage:Int(Target:Int)
    		Self.ReadImage(Self.Width, Self.Height)
    
    		If Self.SurfaceDesc.PixelFormat.Flags & DDD_DDPF_RGB Then
    			' Uncompressed
    			glTexImage2D(Target, 0, Self.Components, Self.Width, Self.Height, ..
    			             0, Self.Components, GL_UNSIGNED_BYTE, Self.Data)
    		Else
    			' Compressed
    			If Width < 8 Then Size = 8
    			glCompressedTexImage2D(Target, 0, Self.Components, Self.Width, ..
    			                       Self.Height, 0, Self.Size, Self.Data)
    		EndIf
    	End Method
    
    	Method SetMIPMaps:Int(Target:Int)
    		Local Level:Int, Width:Int, height:Int, Size:Int
    
    		Width  = Self.Width
    		Height = Self.Height
    		Size   = Self.Size
    
    		For Level = 1 To Self.SurfaceDesc.MipMapCount
    			Self.ReadImage(Width, Height, Size)
    
    			If Self.SurfaceDesc.PixelFormat.Flags & DDD_DDPF_RGB Then
    				' Uncompressed
    				glTexImage2D(Target, Level-1, Self.Components, Width, Height, ..
    				             0, Self.Components, GL_UNSIGNED_BYTE, Self.Data)
    			Else
    				' Compressed
    				If Width < 8 Then Size = 8
    				glCompressedTexImage2D(Target, Level-1, Self.Components, Width, Height, ..
    				                       0, Size, Self.Data)
    			EndIf
    
    			If glGetError() <> 0 Then Return False
    
    			Width  = Width  Shr 1
    			Height = Height Shr 1
    			Size   = Size   Shr 2 
    		Next
    
    		Return True
    	End Method
    
    	Method SetTexture:Int(Target:Int)
    		If Self.SurfaceDesc.Caps.Caps1 & DDD_DDSCAPS_MIPMAP Then
    			Return Self.SetMIPMaps(Target)
    		Else
    			Return Self.SetTexImage(Target)
    		EndIf
    	End Method
    
    	Function Load:TTexture(URL:Object)
    		Local Loader:TDDSLoader
    
    		Loader = New TDDSLoader
    
    		Loader.Stream = LittleEndianStream(ReadStream(URL))
    		If Not Loader.Stream Then Return Null
    
    		' Check Signature
    		If Loader.Stream.ReadInt() <> DDD_DDS_MAGIC Then
    			Loader.Stream.Close()
    			Return Null
    		EndIf
    
    		' Load Surface Format Header
    		Loader.SurfaceDesc = New TDDS_DDSURFACEDESC2
    		Loader.SurfaceDesc.Read(Loader.Stream)
    
    		' Check Header
    		If Not Loader.CheckHeader() Then
    			Loader.Stream.Close()
    			Return Null
    		EndIf
    
    		' Check Width and Height
    		Loader.Width  = Loader.SurfaceDesc.Width
    		Loader.Height = Loader.SurfaceDesc.Height
    
    		TTexture.AdjustTexSize(Loader.Width, Loader.Height)
    		If (Loader.Width <> Loader.Height) Or ..
    		   (Loader.Width <> Loader.SurfaceDesc.Width) Or ..
    		   (Loader.Height <> Loader.SurfaceDesc.Height) Then
    
    			Loader.Stream.Close()
    			Return Null
    		EndIf
    
    		' Check PixelFormat
    		If Not Loader.GetPixelFormat()
    			Loader.Stream.Close()
    			Return Null
    		EndIf
    
    		' Create Texture
    		Loader.Texture = New TTexture
    
    		If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP Then
    			' Cubemap
    			glBindTexture(GL_TEXTURE_CUBE_MAP, Loader.Texture.TextureID)
    
    			' Positive X
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_POSITIVEX Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    
    			' Negative X
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_NEGATIVEX Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    
    			' Positive Y
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_POSITIVEY Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    
    			' Negative Y
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_NEGATIVEY Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    
    			' Positive Z
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_POSITIVEZ Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    
    			' Negative Z
    			If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP_NEGATIVEZ Then
    				If Not Loader.SetTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT) Then
    					Loader.Texture.Remove()
    					Loader.Stream.Close()
    					Return Null
    				EndIf
    			EndIf
    		Else
    			glBindTexture(GL_TEXTURE_2D, Loader.Texture.TextureID)
    			If Not Loader.SetTexture(GL_TEXTURE_2D) Then
    				Loader.Texture.Remove()
    				Loader.Stream.Close()
    				Return Null
    			EndIf
    		EndIf
    
    		' Set RenderModes
    		If Loader.SurfaceDesc.Caps.Caps1 & DDD_DDSCAPS_MIPMAP Then
    			Loader.Texture.AddRenderMode(DDD_TEXTURE_MIPMAP)
    		EndIf
    
    		If Loader.SurfaceDesc.Caps.Caps2 & DDD_DDSCAPS2_CUBEMAP Then
    			Loader.Texture.AddRenderMode(DDD_TEXTURE_CUBEMAP)
    		EndIf
    
    		' Close Stream and return loaded Texture
    		Loader.Stream.Close()
    		Return Loader.Texture
    	End Function
    End Type
    

    Naja, und wenn du die Textur erstmal geladen hast, kannst du sie auch auf einem Quad rendern 😉

    mfg olli



  • Hi!

    Danke erst mal für den Codeausschnitt! 🙂

    Sofern ich den Code richtig verstehe, lädst du ja die Daten für das Bild an sich in ein Byte[]. Wenn dem so ist, sind wir jetzt auf dem gleiche Standpunkt. 😉

    Jetzt möchte ich die Daten aus dem Byte irgendwie als Bild in meinem Fenster darstellen. Wie mach ich das (in C++ und ggf. mit DirectX)? Du hast ja von einem "Quad" geschrieben... Was ist das? ^^ Bin da nicht so fit drin...

    Gruß veryxRV

    PS: Der hintergrund der ganzen Sache ist, dass ich eine Art Puzzle aus DDS Images habe, die ich gerne in meinem Fenster zusammengefügt darstellen möchte. Die bilder sollen also in einem Raster auf dem Bildschirm ausgegeben werden.

    Und noch was: Ich brauche die DDS nicht als Textur, sondern wie gesagt als 2D Image.



  • Kommt drauf an, ob wir da wirklich auf dem selben Level sind ^^ Wenn ich mit meiner Engine die .DDS Datei mit allen Raffinessen wie Kompression, MIPMaps und Cubemaps geladen habe brauche ich nur noch ein Mesh, auf dem ich die Textur anzeige. Die .DDS Datei nur einfach in ein Byte-Array zu laden bringt ja nichts.

    Unter OpenGL wäe der einfachste Weg, die Textur zu binden und dann ein einfaches Quad zu zeichnen:

    Texture = TDDSLoader("Test.dds")
    ' ...
    glBindTexture(Texture.TextureID)
    glBegin(GL_QUADS)
    	' Links Oben
    	glTexCoord2f(0.0, 0.0)
    	glVertex2f(-0.5, 0.5)
    
    	' Rechts Oben
    	glTexCoord2f(1.0, 0.0)
    	glVertex2f(0.5, 0.5)
    
    	' Rechts Unten
    	glTexCoord2f(1.0, 1.0)
    	glVertex2f(0.5, -0.5)
    
    	' Links Unten
    	glTexCoord2f(0.0, 1.0)
    	glVertex2f(-0.5, -0.5)
    glEnd()
    ' ...
    gluSwapBuffers()
    

    Bin etwas aus der Übung, das ich bis zu letzt mit Netzwerkkram zu tun hatte.
    Wenn du mehrere Quads zu rendern hast, dann machst du am besten das ganze über Displaylists und mit GL_TRIANGLES.

    Also ich finde, das Anzeigen einer Textur ist wohl der weniger problematische Teil. Die Textur erstmal zu laden ist weitaus schwieriger(unter OpenGL zumindest).

    Vllt. schaust du mal kurz bei http://wiki.delphigl.com/index.php/Tutorial_Lektion_2 vorbei. Musst ja nicht alles über 3D wissen, aber über Texturen und Primitives ist das nicht schlecht.

    mfg olli

    Edit: Vllt. willst du einfach nur ein Bild zeichnen ohne den ganzen "Krims Krams ". Dann speicher besser die Bilder als .BMP oder .JPG ab und nutze SDL:
    http://www.pl-berichte.de/work/sdl/sdl-teil1.html das ist weitaus leichter zu erlernen und auch intuitiver.



  • Also mit 3D an sich kenne ich mich eigentlich schon aus, also mit dem Prinzip, nur halt nicht so wirklich mit der Programmierung.

    Leider kann ich mit OpenGL nicht viel anfangen. Ich muss aber sagen, dass es mich wirklich wundert, dass im DirectX SDK keine Bibliotheken für DDS Files vorhanden sind!

    Eigtl. müssten jeweils 3 Bytes in der Bytefolge für das Bild doch einen Farbwert für einen Pixel darstellen oder?



  • Eben nicht. .DDS Dateien beinhalten wie gesagt solche Raffinessen wie Cubemaps, MIPMaps und Kompression. Nimm doch besser .BMP oder unkomprimierte .TGA Dateien.

    Bei SDL müsstest du dir übrigens da keine Gedanken machen. Da kannst du auch .JPG nehmen.

    Jedenfalls haben alle Bildformate irgendwelche Zusatzinfos und sei es nur Breite und Höhe in Pixel. Einfach eine Datei in ein Byte-Array zu laden genügt nicht. Es muss erst aufbereitet werden(dekomprimieren, Format auslesen, usw.) und erst dann bekommst du die Rohdaten des Bilds. Selbst .BMP kann komprimiert sein(RLE Komprimierung).

    Und DirectX wird sicher ein .DDS Loader bereitstellen. Irgendwie über D3DXCreateTextureFromFile o.ä.

    Wenn das ganze nur 2D sein soll, nimm besser SDL und vergiss .DDS 🙂



  • Würde ich auch sehr gerne, das Problem ist nur, dass eine Software dieses Puzzle im DDS Format ausgibt. Normalerweise SOLLTE diese Software diese DDS Files auch Problemlos zu einem großen DDS File zusammenfügen. Leider ist dieses Programm jedoch die reinste Katastrophe und u.a. funktioniert diese Funktion nicht richtig.

    Nun habe ich mir halt vorgenommen, ein kleines Tool zu schreiben, dass dem Benutzer die DDS richtig zusammenfügt und zwar ohne, dass er vorher etwas anderes machen muss, als den Ordner mit den DDS Files anzugeben.

    Mein Programm liest also erst den Header aus in die entsprechenden Variablen. Danach gelangt er ja an die Daten für das eigentliche Bild. Dieses ist 32768 Bytes groß. Diese 32768 Bytes liest ers also in ein Byte[]. Und mit diesem Byte[] kann ich jetzt nichts anfangen?



  • Da gibt es doch beispielsweise für Photoshop Tools, die Texturen aus der .DDS Datei laden. Und nein, mit diesem Byte-Array kannst du nichts anfangen. Wäre praktisch so, als wenn ich dir für eine Pipercup den Schlüssel gebe du das Flugzeug aber nicht zum abheben bringen kannst.

    Schau mal auf der NVidia Seite vorbei, da dürften die Tools zu .DDS zu finden sein.

    mfg olli



  • Okay, ich muss die Daten also erst dekromprimieren, richtig?

    Grr ist das ein Mist mit diesen Files 🙄

    Na ja, danke jedenfalls für die Mühe! 🙂



  • In der .DDS Datei kann es mehrere Bilder geben. Zum einen sind das die MIPMaps Stufenbilder zum anderen für Cubemaps die 6 Seitenbilder. Und weiterhin existieren ein Haufen voller Bildformate:

    ' DDS PixelFormats
    Const DDD_DDS_RGBA8888 = 1 ' -> GL_RGBA
    Const DDD_DDS_RGBA5551 = 2 ' -> GL_RGBA
    Const DDD_DDS_RGBA4444 = 3 ' -> GL_RGBA
    Const DDD_DDS_RGB888   = 4 ' -> GL_RGB
    Const DDD_DDS_RGB565   = 5 ' -> GL_RGB
    Const DDD_DDS_DXT1     = 6 ' -> GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
    Const DDD_DDS_DXT3     = 7 ' -> GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
    Const DDD_DDS_DXT5     = 8 ' -> GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
    

    Die ersten 5 sind unkomprimiert und die letzten 3 sind komprimiert. Zu der Komprimierung gibt es Textdateien für die OpenGL Extensions.

    Aber ich versichere dir: alles sau schwer zu machen ^^

    mfg olli



  • Ja das denke ich mir. Leider sind meine Bilder dann alle mit DXT1 komprimiert... mal sehen ob es bei Nvidia doch was gescheites gibt, ansonsten muss halt ein Commandline-Tool erst die ganzen Bilder in BMP umwandeln. Nur dann kann ich keinen schönen Status-Balken anzeigen ^^


Anmelden zum Antworten