2016-04-06 10 views
1

Der folgende Code zeichnet ein Rechteck im 2D-Bildschirmbereich mit OpenGL ES2. Wie verschiebt man die Zeichnung des Rechtecks ​​um 1 Pixel nach rechts, ohne die Eckpunkte zu verändern?OpenGL Orthographische Projektion und Translate

Insbesondere versuche ich, die Koordinaten 0,5 Pixel nach rechts zu verschieben. Ich musste dies vorher mit GLES1.x machen und der Grund dafür war, dass ich Probleme hatte, Zeilen an der richtigen Stelle zu zeichnen, es sei denn, ich habe eine glTranslate() mit 0.5f erstellt.

Ich bin verwirrt über die Verwendung von Glm :: translate() im folgenden Code.

Wenn ich eine Übersetzung von 0.5f versuche, bewegt sich das ganze Rechteck von der linken Seite des Bildschirms in die Mitte - ein Sprung von etwa 200 Pixel.

Ich bekomme das gleiche Ergebnis, ob ich eine Glm :: Translate auf dem Modell oder der View-Matrix.

Ist die Reihenfolge der Matrixmultiplikation falsch und was sollte sie sein?

short g_RectFromTriIndices[] = 
{ 
    0, 1, 2, 
    0, 2, 3 

}; // The order of vertex rendering. 

GLfloat g_AspectRatio = 1.0f; 


//-------------------------------------------------------------------------------------------- 
// LoadTwoTriangleVerticesForRect() 
//-------------------------------------------------------------------------------------------- 
void LoadTwoTriangleVerticesForRect(GLfloat *pfRectVerts, float fLeft, float fTop, float fWidth, float fHeight) 
{ 
    pfRectVerts[ 0 ] = fLeft; 
    pfRectVerts[ 1 ] = fTop; 
    pfRectVerts[ 2 ] = 0.0; 

    pfRectVerts[ 3 ] = fLeft + fWidth; 
    pfRectVerts[ 4 ] = fTop; 
    pfRectVerts[ 5 ] = 0.0; 

    pfRectVerts[ 6 ] = fLeft + fWidth; 
    pfRectVerts[ 7 ] = fTop + fHeight; 
    pfRectVerts[ 8 ] = 0.0; 

    pfRectVerts[ 9 ] = fLeft; 
    pfRectVerts[ 10 ] = fTop + fHeight; 
    pfRectVerts[ 11 ] = 0.0; 
} 

//-------------------------------------------------------------------------------------------- 
// Draw() 
//-------------------------------------------------------------------------------------------- 
void Draw(void) 
{ 
    GLfloat afRectVerts[ 12 ]; 

    //LoadTwoTriangleVerticesForRect(afRectVerts, 0, 0, g_ScreenWidth, g_ScreenHeight); 
    LoadTwoTriangleVerticesForRect(afRectVerts, 50, 50, 100, 100); 

    // Correct for aspect ratio so squares ARE squares and not rectangular stretchings.. 
    g_AspectRatio = (GLfloat) g_ScreenWidth/(GLfloat) g_ScreenHeight; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    GLuint hPosition = glGetAttribLocation(g_SolidProgram, "vPosition"); 

    // PROJECTION 
    glm::mat4 Projection = glm::mat4(1.0); 
    // Projection = glm::perspective(45.0f, g_AspectRatio, 0.1f, 100.0f); 

    // VIEW 
    glm::mat4 View = glm::mat4(1.0); 

    static GLfloat transValY = 0.5f; 
    static GLfloat transValX = 0.5f; 

    //View = glm::translate(View, glm::vec3(transValX, transValY, 0.0f)); 

    // MODEL 
    glm::mat4 Model = glm::mat4(1.0); 

    // static GLfloat rot = 0.0f; 

    // rot += 0.001f; 
    // Model = glm::rotate(Model, rot, glm::vec3(0.0f, 0.0f, 1.0f)); // where x, y, z is axis of rotation (e.g. 0 1 0) 

    glm::mat4 Ortho = glm::ortho(0.0f, (GLfloat) g_ScreenWidth, (GLfloat) g_ScreenHeight, 0.0f, 0.0f, 1000.0f); 

    glm::mat4 MVP; 

    MVP = Projection * View * Model * Ortho; 

    GLuint hMVP; 

    hMVP = glGetUniformLocation(g_SolidProgram, "MVP"); 
    glUniformMatrix4fv(hMVP, 1, GL_FALSE, glm::value_ptr(MVP)); 

    glEnableVertexAttribArray(hPosition); 

    // Prepare the triangle coordinate data 
    glVertexAttribPointer(hPosition, 3, GL_FLOAT, FALSE, 0, afRectVerts); 

    // Draw the rectangle using triangles 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, g_RectFromTriIndices); 

    glDisableVertexAttribArray(hPosition); 
} 

Hier ist die Vertex-Shader-Quelle:

attribute vec4 vPosition; 

uniform mat4 MVP; 

void main() 
{ 
    gl_Position = MVP * vPosition; 
} 

UPDATE: Ich finde die folgende Matrix-Multiplikation mir bessere Ergebnisse gibt. Ich weiß nicht, ob diese „richtige“ ist oder nicht aber:

MVP = Ortho * Model * View * Projection; 

Antwort

1

Das MVP mir wirklich seltsam scheint, sollten Sie nicht mehr als 4 Dinge müssen es in Ihrem MVP zu bekommen .. Ihre Projektions-Matrix sollte nur derjenige sein, der Orthogonal, so in diesem Fall

MVP = Projection * View * Ortho;

Aber ich kann auch sehen, dass Ihre Projektions-Matrix aus Sicht kommentiert worden ist, so glaube nicht, dass ich es viel im Moment tut.

Mit den Geräuschen, da Sie wollen, dass die Modellkoordinaten während der Bewegung gleich bleiben, möchten Sie Ihre Kamera richtig bewegen? Also (indem Sie sehen, dass Ihre Scheitelpunkte einen Koordinatenbereich von 1 Einheit pro Pixel verwenden), wenn Sie eine Verschiebung von 0.5f auf Ihre Ansicht vornehmen, verschiebt sich die Hälfte Ihres Projektionsraums. Stattdessen möchten Sie etwas wie eine Camera Klasse haben, die Sie Ihre View aus der Verwendung der X und Y Positionen der Kamera bekommen.

Dann können Sie Ihre Ansicht Matrix mit der Kamera Position, die das Welteinheitensystem teilen können, die Sie verwenden, die 1 Einheit pro Pixel ist.

glm::mat4 view; 
view = glm::lookAt(glm::vec3(camX, camY, 0.0), glm::vec3(0.0, 0.0, 0.0),glm::vec3(0.0, 1.0, 0.0)); 

riss ich diese Zeile gerade (minus Camz für Camy Wechsel) von einem wirklich guten 3D-Tutorial auf Kamera here aber genau das gleiche Konzept kann stattdessen

auf eine orthogonale Kamera angewendet werden, ich weiß, es ist ein bisschen Mehr Aufwand, aber eine Cmaera-Klasse, die Sie auf diese Weise steuern können, ist schöner Praxis als manuell mit Glm :: translate, drehen & Maßstab, um Ihre Ansichtsfenster zu steuern (und es können Sie sicherstellen, dass Sie mit einem mehr objektiven Koordinatensystem arbeiten zwischen Ihrer Kamera und den Modellen Koordinatenpunkten

Verwandte Themen