opengl es 2.0游戏与图形编程——2.设置图形投影
来源:互联网 发布:淘宝里的运费险怎么退 编辑:程序博客网 时间:2024/05/22 18:46
注意:本文是读书笔记,代码是使用书中sdk的,主要掌握重点知识,别在意小细节
1.两种投影:正交投影(2d,但可使用z,只是透视完全基于当前屏幕比),透视投影(3d)
2.初始设置矩阵
模型视图矩阵:物体空间 -> (模型)世界空间 ->(视图) 摄像机空间
拓展:
[视图变换] 当摄像机的位置和朝向任意时,投影变换及气体类型的变换变得困难。为了简化运算,我们将摄像机变化到世界坐标系原点,并旋转使摄像机的 光轴和世界坐标系z轴正方向一致。 视图变换是从世界坐标系到摄像机坐标系的变换,计算就是将摄像机弄回原点并对齐z轴的变换(也可以是将摄像机从坐标轴原点移动到摄像机当前位置的 逆变换)。 许多计算都在眼睛坐标系中完成,一个常用的就是光照需要在这个空间中实现,因为眼睛位置决定了光照效果,否则的话,很难实现镜面光。因此我们需要将法线坐标转换到眼睛坐标系中。 标准向量(Normal vectors)——从对象坐标系(Object coordinates)变换到视觉坐标系(eye coordinates),它是用来计算光照(lighting calculation)的.注意标准向量(Normal vectors)的变换和顶点的不同。其中视觉矩阵(view matrix)是GL_MODELVIEW逆矩阵的转置矩阵和标准向量(Normal vector是)相乘所得。代码:
GFX_set_matrix_mode( MODELVIEW_MATRIX );GFX_load_identity(); vec3 e = {0.0f, -3.0f, 0.0f}, c = {0.0f, 0.0f, 0.0f}, u = {0.0f, 0.0f, 1.0f}; GFX_look_at(&e, &c, &u); static float y = 0.0f; y += 0.1f; GFX_translate(0.0f, y, 0.0f); GFX_rotate(y * 50.0f, 1.0f, 1.0f, 1.0f);
投影矩阵:摄像机空间 -> 裁减空间(视锥空间)
// 2d GFX_set_orthographic((float)height / (float)width, 5.0f, (float)width / (float)height, 1.0f, 100.0f, 0.0f); // 3d GFX_set_perspective(45.0f, (float)width / (float)height, 0.01f, 100.0f, 0.0f);
3.使用着色器
program = PROGRAM_init( ( char * )"default" );program->vertex_shader = SHADER_init( VERTEX_SHADER, GL_VERTEX_SHADER ); program->fragment_shader = SHADER_init( FRAGMENT_SHADER, GL_FRAGMENT_SHADER );m = mopen( VERTEX_SHADER, 1 );if( m ) {if( !SHADER_compile( program->vertex_shader, ( char * )m->buffer, DEBUG_SHADERS ) ) exit( 1 );}m = mclose( m );m = mopen( FRAGMENT_SHADER, 1 );if( m ) {if( !SHADER_compile( program->fragment_shader, ( char * )m->buffer, DEBUG_SHADERS ) ) exit( 2 ); } m = mclose( m ); if( !PROGRAM_link( program, DEBUG_SHADERS ) ) exit( 3 );上面创建了一个着色器程序,并读取和编译了顶点着色器和片段着色器,然后链接了这个着色器程序。
下面是绘制时的代码:
if( program->pid ) {char attribute, uniform;glUseProgram( program->pid );uniform = PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" );glUniformMatrix4fv( uniform,1 /* How many 4x4 matrix */,GL_FALSE /* Transpose the matrix? */, <span style="white-space:pre"></span>( float * )GFX_get_modelview_projection_matrix() );attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"POSITION" );glEnableVertexAttribArray( attribute );glVertexAttribPointer( attribute, 3, GL_FLOAT, GL_FALSE, 0, POSITION );attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"COLOR" );glEnableVertexAttribArray( attribute );glVertexAttribPointer( attribute, 4, GL_FLOAT, GL_FALSE, 0, COLOR );glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );}先使用来该着色器程序,获取其中定义的全局uniform变量 MODELVIEWPROJECTION 的地址location,并设置其值。
同理设置了要绘制的顶点多两个属性的值(数组),属性值如下:
static const float POSITION[ 12 ] = {-0.5f, 0.0f, -0.5f, // Down left (pivot point)0.5f, 0.0f, -0.5f, // Up left-0.5f, 0.0f, 0.5f, // Down right0.5f, 0.0f, 0.5f // Up right};static const float COLOR[ 16 ] = {1.0f, 0.0f, 0.0f, 1.0f, // Red0.0f, 1.0f, 0.0f, 1.0f, // Green0.0f, 0.0f, 1.0f, 1.0f, // Blue1.0f, 1.0f, 0.0f, 1.0f // Yellow};设置好变量和值后就提交渲染了。
4.着色器代码
顶点着色器:
uniform mediump mat4 MODELVIEWPROJECTIONMATRIX;attribute mediump vec4 POSITION;attribute lowp vec4 COLOR;varying lowp vec4 color;void main( void ) {gl_Position = MODELVIEWPROJECTIONMATRIX * POSITION;color = COLOR;}主要就是把cpp里传来的顶点位置属性 左乘了 模型视图 投影矩阵,即被变换到裁剪空间了,并用gl_Position输出。然后给片段着色器传递了一个color变量(varying标记)。
片段着色器:
varying lowp vec4 color;void main( void ) {gl_FragColor = color;}直接输出顶点着色器传来的颜色值。
最终效果如下:
5.看下cocos2dx
设置矩阵:
case Projection::_2D: { loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); Mat4 orthoMatrix; Mat4::createOrthographicOffCenter(0, size.width, 0, size.height, -1024, 1024, &orthoMatrix); multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, orthoMatrix); loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); break; } case Projection::_3D: { float zeye = this->getZEye(); Mat4 matrixPerspective, matrixLookup; loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); // issue #1334 Mat4::createPerspective(60, (GLfloat)size.width/size.height, 10, zeye+size.height/2, &matrixPerspective); multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixPerspective); Vec3 eye(size.width/2, size.height/2, zeye), center(size.width/2, size.height/2, 0.0f), up(0.0f, 1.0f, 0.0f); Mat4::createLookAt(eye, center, up, &matrixLookup); multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixLookup); loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); break; }默认是3d方式,投影矩阵里已经乘了一个往屏幕中心看的摄像机矩阵了。
节点的模型视图矩阵:
Mat4 Node::transform(const Mat4& parentTransform){ return parentTransform * this->getNodeToParentTransform();}这个会传递给渲染命令RenderCommand使用,比如:
void TrianglesCommand::useMaterial() const{ //Set texture GL::bindTexture2D(_textureID); //set blend mode GL::blendFunc(_blendType.src, _blendType.dst); _glProgramState->apply(_mv);}被着色器程序状态ProgramState作为内置的全局变量CC_MVMatrix (还有类似的CC_MVPMatrix)传递给其着色器代码使用。
着色器代码:
const char* ccPositionColor_vert = STRINGIFY(attribute vec4 a_position;attribute vec4 a_color;\n#ifdef GL_ES\nvarying lowp vec4 v_fragmentColor;\n#else\nvarying vec4 v_fragmentColor;\n#endif\nvoid main(){ gl_Position = CC_MVPMatrix * a_position; v_fragmentColor = a_color;});
const char* ccPositionColor_frag = STRINGIFY(\n#ifdef GL_ES\nprecision lowp float;\n#endif\nvarying vec4 v_fragmentColor;void main(){ gl_FragColor = v_fragmentColor;});
0 0
- opengl es 2.0游戏与图形编程——2.设置图形投影
- OpenGL ES(2)——定义图形
- OpenGL ES(3)——绘制图形
- OpenGL视口和投影的关系——设置图形不变形
- OPENGL ES 图形管道
- OpenGL基础图形编程—OpenGL变换
- 图形编程之 OpenGL ES 2.0 —— 从我们的世界到他们的世界 (1)
- 图形编程之 OpenGL ES 2.0 —— 从我们的世界到他们的世界 (2)
- 图形编程之 OpenGL ES 2.0 —— 从我们的世界到他们的世界 (4)
- 图形编程之 OpenGL ES 2.0 —— 从我们的世界到他们的世界 (5)
- 图形编程之 OpenGL ES 2.0 —— 从我们的世界到他们的世界 (3)
- OpenGL es 2.0 实战 - 渲染图形变形
- OpenGL基础图形编程 - OpenGL与3D图形世界
- OpenGL基础图形编程 - OpenGL与3D图形世界
- Android 图形 II-OpenGL ES
- 使用OpenGL ES显示图形
- 动画和图形:OpenGL ES
- opengl es glEnable 方法设置图形显示能力
- threshold函数
- POJ 1062 昂贵的聘礼(dijkstra)
- SpringMVC之@RequestBody, @ResponseBody
- 2016 阿里校招笔试应用题总结
- jQuery 浏览器版本判断BUG
- opengl es 2.0游戏与图形编程——2.设置图形投影
- thinking in java学习笔记(二)
- 关于枚举enum
- zjnu(1182)——能量项链
- hdoj 2824 The Euler function 【欧拉函数】
- js apply/call/caller/callee/bind使用方法与区别分析
- hdoj.1759 Matrix Revolution【矩阵快速幂->逆思维】 2015/08/24
- HDOJ 1074.Doing Homework(状态压缩DP)
- 重启adb连接