Linux OpenGL ES 2.0 Textur verwenden

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

Hallo,

ich hatte ja hier mal nach 3D ohne X gefragt:
http://zfx.info/viewtopic.php?f=5&t=3755 ich habe das Beispiel
etwas umgebaut und entflochten. Läuft bisher gut genug für meine Zwecke. Wegen
meiner nicht immer ganz aktuellen Hardware wollte ich OpenGL ES 2.0 verwenden.

Jetzt wollte ich eigentlich mit FreeType Texte auf ein Dreieck schreiben. Das
habe ich aber nicht zum laufen bekommen um es einfacher zu machen habe ich
dann erst mal versucht einfach irgendeine Textur auf das Dreieck zu malen was
aber auch nur Teilweise funktioniert.

Hier mal die Source-Code Teile:

Vertex-Shader:

Code: Alles auswählen

#version 300 es
layout (location = 0) in vec4 vPosition;

void main ()
{
  gl_Position = vPosition;
}
Fragment-Shader:

Code: Alles auswählen

#version 300 es
precision mediump float;
out vec3 fragColor;
in vec2 UV;
uniform sampler2D myTexture;

void main ()
{
  fragColor = texture(myTexture, UV).rgb;
}
Zeichenfunktion "draw":

Code: Alles auswählen

  glClearColor (0.0, 0.0, 0.0, 0.0);
  glClear (GL_COLOR_BUFFER_BIT);
  glUseProgram (gl.program);


  GLubyte pixels [] = { 255,   0,   0,  0, 255,   0,  0,   0, 255,  255, 255,   0 };
  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  GLuint textureId;
  glGenTextures (1, &textureId);
  glBindTexture (GL_TEXTURE_2D, textureId);
  glTexImage2D (GL_TEXTURE_2D, 0,  GL_RGB, 4, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  GLint texLoc = glGetUniformLocation(gl.program, "myTexture");
  glActiveTexture (GL_TEXTURE0);    // activate texture unit 0
  glUniform1i (texLoc, 0);  // inform the shader to use texture unit 0

  GLfloat triangle_vertices[] = { 0.0,  0.8,
                                 -0.8, -0.8,
                                  0.8, -0.8,
                                  0.5,  0,9 };

  GLint  attribute_coord;
  glEnableVertexAttribArray (attribute_coord);
  glVertexAttribPointer (attribute_coord, 2, GL_FLOAT, GL_FALSE, 0, triangle_vertices);
  glDrawArrays (GL_TRIANGLES,      0, 3);
  glDisableVertexAttribArray (attribute_coord);
  glFlush ();
Ich glaube die drei Programmteile enthalten das wichtigste. Wenn was fehlt kann ich das gerne noch nachliefern.

Das Programm gibt jetzt ein rotes Dreieck aus. Wenn man im Array pixels die Werte in der ersten Zeile verändert dann ändert sich die Farbe des Dreiecks. Ich hätte allerdings erwartet das alles aus dem Array pixels zum füllen des Dreiecks verwendet wird und halt entsprechend oft hintereinander kopiert.

Grüße
Alexander
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Wieso hast du keine uv-koordinaten an den shader übergeben?
Das musst du tun, ansonsten kann ja nicht ordentlich gemapt werden.
Und wieso haben deine vertices 8 einträge? Müssten das nicht 9 sein?
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

UV-Koordinaten da muss ich mal suchen wie das geht. Gemacht habe ich es nicht weil ich es nicht wusste. Bin recht neu bei OpenGL und habe mir das Programm aus diversen Beispielen und der OpenGL Referenz im Internet zusammen gesucht. Wenn Du irgendwo ein gutes Beispiel kennst wäre ein Link da hin auch hilfreich.

Das mit den vertices verstehe ich jetzt nicht. Warum 9? Momentan mal ich ein Dreieck das wären dann 3 Punkte 3*2=6 also. Das habe ich ja auch so in der Funktion glDrawArrays angegeben. Warum im Array mehr sind liegt daran das ich auch schon probiert habe andere Formen zu malen (z.B. Punkte, Linien od. Polygone). Das hat auch funktioniert nur die Texturen wollen nicht.
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Okay, ich kann ja auch mal nach einem Beispiel wegen den UV-Koordinaten schauen.

Naja, das mit den Vertices ist ja so:
(Ich habe mich übrigens da oben verschrieben. Es sollte in deinem Beispiel eigentlich 12 heißen.)
Du hast ja in deinem Vertex-Shader angegeben, dass Du 4 Werte für einen Vertex angibst. Mit dieser Zeile:

Code: Alles auswählen

layout (location = 0) in vec4 vPosition;
vec4 steht ja für einen 4-komponenten Vektor. Also x,y,z,w. Also müsstest Du auch dein triangle_vertices so abändern.
Oder du definierst eben im Shader, dass nur 3 oder 2 Werte genügen um einen Vertex zu beschreiben.
Mit zB

Code: Alles auswählen

layout (location = 0) in vec3 vPosition; // 3-komponenten vektor 
Damit bräuchtest Du aber dann eben 9 Einträge in deinem triangle_vertices ;)
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Naja... und das mit den UV-Koordinaten müsste dann so in etwa funktionieren.
(Nur mal so schematisch.)

