2016-03-06 40 views
0

我發現this code sample,我想用現代的opengl做什麼。正字比例縮放opengl視口

我想弄清楚如何用我的代碼做到這一點,但我有一個非常困難的時間。

/* 
* GL03Viewport.cpp: Clipping-area and Viewport 
* Implementing reshape to ensure same aspect ratio between the 
* clipping-area and the viewport. 
*/ 
#include <GL/glut.h> // GLUT, include glu.h and gl.h 

/* Initialize OpenGL Graphics */ 
void initGL() { 
    // Set "clearing" or background color 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque 
} 

void display() { 
    glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer with current clearing color 

    // Define shapes enclosed within a pair of glBegin and glEnd 
    glBegin(GL_QUADS);    // Each set of 4 vertices form a quad 
     glColor3f(1.0f, 0.0f, 0.0f); // Red 
     glVertex2f(-0.8f, 0.1f);  // Define vertices in counter-clockwise (CCW) order 
     glVertex2f(-0.2f, 0.1f);  // so that the normal (front-face) is facing you 
     glVertex2f(-0.2f, 0.7f); 
     glVertex2f(-0.8f, 0.7f); 

     glColor3f(0.0f, 1.0f, 0.0f); // Green 
     glVertex2f(-0.7f, -0.6f); 
     glVertex2f(-0.1f, -0.6f); 
     glVertex2f(-0.1f, 0.0f); 
     glVertex2f(-0.7f, 0.0f); 

     glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray 
     glVertex2f(-0.9f, -0.7f); 
     glColor3f(1.0f, 1.0f, 1.0f); // White 
     glVertex2f(-0.5f, -0.7f); 
     glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray 
     glVertex2f(-0.5f, -0.3f); 
     glColor3f(1.0f, 1.0f, 1.0f); // White 
     glVertex2f(-0.9f, -0.3f); 
    glEnd(); 

    glBegin(GL_TRIANGLES);   // Each set of 3 vertices form a triangle 
     glColor3f(0.0f, 0.0f, 1.0f); // Blue 
     glVertex2f(0.1f, -0.6f); 
     glVertex2f(0.7f, -0.6f); 
     glVertex2f(0.4f, -0.1f); 

     glColor3f(1.0f, 0.0f, 0.0f); // Red 
     glVertex2f(0.3f, -0.4f); 
     glColor3f(0.0f, 1.0f, 0.0f); // Green 
     glVertex2f(0.9f, -0.4f); 
     glColor3f(0.0f, 0.0f, 1.0f); // Blue 
     glVertex2f(0.6f, -0.9f); 
    glEnd(); 

    glBegin(GL_POLYGON);   // These vertices form a closed polygon 
     glColor3f(1.0f, 1.0f, 0.0f); // Yellow 
     glVertex2f(0.4f, 0.2f); 
     glVertex2f(0.6f, 0.2f); 
     glVertex2f(0.7f, 0.4f); 
     glVertex2f(0.6f, 0.6f); 
     glVertex2f(0.4f, 0.6f); 
     glVertex2f(0.3f, 0.4f); 
    glEnd(); 

    glFlush(); // Render now 
} 

/* Handler for window re-size event. Called back when the window first appears and 
    whenever the window is re-sized with its new width and height */ 
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer 
    // Compute aspect ratio of the new window 
    if (height == 0) height = 1;    // To prevent divide by 0 
    GLfloat aspect = (GLfloat)width/(GLfloat)height; 

    // Set the viewport to cover the new window 
    glViewport(0, 0, width, height); 

    // Set the aspect ratio of the clipping area to match the viewport 
    glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix 
    glLoadIdentity();    // Reset the projection matrix 
    if (width >= height) { 
    // aspect >= 1, set the height from -1 to 1, with larger width 
     gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0); 
    } else { 
     // aspect < 1, set the width to -1 to 1, with larger height 
    gluOrtho2D(-1.0, 1.0, -1.0/aspect, 1.0/aspect); 
    } 
} 

