OpenGL Transformation
以下图片和部分内容来源:
(1、http://www.songho.ca/opengl/gl_transform.html
2、http://www.antongerdelan.net/opengl/index.html
3、opengl 官网论坛)
opengl顶点从模型到窗口坐标的变换过程,原来一直对NDC到屏幕有疑惑,看到国外一个讲opengl的博客,结合另外的网站和博客,先记录下,回头再添加详细的说明。
OpenGL vertex transformation
下图是对OpenGL Vertex Transfermation 的详细图解。
上图的代码表述:
glViewport(0,0,1280,720);
vec3 someVtx=vec3(5,6,7);
mat4 mPerspective = mat4::perspective(45.0f,...);
mat4 mView = mat4::lookat(...);
mat4 mModel = ...;
mat4 MVP = mPerspective*mView * mModel;
//--------[ GPU side !!! ]-------------------[
vec4 CLIPSPACE = MVP * vec4(someVtx,1.0f); // vertex shader!!
// this CLIPSPACE var is known as gl_Position
//------[ stuff out of your control ]-------[
vec3 NDC = vec3(CLIPSPACE.xyz/CLIPSPACE.w);
// well, you can tweak some of the numbers here,
// i.e with glViewport()
float screenX = (NDC.x *0.5+0.5)*1280;
float screenY = (NDC.y *0.5+0.5)*720;
//------------------------------------------/
//-------------------------------------------/
//=============================================================================================//
//上述代码中mModel 、mView 和 mPerspective 的生成。
mModel:mModel Matrix主要对模型本身进行空间变化,比较直观,不多说明。
mView:mView Matrix 的图解
View Matrix:
// minimal implementation of Vector3 struct
struct Vector3
{
float x;
float y;
float z;
Vector3() : x(0), y(0), z(0) {}; // constructors
Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
// functions
Vector3& normalize(); //
Vector3 operator-(const Vector3& rhs) const; // subtract rhs
Vector3 operator*(const Vector3& rhs) const; // cross product
Vector3& operator*=(const float scale); // scale and update itself
};
Vector3& Vector3::normalize() {
float invLength = 1 / sqrtf(x*x + y*y + z*z);
x *= invLength;
y *= invLength;
z *= invLength;
return *this;
}
Vector3 Vector3::operator-(const Vector3& rhs) const {
return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
}
Vector3 Vector3::cross(const Vector3& rhs) const {
return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
}
///
// compute transform axis from object position and target point
///
void lookAtToAxes(const Vector3& position, const Vector3& target,
Vector3& left, Vector3& up, Vector3& forward)
{
// compute the forward vector
forward = target - position;
forward.normalize();
// compute temporal up vector based on the forward vector
// watch out when look up/down at 90 degree
// for example, forward vector is on the Y axis
if(fabs(forward.x) < EPSILON && fabs(forward.z) < EPSILON)
{
// forward vector is pointing +Y axis
if(forward.y > 0)
up = Vector3(0, 0, -1);
// forward vector is pointing -Y axis
else
up = Vector3(0, 0, 1);
}
// in general, up vector is straight up
else
{
up = Vector3(0, 1, 0);
}
// compute the left vector
left = up.cross(forward); // cross product
left.normalize();
// re-calculate the orthonormal up vector
up = forward.cross(left); // cross product
up.normalize();
}
///
// compute transform axis from object position, target and up direction
///
void lookAtToAxes(const Vector3& pos, const Vector3& target, const Vector3& upDir,
Vector3& left, Vector3& up, Vector3& forward)
{
// compute the forward vector
forward = target - pos;
forward.normalize();
// compute the left vector
left = upDir.cross(forward); // cross product
left.normalize();
// compute the orthonormal up vector
up = forward.cross(left); // cross product
up.normalize();
}
mPerspective:mPerspective Martix 说明图