Code: Alles auswählen

GLfloat triangle_vertices[] = { 0.0, 0.8,
-0.8, -0.8,
0.8, -0.8,
0.5, 0,9 };

GLfloat uvCoords[] = { 0.0, 0.0,
1.0, 0.0,
0.5, 1.0};
// Die UV-Koordinaten; Pro Vertex einen 2-komponenten Vektor

GLint attribute_coord;
glEnableVertexAttribArray (attribute_coord);
glVertexAttribPointer (attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, triangle_vertices);
GLint attribute_uvCoord;
glEnableVertexAttribArray (attribute_uvCoord);
glVertexAttribPointer (attribute_uvCoord, 2, GL_FLOAT, GL_FALSE, 0, uvCoords);

glDrawArrays (GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray (attribute_coord);
glDisableVertexAttribArray (attribute_uvCoord);
glFlush ();
So in etwa müsste das im Programm ausehen.
Jetzt must Du wahrscheinlich im Shader noch folgendes angeben

Code: Alles auswählen

#version 300 es
layout (location = 0) in vec4 vPosition; // <= oder wie auch immer...
layout (location = 1) in vec2 uvCoord;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

void main ()
{
gl_Position = vPosition;
UV = uvCoord;
}
Jooo...so in etwa sollte das aussehen...
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

Stimmt das mit dem vec4 habe ich während der Experimente aus den Augen verloren. Ich habe es jetzt mal auf vier geändert soweit funktioniert das auch. Was Merkwürdig ist wenn ich die UV-Koordinaten wie nach Deinem Beispiel angebe dann Zeichnet er mir das Dreieck an die Position der UV-Koordinaten und füllt es wieder mit einer Farbe aus.
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Na dann stimmt etwas mit meinem beispiel nicht, sorry.
So aus dem kopf bekomme ich das jetzt auch nicht hin.
Du musst jedoch, und das ist sicher, einmal die vertices *und* die uv-koordinaten dem shader übergeben.
Schaue mal am besten nach einem tutorial oder beispiel wie das bei openGl es gemacht wird.
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Wart, ich habe gerade gesehen, dass ich da einen Fehler gemacht habe.

Code: Alles auswählen

....
GLfloat uvCoords[] = { 0.0, 0.0,
1.0, 0.0,
0.5, 1.0};
// Die UV-Koordinaten; Pro Vertex einen 2-komponenten Vektor

glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, triangle_vertices);

glEnableVertexAttribArray (1);
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, uvCoords);