/* Main function: GLUT runs as a console application starting at main() */ 
int main(int argc, char** argv) { 
    glutInit(&argc, argv);   // Initialize GLUT 
    //glutInitWindowSize(640, 480); // Set the window's initial width & height - non-square 
    glutInitWindowSize(1024, 720); // Set the window's initial width & height - non-square 
    glutInitWindowPosition(50, 50); // Position the window's initial top-left corner 
    glutCreateWindow("Viewport Transform"); // Create window with the given title 
    glutDisplayFunc(display);  // Register callback handler for window re-paint event 
    glutReshapeFunc(reshape);  // Register callback handler for window re-size event 
    initGL();      // Our own OpenGL initialization 
    glutMainLoop();     // Enter the infinite event-processing loop 
    return 0; 
} 

有兩個機會,我對我的代碼有兩個原因。 1)我想有0,0是左下角,寬度,高度是右上角。

2)第二個更令人困惑的部分是如何保持我的像素座標。示例代碼使用範圍在-1.0到1.0的點,但我希望能夠說我的四邊形是50px×50px。

當前我創建了像這樣的視口和投影。

point3 eye, center; 
    vec3 up; 
    vmathP3MakeFromElems(&eye, 0, 0, 0); 
    vmathP3MakeFromElems(&center, 0, 0, -1); 
    vmathV3MakeFromElems(&up, 0, 1, 0); 
    vmathM4MakeLookAt(&v_mat, &eye, &center, &up); 

    vec3 trans; 
    vmathV3MakeFromElems(&trans, 0, 0, -20); 
    vmathM4MakeTranslation(&v_mat, &trans); 

    glViewport(0, 0, width, height); 
    vmathM4MakeOrthographic(&p_mat, 0, width, 0, height, 1, 100); 

我現在畫的是像這樣定義1四:

//3 position, 4 color, 2 texture coordinates 
float v_data[] = {-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 
      -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 
      1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f}; 

short i_data[] = {0, 1, 2, 0, 2, 3}; 

,我設置它的模型矩陣是這樣的:

vmathV3MakeFromElems(&out->scale, texture->width * 0.5f, texture->height * 0.5f, 1); 
vmathM4SetElem(&out->model_mat, 0, 0, out->scale.x); 
vmathM4SetElem(&out->model_mat, 1, 1, out->scale.y); 
vmathM4SetElem(&out->model_mat, 2, 2, 1); 
vmathM4SetElem(&out->model_mat, 3, 3, 1); 

vmathM4SetElem(&out->model_mat, 3, 0, (out->scale.x) - (x)); 
vmathM4SetElem(&out->model_mat, 3, 1, (out->scale.y) + (y)); 

所以我怎麼能做到視縮放像示例代碼,但能夠使用像素[這可能是錯誤的方法,我不確定]。

頂部的示例代碼可以複製粘貼並使用此命令構建。

gcc -lglut -lGLU -lGL -o glsample glsample.c && ./glsample 

回答

0
vmathM4MakeOrthographic(&p_mat, 0, width, 0, height, 1, 100); 

比方說,這條線後p_mat將舉行這樣的矩陣:

|1/width     | -> p_mat[0][0] 
|   1/height  | -> p_mat[1][1] 
|     .... | 
|      | 

這應該確保,如果寬度和高度以像素爲單位,你會保持你的像素完美的比例。 你提供的第一樣本,然而,使用

gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0); 

不考慮屏幕寬度和高度(僅在它們之間的縱橫比),你將具有均勻的單元規模。

基本上,通過在投影矩陣(p_mat[0][0] & p_mat[1][1])中劃分或乘以這兩個分量(通過保留方面的相同數量),可以縮放視口。要達到像素完美的比例,只需將它們設置爲1 /寬度和1 /高度。