2016-03-06 38 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 /高度。