Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 15:19

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 58 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Autor Nachricht
BeitragVerfasst: Mi Jan 28, 2015 17:00 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
allerdings weiß ich überhaupt nicht wie man die Klasse TShader selbst erstellen kann.

Auf die TShader kannst du auch verzichten, und dies mit InitShader lösen wie bei meinem ersten Code.

Code:
  1. glVertexAttribPointer(intexco, 3, GL_FLOAT, False, SizeOf(TVertex),  Pointer(PtrUInt(@PVertex(nil)^.texco)));

Da texcoords normalerweise 2D sind, musst du die 3 durch eine 2 ersetzen.
Wie kommst du auf die Zeigerverschachtlung bei Poin.... ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 28, 2015 18:12 
Offline
DGL Member

Registriert: Sa Jan 03, 2015 13:28
Beiträge: 23
Programmiersprache: Lazarus/FPC
Danke Dir :)
Ich habe die TexCoord mal der Übersicht halber im Programm und im Shader in "inTexCoord" umbenannt, wie Du vorgeschlagen hast.

Mit dem Deklarieren/definieren habe ich mich falsch ausgedrückt, gemeint habe ich damit, daß der Inhalt des Arrays ja irgendwo herkommen muss.

Hier nochmal der Code, den ich gerade benutze:
Code:
  1. type
  2.   TVertex = packed record
  3.     pos: TgluVector3f;
  4.     texco: TgluVector3f;
  5.   end;  

in TMainForm.Render:
Code:
  1.   inPosLocation := glGetAttribLocation(fShader.ProgramObj, 'inPos');
  2.   glEnableVertexAttribArray(inPosLocation);
  3.   glVertexAttribPointer(inPosLocation, 3, GL_FLOAT, False, SizeOf(TVertex), Pointer(PtrUInt(@PVertex(nil)^.pos))) ;
  4.  
  5.   intexco := glGetAttribLocation(fShader.ProgramObj, 'inTexCoord');
  6.   glEnableVertexAttribArray(intexco);
  7.   glVertexAttribPointer(intexco, 3, GL_FLOAT, False, SizeOf(TVertex),  Pointer(PtrUInt(@PVertex(nil)^.texco)));  

Der Wert von PtrUInt(@PVertex(nil)^.texco) ist 12, kann das stimmen?
In dem Fall stehen ja vor dem ersten Wert der Texturkoordinaten die x,y und z Daten von inPos.

Wie gesagt, die übergebene Variable für die Textur-Koordinaten heißt im Shader nach wie vor gleich wie in glGetAttribLocation, dennoch ist der Renderpanel mit der Farbe des linken oberen Eckpixels der Textur gefüllt. Lediglich wenn ich als Offset für glVertexAttribPointer(intexco,...) wieder Pointer(0) angebe, wird die Textur wieder im rechten oberen Viertel gespiegelt gezeigt. Irgendwas fehlt bei den Textur Koordinaten.

Kompletter Shader Code:
Code:
  1. /* ShaderObject: GL_VERTEX_SHADER */
  2. #version 330
  3. uniform mat4 uModelViewProjMat;
  4. in vec3 inPos;
  5.  
  6. in vec2 inTexCoord; 
  7. out vec2 vTexCoord;
  8.  
  9. void main(void)
  10. {
  11.   gl_Position = vec4(inPos, 1.0);
  12.   vTexCoord = inTexCoord;
  13. }
  14.  
  15. /* ShaderObject: GL_FRAGMENT_SHADER */
  16. #version 330
  17.  
  18.  uniform sampler2D u_texture;   //diffuse map
  19.  
  20. in vec2 vTexCoord; 
  21. out vec4 outColor; // ausgegebene Farbe 
  22.  
  23. void main(void)
  24.   vec4 TextureColor = texture(u_texture, vTexCoord); 
  25.   outColor = TextureColor; 
  26. }

Die Shader Tutorials habe ich mir grob angesehen, bin dort aber auch direkt wieder auf veraltete Befehle wie gl_TexCoord gestoßen.
Ich habe auch mit mehreren Texturen herumprobiert, so wie es dort beschrieben ist. Dazu habe ich im Shader "uniform sampler2D v_texture;" hinzugefügt (direkt hinter "uniform sampler2D u_texture;") und in der Renderprozedur "fshader.Uniform1f('v_texture', 0);".
In Form.Create habe ich folgendes hinzugefügt:
Code:
  1.   fTexture2 := TglBitmap2D.Create('trees_normals.png');
  2.   fTexture2.GenTexture;
  3.   glActiveTexture(1);
  4.   fTexture2.Bind;

