2010-11-29 13 views
1

Ich fing an, mit einem OpenGL ES 1.0 zu spielen, und ich stoße auf ein (Anfänger) Problem: Ich habe versucht, eine quadratische Textur auf den durch Dreiecke beschriebenen Würfel abzubilden.Mapping einer quadratischen Textur zu einem Dreieck

// Turn necessary features on 
    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE, GL_SRC_COLOR); 
    glEnable(GL_CULL_FACE); 
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

    // Bind the number of textures we need, in this case one. 
    glGenTextures(1, &texture[0]); 
    glBindTexture(GL_TEXTURE_2D, texture[0]); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

//Drawing code 
static GLfloat rot = 0.0; 

static const Vertex3D vertices[] = { 
    -1.0f,-1.0f,-1.0f, //0 00 
    1.0f,-1.0f,-1.0f, //1 10 
    1.0f, 1.0f,-1.0f, //2 11 
    -1.0f, 1.0f,-1.0f, //3 01  
}; 


static const int vertexCnt = 3 * 2; 

static const GLubyte cube[] = { 
    3,0,2, 
    1,2,0, 
}; 

static const GLfloat texCoords[] = { 
    0,1, 
    0,0, 
    1,1, 
    1,0, 
    1,1, 
    0,0, 
}; 


