Entwickler-Ecke

Multimedia / Grafik - Textur bekommt Blauton - OpenGL


Black Force - Mo 12.05.08 16:52
Titel: Textur bekommt Blauton - OpenGL
Hallo,

Ich hab mit OpenGL eine Textur auf meinen Würfel geladen.
Bloß wird der Hintergrund des Bildes immer Blau, was wahrscheinlich
am folgenden Code liegt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
begin
  tex := IMG_Load('./bild.bmp');
  if assigned(tex) then
  begin
    glGenTextures(1, @TexID);
    glBindTexture(GL_TEXTURE_2D, TexID);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 03, tex^.w, tex^.h,0, GL_RGB, GL_UNSIGNED_BYTE, tex^.pixels);//hier ist vielleicht der
                                                                                               //Fehler 
    SDL_FreeSurface(tex);
  end;


BenBE - Mo 12.05.08 18:00

Lädst Du dein Bild RGB oder BGR. Muss man bei OpenGL nämlich unterscheiden.


turboPASCAL - Mo 12.05.08 18:49

... ggf. setze die Farbe auf Weiss vor dem zeichen deines Würfels. ( glColor4f() )


Black Force - Mo 12.05.08 20:27

Das mit dem weißstellen hat nicht ganz geklappt. Der Hintergrund ist zwar
wieder weiß, aber dafür gibts andere Farbfehler.
Ich glaube, dem Code kann man entnehmen, dass es RGB ist.


F34r0fTh3D4rk - Mo 12.05.08 20:53

Vielleicht ist dein Bild intern BGR gespeichert. Kommt selten vor, ist mir aber auch schon passiert.

mfg


Black Force - Mo 12.05.08 20:56

Kann nicht sein, weil ich den Hintergrund und meinen Würfel
einwandfrei färben konnte durch flcolor3f(r,g,b);.


F34r0fTh3D4rk - Mo 12.05.08 21:26

Es geht ja auch nur um die Textur.


Yogu - Mo 12.05.08 22:02

Hallo,

es empfiehlt sich sowieso, TGA-Dateien zu nehmen. Sie haben wenig Header und sind einfach aufgebaut. In einem Artikel im DGL Wiki [http://wiki.delphigl.com/index.php/TGA_Bilder_laden] ist das ganz gut erklärt.

Du kannst auch meine Unit GLTGA nehmen:


GLTGA.pas - Version 0.1.10, 10.05.08 (gekürzt)
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
unit GLTGA;

interface

uses
  Classes, SysUtils;

type
  TGLTGAFile = class
  private
    fWidth:     Word;  // Breite
    fHeight:    Word;  // Höhe
    fDepth:     Byte;  // Farbtiefe (Byte pro Pixel)
    fData:      PByte; // Inhalt    
  public
    constructor Create;
    destructor Destroy; override;

    function LoadFromFile(FileName: String): Boolean;
    function LoadFromStream(Stream: TStream): Boolean;

    property Width:     Word  read fWidth;
    property Height:    Word  read fHeight;
    property Depth:     Byte  read fDepth;
    property Data:      PByte read fData;
  end;

implementation

constructor TGLTGAFile.Create;
begin
  inherited Create;
end;

destructor TGLTGAFile.Destroy;
begin      
  if Assigned(fData) then FreeMem(fData);
  fData := nil;
  inherited Destroy;
end;

function TGLTGAFile.LoadFromFile(FileName: String): Boolean;
var Stream: TFileStream; 
begin
  Result := False;
  try
    Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  except
    on E: EFOpenError do
    begin
      Application.MessageBox(PChar('Die Texturdatei '''+FileName+''' konnte nicht geladen werden: '#13#13+E.Message), 'Fehler beim Laden der Datei'16);
      Exit;
    end;
    else raise;
  end;

  try
    Result := LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

function TGLTGAFile.LoadFromStream(Stream: TStream): Boolean;
var Bytes: Cardinal; ImageType: Byte;
begin
  Result := False;
  
  // Bildtyp laden
  Stream.Seek(2, soFromCurrent);
  Stream.Read(ImageType, 1);
  if ImageType <> 2 then
  begin
      Application.MessageBox(PChar('Der Typ der TGA-Datei kann nicht gelesen werden.'), 'Fehler beim Laden der Datei'16);
    Exit;
  end;

  // Breite, Höhe und Farbtiefe laden
  Stream.Seek(9, soFromCurrent);
  Stream.Read(fWidth, 2);
  Stream.Read(fHeight, 2);
  Stream.Read(fDepth, 1);
  fDepth := fDepth div 8;

  // Inhalt laden
  Bytes := fWidth * fHeight * fDepth;
  GetMem(fData, Bytes);
  Stream.Seek(1, soFromCurrent);
  Stream.Read(fData^, Bytes);

  Result := True;
end;

end.

Du solltest noch die Messageboxen durch ein Fehlersystem ersetzen - zum Beispiel Exceptions.

Grüße,
Yogu


Black Force - Mo 12.05.08 22:20

Ich hab meinen Code ja größtenteils von einem Tutorial von dgl, der mit sdl
arbeitet. Darum wollte ich es genauso machen.

Ich hab es jetzt mit .jpg versucht. Die Farben sind zwar richtig, aber
da nimmt die Helligkeit ab, je mehr man sich vom Bild abwendet.

Naja, guckt es euch an.


Black Force - Mo 12.05.08 22:53

Das Problem mit der Helligkeit hab ich jetzt gelöst.
Lag an
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
:oops:
Aber die Farben von der Textur sind immer noch nicht korrekt.


Lossy eX - Mi 14.05.08 12:50

BMPs sind grundsätzlich IMMER BGR. TGAs auch im übrigen auch. ;) Wenn du mit SDL_image ein BMP lädst, dann sind die Daten des Surfaces auch BGR. Ich habe das gerade noch mal geprüft, weil ich es selber nicht 100%tig wusste. Und OpenGL erwartet bei deinem Code eine Textur im RGB Format. Also sind bei dir die Kanäle rot und blau vertauscht. Grün ist aber richtig. So etwas kannst du am Besten erkennen, wenn eine typisch blaue Stelle des Bildes plötzlich rot ist. Oder andersrum.

Das kannst du ändern in dem du bei glTexImage den Paramater GL_RGB in GL_BGR tauscht. Denn dann erwartet OpenGL eine Textur im BGR Format. Allerdings sei noch erwähnt, dass JPEG/PNG in RGB abgespeichert werden, weswegen du dann wieder Probleme bekommen könntest. Der Code im Tutorial benutzt ja auch ein JPEG.

Alternativ kann ich evtl, die neuste Version meines Loaders glBitmap [http://www.delphigl.com/forum/viewtopic.php?t=7458] anbieten. Der kommt jetzt auch mit Linux und SDL klar.