Der Shader meldet hier direkt "can't find variable 'v_texture' in the program".


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 28, 2015 18:20 
Offline
DGL Member

Registriert: Sa Jan 03, 2015 13:28
Beiträge: 23
Programmiersprache: Lazarus/FPC
mathias hat geschrieben:
Auf die TShader kannst du auch verzichten, und dies mit InitShader lösen wie bei meinem ersten Code.

Okay, ich schau mir das alles nochmal genau an, sobald Lösung A mal läuft ;) Oder parallel dazu, vielleicht klappt ja irgendwann eine von beiden Herangehensweisen :D

mathias hat geschrieben:
Da texcoords normalerweise 2D sind, musst du die 3 durch eine 2 ersetzen.
Wie kommst du auf die Zeigerverschachtlung bei Poin.... ?

Ja, das sehe ich ein, habe die 3 in eine 2 geändert, und texco in TVertex entsprechend als TgluVector2f angegeben. Geändert hat sich dadurch allerdings im Ergebnis nichts.
Die Zeigerverschachtlung habe ich einfach mal so von Bergmann übernommen, immerhin wird dadurch automatisch (hoffentlich) der richtige Wert eingesetzt.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 28, 2015 18:41 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Hier nochmal der Code, den ich gerade benutze:
Code:
  1. type
  2.   TVertex = packed record
  3.     pos: TgluVector3f;
  4.     texco: TgluVector3f;
  5.   end;
  6.  
  7. var
  8.   Vertex : TVertex  


Ich kenne TgluVector3f nicht, aber was sicher pos und texco müssen eine Array of glFloat sein.

Code:
  1.   inPosLocation := glGetAttribLocation(fShader.ProgramObj, 'inPos');
  2.   glEnableVertexAttribArray(inPosLocation);
  3.   glVertexAttribPointer(inPosLocation, 3, GL_FLOAT, False, Length(Vertex.pos) * SizeOf(glFloat), Pointer(Vertex.pos))) ;
  4.  
  5.   intexco := glGetAttribLocation(fShader.ProgramObj, 'inTexCoord');
  6.   glEnableVertexAttribArray(intexco);
  7.   glVertexAttribPointer(intexco, 2, GL_FLOAT, False, Length(Vertex.texco * SizeOf(glFloat),  Pointer(Vertex.texco)));  


Wen pos und texco eine statische Array ist, musst du Pointer(Vertex.xxx) durch @Vertex.xxx ersetzen.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 28, 2015 20:23 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
mathias hat geschrieben:
Wen pos und texco eine statische Array ist, musst du Pointer(Vertex.xxx) durch @Vertex.xxx ersetzen.
Eben nicht, das ist kein normaler Pointer. Wenn kein VBO gebunden wäre, dann würde OpenGL dort einen Zeiger auf die Daten erwarten, deshalb ist das ein Pointer. Wenn allerdings ein VBO gebunden ist, dann erwartet OpenGL den Offset der Daten im VBO, als Integer. Da man aber einen Integer nicht an einen Pointer übergeben kann, ist dort der harte cast drin.
Der Ausdruck den ich da gebaut hab ist eigentlich selbsterklärend (kann aber auch sein das ich in letzter Zeit bischen zu viel C gemacht hab, da ist das standard^^):
Code:
  1. TTest = packed record
  2.   test1, test2: Integer;
  3. end;
  4. PTest = ^TTest;
  5. PtrUInt(@PTest(nil)^.test2))

Also, was macht das. Wir nehmen einen nil-Pointer (0x00000000), den casten wir in einen PTest, das wir auf dessen Elemente zugreifen können. Das würde normalerweiße in einem Segmentation-Fault enden, aber wir greifen ja nicht die Daten ab, sondern lassen uns die Addresse des Elements geben (mit @). Bei einem packed record liegen die Daten alle schön der Reihe nach im RAM, so wie sie im Record definiert sind. Heißt test1 hat Offset = 0 und test2 hat Offset = 4 (weil test1 = Integer = 4Byte). Die Basis-Addresse auf die das Offset addiert wird ist in dem Fall unser nil-Pointer, also 0x00000000. Daraus folg die Addresse von test2 ist 0x00000000 + 4 byte = 0x00000004. Die Addresse wird dann in ein PtrUInt gecastet, was nix anderes ist als ein Int der genauso groß wie ein Pointer ist (4 byte auf 32bit-Maschinen bzw. 8 byte auf 64bit Maschinen). Dieser PtrUInt-Wert wäre in unserem Fall 4 (von 0x00000004). Und das casten wir am Ende wieder in einen Pointer, weil OpenGL einen Pointer erwartet. Zugegeben, die lestzen beiden Casts hätte man weglassen können, aber so ist es IMHO sauberer.