glClearColor(0.0, 0.0, 0.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glLoadIdentity(); 

glTranslatef(0.0f, 0.0f, -3.0f); 

glBindTexture(GL_TEXTURE_2D, texture[0]); 

glEnableClientState(GL_VERTEX_ARRAY); 
//glEnableClientState(GL_COLOR_ARRAY); 
glEnableClientState(GL_NORMAL_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glEnable(GL_COLOR_MATERIAL); 


glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
glVertexPointer(3, GL_FLOAT, 0, vertices); 

//glColorPointer(4, GL_FLOAT, 0, colors); 
glNormalPointer(GL_FLOAT, 0, normals); 



glDrawElements(GL_TRIANGLES, vertexCnt, GL_UNSIGNED_BYTE, cube); 


glDisableClientState(GL_VERTEX_ARRAY); 
//glDisableClientState(GL_COLOR_ARRAY); 
glDisableClientState(GL_NORMAL_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

Jetzt, nach zig Versuchen, ich kann es einfach nicht noch andere Seiten bekommen arbeiten ... Gibt es eine Faustregel gilt: für Fall, wenn auf Dreiecke Quadrat Textur-Mapping?

EDIT: Ich denke, ich finde heraus, wie das Mapping getan werden sollte. Aber es funktioniert nicht für dieses Beispiel (ein Gesicht). Kann jemand bitte einfach überprüfen, ob ich korrekt mapped habe (vorausgesetzt, dass der Rest des Codes funktioniert)?

Vielen Dank

+0

Ich glaube nicht, gibt es eine Möglichkeit ordentlich ein Quadrat Karte auf ein Würfel, während dieselben Eckendaten wiederverwendet werden. Ich würde Ihren Würfel als 6 getrennte Quadrate = 24 Scheitelpunkte anstelle von 8 nachbearbeiten. –

+0

Ich vermute, dass Ihr 'Normalen' Array falsch ist. Können Sie uns zeigen, was der Inhalt Ihres normalen Zeigers ist? Änderst du die Normale für jedes Gesicht? –

+0

Normalen sind irgendwie falsch, aber ich wusste nicht, dass sie Auswirkungen auf Textur Mapping haben .. Ich dachte, dass sie nur die Beleuchtung beeinflussen ... wird es überprüfen.Danke – sinek

Antwort

1

Genau wie andere glaube ich nicht, dass es einen Trick gibt, um Ihre Quad-Texturen auf Dreiecke abzubilden.

Das Hauptproblem, das Sie erleben, liegt in den Unstetigkeiten in den Texturkoordinaten für jede Ecke. Wenn eine Ecke als einige UV-Koordinaten {u, v} für eine Fläche verwendet wird, heißt das nicht, dass sie für die anderen beiden Flächen, die die Ecke teilen, denselben Wert hat. Es ist möglich, eine Zuordnung zu finden, so dass UV an jeder Ecke des Würfels (geteilt durch 3 Flächen) eindeutig ist und alle 4 UV-Werte ({0,0}, {1,0}, {1,1} und {0,1}) sind auf jedem Gesicht vorhanden, aber dann wären einige Texturen vollständig verzerrt. Versuchen Sie, dies auf einem Blatt Papier zu überprüfen: {1,1} ist nicht immer das Gegenteil von {0,0}.

Der einfachste Weg zu beginnen wäre, explizit 6 Quads zu deklarieren, von denen jede aus zwei Dreiecken besteht. Das ergibt insgesamt 24 Vertices (24 Positionen und 24 Tex-Coords, verschachtelt oder nicht) und 36 Indizes (6 Quads aus zwei Dreiecken, 6 * 2 * 3 = 36).

Hier Ihren Code aktualisiert ist ein Würfel angezeigt werden (es könnte einige Wickel Problem sein, damit ich deaktiviert Gesicht sicher sein Culling):

glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
glDisable(GL_CULL_FACE); 

static const float vertices[] = { 
     0.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 0.0f, 

     0.0f, 1.0f, 1.0f, 
     0.0f, 0.0f, 1.0f, 
     1.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 1.0f, 

     0.0f, 1.0f, 1.0f, 
     1.0f, 1.0f, 1.0f, 
     0.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 0.0f, 

     0.0f, 0.0f, 1.0f, 
     0.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 1.0f, 
     1.0f, 0.0f, 0.0f, 

     1.0f, 1.0f, 0.0f, 
     1.0f, 1.0f, 1.0f, 
     1.0f, 0.0f, 0.0f, 
     1.0f, 0.0f, 1.0f, 

     0.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 0.0f, 
     0.0f, 1.0f, 1.0f, 
     0.0f, 0.0f, 1.0f 
     }; 


static const int vertexCnt = 6 * 4; 

static const GLubyte cube[] = { 
    0, 1, 2, 1, 2, 3, 
    4, 5, 6, 5, 6, 7, 
    8, 9, 10, 9, 10, 11, 
    12, 13, 14, 13, 14, 15, 
    16, 17, 18, 17, 18, 19, 
    20, 21, 22, 21, 22, 23 
}; 

static const GLfloat texCoords[] = { 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    0.0f, 1.0f, 

    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    0.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 1.0f, 
    1.0f, 0.0f, 

    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 

    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    0.0f, 1.0f 
    }; 

glClearColor(0.0, 0.0, 0.0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

//glLoadIdentity(); 

//glTranslatef(0.0f, 0.0f, -3.0f); 
glRotatef(3.1415927f, 1.0f, 1.0f, 0.0f); 

glBindTexture(GL_TEXTURE_2D, spriteTexture); 

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
glVertexPointer(3, GL_FLOAT, 0, vertices); 

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cube); 
+0

Können Sie bitte überprüfen, dass ich die Koordinaten in meinem obigen Beispiel richtig abbilde. Übrigens. Danke für die Information! – sinek

+0

Er versucht für jetzt ein einziges Gesicht zu zeichnen. Diskontinuitäten sind nicht das Problem. –

+1

Ja, die Frage wurde bearbeitet (war früher für einen Würfel) ;-) Das Mapping scheint jetzt korrekt zu sein. Wenn also nichts auf dem Bildschirm erscheint, würde ich mit der Deaktivierung von Face Culling und GL_COLOR_MATERIAL beginnen. – Ozirus

1

Ich habe nicht versucht, durch Ihre Eckenlisten Stück, aber meine Vermutung ist, dass Sie Ihre Koordinaten völlig verkorksten und Mapping falsch haben, können Sie Ihr Index Pufferformat falsch angegeben haben, oder Sie haben ein Back-Face-Culling eingeschaltet, und einige Ihrer Eckpunkte sind in der falschen Reihenfolge.

Was die Texturkoordinaten selbst angeht, sollte es keinen Trick geben mit der Zuordnung zu Dreiecken im Vergleich zu Quads. Sie müssen nur 6 Texturkoordinaten haben, wo Sie vorher vier gehabt hätten, da es sechs Ecken gibt (zwei Duplikate pro Gesicht). Sie können möglicherweise Doppelungen vermeiden, indem Sie einen Indexpuffer verwenden, wie Sie es mit Ihrem Würfel haben.

Wie für ein mögliches Rückseitenaussortierungsproblem müssen Sie Ihre Scheitelpunkte jedes Mal in der gleichen Reihenfolge definieren. Alle im Uhrzeigersinn, in Bezug auf die Richtung, in die die Textur zeigt, oder alle gegen den Uhrzeigersinn.

Welche Befehle verwenden Sie zum Einrichten Ihrer OpenGL-Pipeline und welche Befehle verwenden Sie zum Zeichnen dieser Scheitelpunkte? Bitte fügen Sie der Frage den entsprechenden Code hinzu.

Verwandte Themen