openGL ES 图形绘制(详解)

来源:互联网 发布:mac怎么免费下载软件 编辑:程序博客网 时间:2024/05/17 08:59

一步一个脚印,21天基本掌握opengl es。
图形绘制效果图:
这里写图片描述
OpenGL ES 是强大的图形处理工具,他是基于底层C代码实现的,直接作用于GPU,处理速度十分快速。
这里写图片描述
主要写代码的位置是templateApp.cpp

#include "templateApp.h"TEMPLATEAPP templateApp = { templateAppInit,                            templateAppDraw ,};//定义顶点着色器文件 vertex  shader着色器#define VERTEX_SHADER ( char * )"vertex.glsl"//定义片段着色器文件 fragment片段#define FRAGMENT_SHADER ( char * )"fragment.glsl"//定义一个是否启用着色器的标志 启用ON(1)#define DEBUG_SHADERS 1//用来管理所有着色器程序的空白PROGRAM结构PROGRAM *program = NULL;//声明MEMORY结构指针  使用MEMORY指针结构从磁盘中读取着色器文件MEMORY *m = NULL;
//开启gles的初始化过程,,,非常好用//用当前屏幕尺寸设置GL视区//使用GFX_set_matrix 模式功能告诉GFX实现过程重点关注投影矩阵,以便建立2D模型
 atexit( templateAppExit );    GFX_start();    glViewport( 0, 0, width, height );    GFX_set_matrix_mode( PROJECTION_MATRIX );    {        //声明两个用来保存屏幕宽度和高度一半值得临时float变量        float half_width = (float)width * 0.5f ,half_height = (float)height * 0.5f;        //确保当前矩阵是干净的 使用下面的函数来加载单位矩阵        GFX_load_identity();        //到目前为止我们已经做好了设置2D屏幕投影的准备。。。为此需要使用GFX_set_orthographic_2d函数,并传入屏幕尺寸的一半(正方向和负方向)。        GFX_set_orthographic_2d(-half_width, half_width, -half_height, half_height);        //该操作 将使用GL单元与屏幕像素之间1:1的比例,在屏幕中心定位投影矩阵的原点        //接下来为了符合OGL,需要将矩阵转换到屏幕的左下角,如下所示:        GFX_translate(-half_width, -half_height, 0.0f);        glDisable(GL_DEPTH_TEST);        glDepthMask( GL_FALSE);    }

//GL的以左下角为坐标原点
由于有时候我们并不需要深度缓冲区,因为大多数情况下,使用该类型时只需要重写颜色缓冲区,所以关闭深度缓冲区
//由于深度颜色缓冲区被关闭,所以还需要关闭深度掩码

//链接顶点和片段着色器

//初始化 program变量指针

program = PROGRAM_init((char *)"default");    //创建一个新的顶点和片段SHADER指针    program->vertex_shader = SHADER_init(VERTEX_SHADER, GL_VERTEX_SHADER);    program->fragment_shader = SHADER_init(FRAGMENT_SHADER,GL_FRAGMENT_SHADER);    //为了能够从磁盘中加载所创建的着色器,需在内存中加载相关内容,为此童颜需要MEMORY结构    m = mopen(VERTEX_SHADER, 1);    //进行指针检查    if( m ) {        //对包含在MEMORY缓冲区指针中的顶点着色器代码进行编译,为此我们,将代码传递到SHADER_compile函数        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 );

//到目前,我们已经成功变异顶点和片段着色器,并做好链接到着色器PROGRAM的准备。
//为了完成顶点和片段着色器的最终链接片段,可以调用PROGRAM_link函数

 if( !PROGRAM_link( program, DEBUG_SHADERS ) ) exit( 3 );

//1 准备框架

//声明一些2D位置,然后将这些顶点连接在一起,从而在屏幕上绘制一个正方形。
static const float POSITION[8] = {        0.0f,0.0f,//下 左        1.0f,0.0f,//上 左        0.0f,1.0f,//下右        1.0,1.0 //上 右    };    //声明顶点颜色    static const float COLOR[16] = {        1.0f /* R*/,0.0/*G*/,0.0f/*B*/,1.0f/*alpha*/,/*Red*/        0.0f,1.0f,0.0f,1.0f,//Green        0.0f,0.0f,1.0f,1.0f,//Blue        1.0f,1.0f,0.0f,1.0f//Yellow    };

//构建应用程序的渲染循环,首先指定用来清理颜色缓冲区的颜色值(灰色),在glclear函数调用之前插入:

 glClearColor(0.5f, 0.5f, 0.5f, 1.0f);    glClear(  GL_COLOR_BUFFER_BIT );

//放大

GFX_set_matrix_mode(MODELVIEW_MATRIX);    GFX_load_identity();    GFX_scale(300, 300.f, 0.0f);

//GLES索引从1开始
//声明两个用来保存顶点属性和统一位置的临时变量

 if(program->pid){        char attribute, uniform;        //为了能够架起应用程序数据与GPU数据之间的桥梁,需要使用这些同一位置        //现在必须告诉GPU你讲使用那个程序来绘图        glUseProgram(program->pid);        //从视频存储器中检索uniform的位置        uniform = PROGRAM_get_uniform_location(program, (char *)"MODELVIEWPROJECTIONMATRIX");        //GPU更新数据        glUniformMatrix4fv(uniform, 1,  GL_FALSE, (float *)GFX_get_modelview_projection_matrix());        //处理顶点属性,检索顶点位置        attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"POSITION");        //告诉GLES可以使用顶点位置属性了        glEnableVertexAttribArray(attribute);        //告诉GLES 需使用该属性的那些数据        glVertexAttribPointer(attribute, 2, GL_FLOAT, GL_FALSE, 0, POSITION);        //对COLOR数组执行相同操作        attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"COLOR");        glEnableVertexAttribArray(attribute);        glVertexAttribPointer(attribute, 4, GL_FLOAT, GL_FALSE, 0, COLOR);        //调用alDrawArrays,告诉CPU使用特定模式绘制相应数据,并告诉使用多少数据:        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    }对于片段以及顶点着色器文件:评论有资源链接
    //为了安全    GFX_error();

最后附上完整代码:

/*CSDNCopyright (C) 2016 xoxo_x*/#include "templateApp.h"TEMPLATEAPP templateApp = { templateAppInit,                            templateAppDraw ,};//定义顶点着色器文件 vertex  shader着色器#define VERTEX_SHADER ( char * )"vertex.glsl"//定义片段着色器文件 fragment片段#define FRAGMENT_SHADER ( char * )"fragment.glsl"//定义一个是否启用着色器的标志 启用ON(1)#define DEBUG_SHADERS 1//用来管理所有着色器程序的空白PROGRAM结构PROGRAM *program = NULL;//声明MEMORY结构指针  使用MEMORY指针结构从磁盘中读取着色器文件MEMORY *m = NULL;void templateAppInit( int width, int height ){    atexit( templateAppExit );    GFX_start();//开启gles的初始化过程,,,非常好用    //用当前屏幕尺寸设置GL视区    glViewport( 0, 0, width, height );    //使用GFX_set_matrix 模式功能告诉GFX实现过程重点关注投影矩阵,以便建立2D模型    GFX_set_matrix_mode( PROJECTION_MATRIX );    {        //声明两个用来保存屏幕宽度和高度一半值得临时float变量        float half_width = (float)width * 0.5f ,half_height = (float)height * 0.5f;        //确保当前矩阵是干净的 使用下面的函数来加载单位矩阵        GFX_load_identity();        //到目前为止我们已经做好了设置2D屏幕投影的准备。。。为此需要使用GFX_set_orthographic_2d函数,并传入屏幕尺寸的一半(正方向和负方向)。        GFX_set_orthographic_2d(-half_width, half_width, -half_height, half_height);        //该操作 将使用GL单元与屏幕像素之间1:1的比例,在屏幕中心定位投影矩阵的原点        //接下来为了符合OGL,需要将矩阵转换到屏幕的左下角,如下所示:        GFX_translate(-half_width, -half_height, 0.0f);        //GL的以左下角为坐标原点        //由于有时候我们并不需要深度缓冲区,因为大多数情况下,使用该类型时只需要重写颜色缓冲区,所以关闭深度缓冲区        glDisable(GL_DEPTH_TEST);        //由于深度颜色缓冲区被关闭,所以还需要关闭深度掩码        glDepthMask( GL_FALSE);    }    //链接顶点和片段着色器    //初始化 program变量指针    program = PROGRAM_init((char *)"default");    //创建一个新的顶点和片段SHADER指针    program->vertex_shader = SHADER_init(VERTEX_SHADER, GL_VERTEX_SHADER);    program->fragment_shader = SHADER_init(FRAGMENT_SHADER,GL_FRAGMENT_SHADER);    //为了能够从磁盘中加载所创建的着色器,需在内存中加载相关内容,为此童颜需要MEMORY结构    m = mopen(VERTEX_SHADER, 1);    //进行指针检查    if( m ) {        //对包含在MEMORY缓冲区指针中的顶点着色器代码进行编译,为此我们,将代码传递到SHADER_compile函数        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 );    //到目前,我们已经成功变异顶点和片段着色器,并做好链接到着色器PROGRAM的准备。    //为了完成顶点和片段着色器的最终链接片段,可以调用PROGRAM_link函数   if( !PROGRAM_link( program, DEBUG_SHADERS ) ) exit( 3 );}void templateAppDraw( void ){    //1 准备框架    //声明一些2D位置,然后将这些顶点连接在一起,从而在屏幕上绘制一个正方形。    static const float POSITION[8] = {        0.0f,0.0f,//下 左        1.0f,0.0f,//上 左        0.0f,1.0f,//下右        1.0,1.0 //上 右    };    //声明顶点颜色    static const float COLOR[16] = {        1.0f /* R*/,0.0/*G*/,0.0f/*B*/,1.0f/*alpha*/,/*Red*/        0.0f,1.0f,0.0f,1.0f,//Green        0.0f,0.0f,1.0f,1.0f,//Blue        1.0f,1.0f,0.0f,1.0f//Yellow    };    //构建应用程序的渲染循环,首先指定用来清理颜色缓冲区的颜色值(灰色),在glclear函数调用之前插入:    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);    glClear(  GL_COLOR_BUFFER_BIT );    //放大    GFX_set_matrix_mode(MODELVIEW_MATRIX);    GFX_load_identity();    GFX_scale(300, 300.f, 0.0f);    if(program->pid){        //GLES索引从1开始        //声明两个用来保存顶点属性和统一位置的临时变量        char attribute, uniform;        //为了能够架起应用程序数据与GPU数据之间的桥梁,需要使用这些同一位置        //现在必须告诉GPU你讲使用那个程序来绘图        glUseProgram(program->pid);        //从视频存储器中检索uniform的位置        uniform = PROGRAM_get_uniform_location(program, (char *)"MODELVIEWPROJECTIONMATRIX");        //GPU更新数据        glUniformMatrix4fv(uniform, 1,  GL_FALSE, (float *)GFX_get_modelview_projection_matrix());        //处理顶点属性,检索顶点位置        attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"POSITION");        //告诉GLES可以使用顶点位置属性了        glEnableVertexAttribArray(attribute);        //告诉GLES 需使用该属性的那些数据        glVertexAttribPointer(attribute, 2, GL_FLOAT, GL_FALSE, 0, POSITION);        //对COLOR数组执行相同操作        attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"COLOR");        glEnableVertexAttribArray(attribute);        glVertexAttribPointer(attribute, 4, GL_FLOAT, GL_FALSE, 0, COLOR);        //调用alDrawArrays,告诉CPU使用特定模式绘制相应数据,并告诉使用多少数据:        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);        //为了安全        GFX_error();    }}void templateAppExit( void ){    printf("程序已退出!!!");    if (program&&program->vertex_shader) {        program->vertex_shader = SHADER_free(program->vertex_shader);    }    if (program&&program->fragment_shader) {        program->fragment_shader = SHADER_free(program->fragment_shader);    }    if (program) {        program = PROGRAM_free(program);    }}
0 0
原创粉丝点击