@Dee: Im TVertex hast du die TexCoords als Vector mit 3 Elementen deklariert, der hat aber nur 2. Dann passt das mit den Offsets und Größen nicht mehr. Ich erweiter das Beispiel-Projekt morgen mal noch um die Texturen, dann hast du ein einfaches funktionierendes Beispiel mit Texturen.
zum v_texture: generell alle Parameter und Variablen, die im Code nicht genutzt werden (lesender Zugriff), werden nicht mit gelinkt. Deshalb kann er die zur Laufzeit auch nicht finden.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 28, 2015 22:29 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Zitat:
mathias hat geschrieben:
Wen pos und texco eine statische Array ist, musst du Pointer(Vertex.xxx) durch @Vertex.xxx ersetzen.

Eben nicht, das ist kein normaler Pointer. Wenn kein VBO gebunden wäre, dann würde OpenGL dort einen Zeiger auf die Daten erwarten, deshalb ist das ein Pointer.


Wieso komme ich zu den folgenden Ergebnissen ?
Erwartet glVertexAttribPointer andere Pointer als glBufferData ?

Code:
  1. type
  2.   TTRiangle = array[0..1] of Tmat3x3;
  3.  
  4. const
  5.   Triangle: TTRiangle = // Statische Array
  6.     (((-0.8, -0.8, 0.0), (0.8, 0.8, 0.0), (-0.8, 0.8, 0.0)),
  7.     ((-0.8, -0.8, 0.0), (0.8, -0.8, 0.0), (0.8, 0.8, 0.0)));
  8. var
  9.   dyn_array: array of Tmat3x3;   // Dynamische Array
  10.  
  11. begin
  12.   ....
  13.   dyn_array := Triangle;
  14.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), @Triangle, GL_STATIC_DRAW);            // geht
  15.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), Pointer(Triangle), GL_STATIC_DRAW);    // Compiler-Fehler
  16.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), @dyn_array, GL_STATIC_DRAW);           // Leeres Bild
  17.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), Pointer(dyn_array), GL_STATIC_DRAW);   // geht
  18.   ...
  19.  

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jan 29, 2015 10:02 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
mathias hat geschrieben:
Erwartet glVertexAttribPointer andere Pointer als glBufferData ?
Wenn ein VBO gebunden ist, dann ja. Wie gesagt ist der Pointer von glVertexAttribPointer dann ein Offset.
Weiterhin ist es gefährlich ein dynamisches Array einfach in Pointer zu casten. Wenn du einen Zeiger auf die Daten willst, dann solltest du das auch so schreiben: @MyArray[0]. Ich hab leider grad kein Beispiel bereit, aber das Array muss nicht immer mit den Daten anfangen. Es könnte auch sein das dort interne Verwaltungs-Daten liegen.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jan 29, 2015 17:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

wie versprochen das erweiterte Beispiel: Download
Das mit den dynamischen Layout Locations (glGetAttribLocation) hab ich mal raus genommen, da das nur für Verwirrung gesorgt hat. Die Locations sind jetzt im Shader und im Programm hart gecodet. So kann man das an den Namen der Konstanten auch besser nachvollziehen, denke ich.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Feb 04, 2015 21:44 
Offline
DGL Member

Registriert: Sa Jan 03, 2015 13:28
Beiträge: 23
Programmiersprache: Lazarus/FPC
Vielen Dank, das Beispiel funktioniert einwandfrei.
Ich kann zwar noch nicht komplett nachvollziehen warum es jetzt funktioniert, aber ich nehme mal an, ich hatte vorher wirklich einen Fehler in den glGetAttribLocation Befehlen.
"layout(location = 0)" im Shader bezieht sich auf die Konstante "LAYOUT_LOCATION_POS = 0;", richtig?
Und die Tatsache daß die Textur richtig herum (ohne sie vorher zu spiegeln) angezeigt wird, ist auch eine Folge der festen Locations?