glDrawArrays (GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray (attribute_coord);
glDisableVertexAttribArray (attribute_uvCoord);
glFlush ();
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

Ach in der Richtung hatte ich auch schon gesucht aber die Lösung ist mir nicht aufgefallen.

Code: Alles auswählen

glEnableVertexAttribArray (0);
Hier muss die 0 und 1 zu dem Wert in dem Shader in den layout Zeilen passen oder?
Das hatte ich dann ja in meiner Ursprünglichen Version auch schon falsch.

Jetzt habe ich ein gestreiftes Dreieck. Da geht zwar noch ein schwarzer Balken durch bei dem ich noch nicht weiß wo er her kommt. Muss ich noch mal suchen. Aber das Ergebnis ist schon mal deutlich besser. Vielleicht bekomme ich ja das dann auch mit dem FreeType hin.

Danke für die Hilfe hat mich schon mal ein ganzes Stück weiter gebracht.
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

alexander_ro hat geschrieben: Hier muss die 0 und 1 zu dem Wert in dem Shader in den layout Zeilen passen oder?
Japp!!
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

Das mit den falschen Farben und schwarzen Streifen kam davon das ich die Funktion unten in meinem ersten Post falsch hatte. Ich hatte da die Breite des Arrays und nicht die Breite in Pixel angegeben.

Code: Alles auswählen

  glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 1, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
Jetzt gehts und auch die Farben sind richtig.
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

Nachdem das mit meiner Einfachen Textur funktioniert habe ich das mal mit FreeType Texten wieder probiert. Als Beispiel habe ich das hier gefunden: https://en.wikibooks.org/wiki/OpenGL_Pr ... ndering_01

In dem glTexImage2D Aufruf unten verwendet der die Konstante GL_RED die es aber bei OpenGL ES 2.0 nicht gibt. Ich habe schon mal gesucht aber die OpenGL ES Beispiele sind recht selten im Netz ich habe jetzt keine Lösung gefunden wie man das bei OpenGL ES mit einer Textur macht die nur einen Farbkanal hat. Habt Ihr vielleicht einen Tipp nach was ich da suchen muss oder wie es geht?

Code: Alles auswählen

    glTexImage2D(
      GL_TEXTURE_2D,
      0,
      GL_RED,
      g->bitmap.width,
      g->bitmap.rows,
      0,
      GL_RED,
      GL_UNSIGNED_BYTE,
      g->bitmap.buffer
    );
joggel

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von joggel »

Ich bin hier leider nur mit Handy und begrenztem Datenvolumen im netz unterwegs.
Aber laut kurzer google-suche habe ich gelesen das GL_RED wohl unter OpenGL ES 3.0 unterstützt wird.
Kannst denn nicht 3.0 statt 2.0 benutzen?
Vlt weiß noch jemand anders hier rat....
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von Jörg »

GL_LUMINANCE oder GL_ALPHA sind einkanalige Formate für GLES 2.0.
(siehe https://www.khronos.org/registry/gles/s ... 2.0.25.pdf, table 3.4).

HTH,

Jörg
alexander_ro
Beiträge: 19
Registriert: 14.03.2005, 08:48

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von alexander_ro »

joggel hat geschrieben:Kannst denn nicht 3.0 statt 2.0 benutzen?
Ich habe einen alten Asus eee 901 und irgendwie geht dort OpenGL ES 3.0 nicht. Ich habe mal angenommen das liegt an der Hardware. Im Moment wäre es noch schön wenn meine Software auch auf dem laufen würde.
Jörg hat geschrieben:GL_LUMINANCE oder GL_ALPHA sind einkanalige Formate für GLES 2.0.
Das mit GL_LUMINANCE und GL_ALPHA habe ich auch gefunden ich dachte aber das wäre was anderes weil zumindest dem Namen nach geht es ja um Beleuchtung oder Transparenz nicht um Farbe oder macht das keinen Unterschied?
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von Schrompf »

Das macht keinen Unterschied. Das sind nur Zahlen, die da gelesen werden, und Du bestimmst im Shader ihre Bedeutung.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8316
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von Krishty »

Kurze Einmischung von außen: Macht es Unterschiede in der Farbraumkonvertierung? LUMINANCE klingt nach automatischem sRGB und ALPHA nach linearen Werten.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Linux OpenGL ES 2.0 Textur verwenden

Beitrag von Jörg »

GLES 2.0 kennt (aus Altersgründen) kein sRGB. Es sollte keine Linearisierung stattfinden.
Antworten