2 Stimmen

GLSL 4.10 Texturzuordnung

Ich versuche herauszufinden, wie man Texturzuordnung unter Verwendung von GLSL Version 4.10 macht. Ich bin ziemlich neu in GLSL und war heute glücklich, ein Dreieck mit Farben gerendert zu haben, die basierend auf sin (Zeit) verblassen, das mit Shadern verwendet wurde. Jetzt interessiere ich mich dafür, Shader mit einer einzigen Textur zu verwenden.

Viele Tutorials und sogar Antworten auf Stack Overflow schlagen vor, gl_MultiTexCoord0 zu verwenden. Das wurde jedoch seit GLSL 1.30 veraltet und die neueste Version ist jetzt 4.20. Meine Grafikkarte unterstützt kein 4.20, deshalb versuche ich 4.10 zu verwenden.

Ich weiß, dass ich meine Textur richtig generiere und binde und habe passende Eckpunktkoordinaten und Texturkoordinaten, da meine Höhenkarte perfekt gerendert wurde, als ich die Fixed-Function-Pipeline verwendet habe, und sie mit Farbe anstelle der Textur gut gerendert wird.

Hier sind meine GLSL-Shader und ein Teil meines C++-Zeichencodes:

---heightmap.vert (GLSL)---

in vec3 position;
in vec2 texcoord;

out vec2 p_texcoord;

uniform mat4 projection;
uniform mat4 modelview;

void main(void)
{
    gl_Position = projection * modelview * vec4(position, 1.0);
    p_texcoord = texcoord;
}

---heightmap.frag (GLSL)---

in vec2 p_texcoord;

out vec4 color;

uniform sampler2D texture;

void main(void)
{
    color = texture2D(texture, p_texcoord);
}

---Heightmap::Draw() (C++)---

// Bind Shader
// Bind VBO + IBO
// Enable Vertex and Texcoord client state

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);

// glVertexPointer(...)
// glTexCoordPointer(...)

glUniform4fv(projLoc, projection);
glUniform4fv(modelviewLoc, modelview);
glUniform1i(textureId, 0);

// glDrawElements(...)

// glDisable/unbind everything

Das, worüber ich auch misstrauisch bin, ist, ob ich die Texturkoordinaten an den Fragment-Shader als Varying übergeben muss, da ich sie im Vertex-Shader nicht berühre. Außerdem habe ich keine Ahnung, wie es die interpolierten Texturkoordinaten bekommen wird. Es scheint, als würde es einfach 0.f oder 1.f erhalten, nicht die interpolierte Koordinate. Ich weiß nicht genug über Shader, um zu verstehen, wie das funktioniert. Wenn mich jemand aufklären könnte, wäre ich begeistert!

Bearbeitung 1:

@Bahbar: Entschuldigung, das war ein Tippfehler. Ich tippe Code auf einem Gerät, während ich ihn auf einem anderen lese. Wie ich sagte, hat alles mit der Fixed Function Pipeline funktioniert. Obwohl glEnableClientState und gl[Vertex|TexCoord]Pointer veraltet sind, sollten sie immer noch mit Shadern funktionieren, oder? glVertexPointer anstelle von glVertexAttribPointer hat mit Farben anstelle von Texturen funktioniert. Außerdem verwende ich glBindAttribLocation (position auf 0 und texcoord auf 1).

Der Grund, warum ich immer noch glVertexPointer verwende, ist, dass ich versuche, nach und nach eine Sache zu veralten.

3voto

Bahbar Punkte 17300

glBindTexture nimmt ein Texturobjekt als zweiten Parameter.

// Aktiviere den Vertex- und Texcoord-Client-Zustand

Ich nehme an, du meintest die generischen Vertex-Attribute? Wo sind deine position und texcoord Attribute eingerichtet? Dafür benötigst du einige Aufrufe von glEnableVertexAttribArray und glVertexAttribPointer anstelle von glEnableClientState und glVertex/TexCoordPointer (alle diese sind auf die gleiche Weise veraltet wie gl_MultiTexCoord in glsl).

Und natürlich, um herauszufinden, wo die Attribute gebunden sind, musst du entweder glGetAttribLocation aufrufen, um herauszufinden, wo GL sich entschieden hat, das Attribut hinzuzufügen, oder es selbst mit glBindAttribLocation definieren (vor dem Linken des Programms).

Bearbeiten um hinzuzufügen, nach deiner Ergänzung:

Nun, 0 könnte Daten von glVertexPointer holen (aus Gründen, auf die du dich nicht verlassen solltest. Attribut 0 ist speziell und die meisten IHVs machen es genauso wie Vertex funktioniert), aber 1 wird sehr wahrscheinlich keine Daten von glTexCoord holen.

In der Theorie gibt es keine Überlappung zwischen den generischen Attributen (wie deinem texcoord, das seine Daten von glVertexAttribPointer(1,XXX) bekommt, 1 hier ist der von dir gewählte Ort) und den integrierten Attributen (wie gl_MultiTexCoord[0], das seine Daten von glTexCoordPointer bekommt).

Nvidia ist bekannt dafür, sich nicht an die Spezifikation zu halten, und tatsächlich Attribute zu aliasen (das kommt aus dem Cg-Modell, soweit ich weiß), und wird so weit gehen zu sagen, einen bestimmten Attributort für glTexCoord zu verwenden (die Cg-Spezifikation schlägt vor, den Ort 8 für TexCoord0 zu verwenden - und Ort 1 ist das Attribut Blendweight - siehe Tabelle 39, S. 242), aber du solltest wirklich den Schritt wagen und deine TexCoordPointer zu VertexAttribPointer-Aufrufen wechseln.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X