Ich habe übrigens noch versucht, eine zweite Textur auf dieselbe Weise einzubinden wie die erste, allerdings wird dann (egal ob mit oder ohne glActiveTexture) immer (nur) die benutzt, die als letzte gebunden wurde.
Im Multitexturing-Beispiel von Mathias werden in der Render-Prozedur beide Texturen nacheinander gebunden, das habe ich ebenfalls versucht, allerdings bisher ohne Erfolg. Vermutlich wird die erste Textur bei mir mit der zweiten überschrieben.
Ich werde morgen mal den Code posten, mit dem ich experimentiert habe.

Vielen Dank jedenfalls erstmal, das Beispiel ist wunderbar übersichtlich und erstaunlich wenig Code.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Feb 04, 2015 22:32 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
"layout(location = 0)" im Shader bezieht sich auf die Konstante "LAYOUT_LOCATION_POS = 0;", richtig?
Und die Tatsache daß die Textur richtig herum (ohne sie vorher zu spiegeln) angezeigt wird, ist auch eine Folge der festen Locations?

Sollte nicht.

Code:
  1. layout (location = 1) in vec3 inNormal;


Mit dieser Zeile tust du nur dir ID-Nr erzwingen.
Mit
Code:
  1. glGetAttribLocation(FProgram_ID, 'inNormal');  

müsste eine "1" rauskommen.
Code:
  1.   glEnableVertexAttribArray(1);
  2.   glVertexAttribPointer(1, 3, GL_FLOAT, False, 0, nil);

Somit kannst du hier direkt eine "1" reinschreiben.

Zitat:
Im Multitexturing-Beispiel von Mathias werden in der Render-Prozedur beide Texturen nacheinander gebunden, das habe ich ebenfalls versucht, allerdings bisher ohne Erfolg. Vermutlich wird die erste Textur bei mir mit der zweiten überschrieben.


Code:
  1.    glGenTextures(1, @textureID0);
  2.    glBindTexture(GL_TEXTURE_2D, textureID0);

Du müsste e2 verschiedene textureIDx haben.Du kannst es mit
Code:
  1. Writeln(textureIDx);
überprüfen.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Feb 05, 2015 18:27 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Dee hat geschrieben:
Und die Tatsache daß die Textur richtig herum (ohne sie vorher zu spiegeln) angezeigt wird, ist auch eine Folge der festen Locations?
Nein, das hat damit nix zu tun. Ich hab einfach nur die Textur-Coords der y-Achse verdreht, das die Textur vertikal gespiegelt wird. Das ist ein einfacher Trick und kostet keine extra Rechenleistung, da die Textur so oder so auf die Geometrie gemappt werden muss, nur wird sie jetzt halt andersrum gemappt. Wenn du 90° Rotationen oder Spiegelungen haben möchtest, dann solltest du das immer über die TextCoords machen.
Code:
  1.   fVBO := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
  2.   fVBO.BufferData(4, sizeof(TVertex), TglcBufferUsage.buStaticDraw, nil);
  3.   p := fVBO.MapBuffer(TglcBufferAccess.baWriteOnly);
  4.   try
  5.     p^.pos := gluVector3f(-0.5, -0.5, 0);  // y-Position des Vertex = oben (-0.5)
  6.     p^.tex := gluVector2f( 0.0,  1.0);     // y-Position der Textur = unten (1.0)
  7.     inc(p);
  8.  
  9.     p^.pos := gluVector3f( 0.5, -0.5, 0);
  10.     p^.tex := gluVector2f( 1.0,  1.0);
  11.     inc(p);
  12.  
  13.     p^.pos := gluVector3f( 0.5,  0.5, 0);
  14.     p^.tex := gluVector2f( 1.0,  0.0);
  15.     inc(p);
  16.  
  17.     p^.pos := gluVector3f(-0.5,  0.5, 0);
  18.     p^.tex := gluVector2f( 0.0,  0.0);
  19.     inc(p);
  20.   finally
  21.     fVBO.UnmapBuffer;
  22.   end;


Dee hat geschrieben:
Ich werde morgen mal den Code posten, mit dem ich experimentiert habe.
Wäre besser, ohne Code ne Aussage zu treffen ist immer schwierig. ^^

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Feb 06, 2015 18:19 
Offline
DGL Member

Registriert: Sa Jan 03, 2015 13:28
Beiträge: 23
Programmiersprache: Lazarus/FPC
Bergmann89 hat geschrieben:
Ich hab einfach nur die Textur-Coords der y-Achse verdreht, das die Textur vertikal gespiegelt wird. Das ist ein einfacher Trick und kostet keine extra Rechenleistung, da die Textur so oder so auf die Geometrie gemappt werden muss, nur wird sie jetzt halt andersrum gemappt.

