2011-11-13 12 views
21

estoy tratando de entender lo que hace el código siguiente:GLM :: perspectiva explicación

glm::mat4 Projection = glm::perspective(35.0f, 1.0f, 0.1f, 100.0f); 

¿Crea un projection matrix? ¿Quita todo lo que no está en la vista del usuario? yo no era capaz de encontrar nada en el API page, y lo único que pude encontrar en el PDF en su página web era la siguiente:

gluPerspective:

glm::mat4 perspective(float fovy, float aspect, float zNear, 
float zFar); 
glm::dmat4 perspective(
double fovy, double aspect, double zNear, 
double zFar); 
From GLM_GTC_matrix_transform extension: <glm/gtc/matrix_transform.hpp> 

Pero no explica los parámetros . Tal vez me perdí algo.

Respuesta

21

Crea una matriz de proyección, es decir, la matriz que describe el conjunto de ecuaciones lineales que transforma vectores del espacio del ojo en el espacio del clip. Las matrices realmente no son magia negra. En el caso de OpenGL que resultan ser un arreglo de 4 por 4 de los números:

X_x Y_x Z_x T_x 
X_y Y_y Z_y T_y 
X_z Y_z Z_z T_z 
X_w Y_w Z_w W_w 

Usted puede multply un 4-vector por una matriz de 4 × 4:

v' = M * v 

v'_x = M_xx * v_x + M_yx * v_y + M_zx * v_z + M_tx * v_w 
v'_y = M_xy * v_x + M_yy * v_y + M_zy * v_z + M_ty * v_w 
v'_z = M_xz * v_x + M_yz * v_y + M_zz * v_z + M_tz * v_w 
v'_w = M_xw * v_x + M_yw * v_y + M_zw * v_z + M_tw * v_w 

Después de alcanzar el clip espacio (es decir, después del paso de proyección), se recortan las primitivas. Los vértices resultantes del recorte son luego sometidos a la brecha perspectiva, es decir,

v'_x = v_x/v_w 
v'_y = v_y/v_w 
v'_z = v_z/v_w 
(v_w = 1 = v_w/v_w) 

y eso es todo. En realidad, no pasa nada en todos esos pasos de transformación que la multiplicación ordinaria de matriz-vector.

Lo bueno de esto es que las matrices se pueden usar para describir la alineación relativa de un sistema de coordenadas dentro de otro sistema de coordenadas. Lo que hace la transformación de perspectiva es que permite que los vértices z-valores "se deslicen" en sus valores w proyectados también. Y por la perspectiva divida una no unidad w causará "distorsión" de las coordenadas de los vértices. Los vértices con una z pequeña se dividirán por una pequeña w, por lo tanto, sus coordenadas "explotarán", mientras que los vértices con una z grande se "exprimirán", que es lo que está causando el efecto de perspectiva.

0

Esta es una versión independiente c de la misma función. Esta es aproximadamente una versión de copiar y pegar de the original.

# include <math.h> 
# include <stdlib.h> 
# include <string.h> 

typedef struct s_mat { 
    float *array; 
    int width; 
    int height; 
} t_mat; 

t_mat *mat_new(int width, int height) 
{ 
    t_mat *to_return; 

    to_return = (t_mat*)malloc(sizeof(t_mat)); 
    to_return->array = malloc(width * height * sizeof(float)); 
    to_return->width = width; 
    to_return->height = height; 
    return (to_return); 
} 

void mat_zero(t_mat *dest) 
{ 
    bzero(dest->array, dest->width * dest->height * sizeof(float)); 
} 

void mat_set(t_mat *m, int x, int y, float val) 
{ 
    if (m == NULL || x > m->width || y > m->height) 
     return ; 
    m->array[m->width * (y - 1) + (x - 1)] = val; 
} 

t_mat *mat_perspective(float angle, float ratio, 
     float near, float far) 
{ 
    t_mat *to_return; 
    float tan_half_angle; 

    to_return = mat_new(4, 4); 
    mat_zero(to_return); 
    tan_half_angle = tan(angle/2); 
    mat_set(to_return, 1, 1, 1/(ratio * tan_half_angle)); 
    mat_set(to_return, 2, 2, 1/(tan_half_angle)); 
    mat_set(to_return, 3, 3, -(far + near)/(far - near)); 
    mat_set(to_return, 4, 3, -1); 
    mat_set(to_return, 3, 4, -(2 * far * near)/(far - near)); 
    return (to_return); 
}