Genialer Trick, das war mir gar nicht aufgefallen. Dankeschön.

Also, zum Thema Multitexturing. Ich habe probiert, eine zweite Textur auf dieselbe Art wie Mathias in seinem Beispiel einzubinden, natürlich auf den glBitmap Loader umgemünzt, mit "fTexture: array[0..2] of TglcBitmap2D;" und einer weiteren Konstanten TEXTURE_FILE2 = 'data\texture2.png';.
Dazu habe ich zwei einfache Bilder mit unterschiedlichen Farbflächen benutzt, um sehen zu können, ob diese sich mit dem Shader mitteln lassen.

Den Code in Form.Create habe ich folgendermaßen abgeändert:
Code:
  1. procedure TMainForm.FormCreate(Sender: TObject);
  2. const
  3.   ia: array[0..1] of integer = (0, 1);
  4. var
  5.   pf: TglcContextPixelFormatSettings;
  6.   p: PVertex;
  7. begin
  8.   pf := TglcContext.MakePF();
  9.   fContext := TglcContext.GetPlatformClass.Create(RenderPanel, pf);
  10.   fContext.BuildContext;
  11.  
  12.   fShader := TglcShaderProgram.Create(@Log);
  13.   fShader.LoadFromFile(ExtractFilePath(Application.ExeName) + SHADER_FILE);
  14.   fShader.Compile;
  15.   fShader.Uniform1iv(UNIFORM_NAME_TEXTURE, 2, ia);
  16.  
  17.   fVBO := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
  18.   fVBO.BufferData(4, sizeof(TVertex), TglcBufferUsage.buStaticDraw, nil);
  19.   p := fVBO.MapBuffer(TglcBufferAccess.baWriteOnly);
  20.   try
  21.     p^.pos := gluVector3f(-0.5, -0.5, 0);
  22.     p^.tex := gluVector2f( 0.0,  1.0);
  23.     inc(p);
  24.  
  25.     p^.pos := gluVector3f( 0.5, -0.5, 0);
  26.     p^.tex := gluVector2f( 1.0,  1.0);
  27.     inc(p);
  28.  
  29.     p^.pos := gluVector3f( 0.5,  0.5, 0);
  30.     p^.tex := gluVector2f( 1.0,  0.0);
  31.     inc(p);
  32.  
  33.     p^.pos := gluVector3f(-0.5,  0.5, 0);
  34.     p^.tex := gluVector2f( 0.0,  0.0);
  35.     inc(p);
  36.   finally
  37.     fVBO.UnmapBuffer;
  38.   end;
  39.  
  40.   fTexture[0] := TglcBitmap2D.Create;
  41.   fTexture[0].LoadFromFile(ExtractFilePath(Application.ExeName) + TEXTURE_FILE);
  42.   fTexture[0].GenTexture;
  43.  
  44.   fTexture[1] := TglcBitmap2D.Create;
  45.   fTexture[1].LoadFromFile(ExtractFilePath(Application.ExeName) + TEXTURE_FILE2);
  46.   fTexture[1].GenTexture;
  47.   MainForm.Caption:=inttostr(fTexture[1].ID);
  48. end;            


Die Textur-ID habe ich als Caption der Form ausgeben lassen, da "Writeln(fTexture[1].ID);" einen Fehler ausgespuckt hat.
Form.Render habe ich ebenfalls abgeändert:
Code:
  1. procedure TMainForm.Render;
  2. begin
  3.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  4.   fVBO.Bind;
  5.   glActiveTexture(0);
  6.   fTexture[0].Bind;
  7.   glActiveTexture(1);
  8.   fTexture[1].Bind;
  9.   fShader.Enable;
  10.  
  11.   glEnableVertexAttribArray(LAYOUT_LOCATION_POS);
  12.   glVertexAttribPointer(LAYOUT_LOCATION_POS, 3, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.pos);
  13.  
  14.   glEnableVertexAttribArray(LAYOUT_LOCATION_TEX);
  15.   glVertexAttribPointer(LAYOUT_LOCATION_TEX, 2, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.tex);
  16.  
  17.   glDrawArrays(GL_QUADS, 0, fVBO.DataCount);
  18.   glDisableClientState(GL_VERTEX_ARRAY);
  19.  
  20.   fShader.Disable;
  21.   fTexture[0].Unbind;
  22.   fTexture[1].Unbind;
  23.   fVBO.Unbind;
  24.  
  25.   fContext.SwapBuffers;
  26. end;  

Ich schätze hier liegt der Fehler, denn nur die letzte gebundene Textur wird benutzt.
Den Vertex-Shader habe ich unberührt gelassen und im Fragment Shader versucht, die zweite Textur zu 50% einfließen zu lassen:
Code:
  1. /* ShaderObject: GL_FRAGMENT_SHADER */
  2. #version 330
  3. uniform sampler2D uTexture[2];
  4. in vec2 vTexCoord;
  5. out vec4 outColor;
  6.  
  7. void main(void)
  8. {
  9.   outColor = texture(uTexture[0], vTexCoord);
  10.   outColor = (outColor + texture(uTexture[1], vTexCoord))/2;
  11. }


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Feb 06, 2015 19:41 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

kleiner Fehler meinerseits: der Shader muss gebunden sein, bevor man ein Uniform setzten kann. Ist bis jetzt nicht aufgefallen, weil der uniform sampler vom Shader-Linker automatisch mit 0 initialisiert wird. Bei sowas hilft es auch immer mit glGetError zu gucken ob irgendein OpenGL Aufruf ein Fehler ausgespuckt hat, dann findet man das eigentlich immer relativ schnell.
kleiner Hinweis: Du brauchst dir nicht extra ein Array anlegen, für die 2 Werte kannst du auch direkt auf die Uniform-Array-Elemente zugreifen.
Code:
  1.   fShader := TglcShaderProgram.Create(@Log);
  2.   fShader.LoadFromFile(ExtractFilePath(Application.ExeName) + SHADER_FILE);
  3.   fShader.Compile;
  4.   fShader.Enable;
  5.   fShader.Uniform1i(UNIFORM_NAME_TEXTURE + '[0]', 0);
  6.   fShader.Uniform1i(UNIFORM_NAME_TEXTURE + '[1]', 1);
  7.   fShader.Disable;


Im Render sind noch zwei Fehler:
- glActiveTexture erwartet eine symbolische Konstante für die Textur-Unit.
- TglcBitmap2D.Unbind macht intern nix anders als glBindTexture(GL_TEXTURE_2D, 0) und das wirkt sich nur auf die aktuell gebundene Texture-Unit aus. Heißt im Klartext fTexture[0].Unbind; entbindet die Textur auf Textur-Unit 1 (die noch von glActiveTexture(1); aktiv ist) und fTexture[1].Unbind; macht das selbe noch einmal.
Code:
  1.   fTextures[0].Bind;            // GL_TEXTURE0 ist der Default-Wert, also sparen wir uns den Call vor'm bind
  2.   glActiveTexture(GL_TEXTURE1); // Unit1 aktivieren
  3.   fTextures[1].Bind;            // Textur an Unit1 binden
  4.   //[...]
  5.   fTextures[1].Unbind;          // Textur von Unit1 entbinden
  6.   glActiveTexture(GL_TEXTURE0); // Default-Wert wieder herstellen
  7.   fTextures[0].Unbind;          // Textur von Unit0 entbinden

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Feb 06, 2015 19:56 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ein Test, ob die Textur richtig gebunden wurde.
Teste die beiden unteren Shader-Code, dann siehst du ob die Textur richtig angekommen ist.

Code:
  1. void main(void)
  2. {
  3.   outColor = texture(uTexture[0], vTexCoord);
  4. }
Code:
  1. void main(void)
  2. {
  3.   outColor = texture(uTexture[1], vTexCoord);
  4. }


Da könnte auch noch ein Fehler sein.
Code:
  1. fShader.Uniform1iv(UNIFORM_NAME_TEXTURE, 2, ia);

Mach es mal auf den direkten Weg:
Code:
  1.  glUniform1iv(glGetUniformLocation(Shader.Program_ID,'uTexture'), 2, ia);

Da dies sowieso nur einmal gemacht wird, kannst du den Umweg über die Unifom_ID-Variable sowieso sparen.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Feb 06, 2015 22:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
mathias hat geschrieben:
Mach es mal auf den direkten Weg:
Code:
  1.  glUniform1iv(glGetUniformLocation(Shader.Program_ID,'uTexture'), 2, ia);
Die Uniform-Methoden der Shader-Klasse machen intern nichts anderes.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 58 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.058s | 17 Queries | GZIP : On ]