opengl|es - 2D绘制
来源:互联网 发布:淘宝确认订单页面 编辑:程序博客网 时间:2024/04/30 18:38
本文关注的是基于SDL的OPENGL|ES(下文简称ES)的2D绘制的实现方式。
ES中常见的实现2D的方法是使用正投影,然后绘制2D纹理
- glDisable( GL_DEPTH_TEST ) ;
- glMatrixMode( GL_PROJECTION ) ;
- glLoadIdentity() ;
- /*
- * Upside-down square viewport: it maps the screen as if the (arbitrary-set) resolution were
- * 1000x1000 pixels.
- *
- */
- glOrtho( /* left */ 0, /* right */ 1000, /* bottom */ 1000, /* top */ 0,
- /* near */ 0, /* far */ 1 ) ;
- - or, preferably to keep the 4/3 ratio like 800x600, 640x480, 1024x768, etc. -
- // Non-reversed 4/3 viewport:
- glOrtho( /* left */ -320.0f, /* right */ 320.0f, /* bottom */ -240.0f, /* top */ 240.0f,
- /* near */ -1, /* far */ 1 )
这里有三个问题,
其一SDL与ES的坐标系统不同,SDL的(0,0)在屏幕的左上角,而ES的在屏幕的左下角,这里可以使用上下反转的正投影来解决,或者在每次绘制前使用如下的变换,
- glMatrixMode( GL_TEXTURE ) ;
- glLoadIdentity() ;
- glScalef( 1, -1, 1 ) ;
其二OPENGL认为自己拥有整个屏幕,对于显示缓存,只能使用OPENGL进行控制
其三在OPENGL与SDL之间的BLIT,当SDL选择OPENGL模式的时候(OPENGLBLIT模式是不被推荐的)是不能之间进行的,这里使用了技巧,是将SDL的缓存转换成了OPENGL的材质,然后供OPENGL的2D显示使用,如下
- /* Use the surface width and height expanded to powers of 2,OPENGL 的纹理大小必须是2的倍数 */
- w = gy_powerOfTwo(surface->w);
- h = gy_powerOfTwo(surface->h);
- texcoord[0] = 0; /* Min X */
- texcoord[1] = 0; /* Min Y */
- texcoord[2] = surface->w / (gy_real32)w; /* Max X */
- texcoord[3] = surface->h / (gy_real32)h; /* Max Y */
- image = SDL_CreateRGBSurface(
- SDL_SWSURFACE,
- w, h,
- 32,
- #if SDL_BYTEORDER != SDL_BIG_ENDIAN /* OpenGL RGBA masks */
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0xff000000
- #endif
- );
- if ( image == NULL ) {
- return 0;
- }
- /* Save the alpha blending attributes */
- saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
- saved_alpha = surface->format->alpha;
- if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
- }
- SDL_SetAlpha(surface, SDL_SRCALPHA, saved_alpha);//记得在正投影后设置纹理的环境时,使用GL_MODULATE模式
- /* Copy the surface into the GL texture image */
- area.x = 0;
- area.y = 0;
- area.w = surface->w;
- area.h = surface->h;
- SDL_BlitSurface(surface, &area, image, &area);
- /* Restore the alpha blending attributes */
- if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
- SDL_SetAlpha(surface, saved_flags, saved_alpha);
- }
- /* Create an OpenGL texture for the image */
- glGenTextures(1, &texture); //生成纹理
- glBindTexture(GL_TEXTURE_2D, texture); //选择纹理
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- w, h,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE/*每种颜色8位*/,
- image->pixels);
- SDL_FreeSurface(image); /* No longer needed */
最后值得注意的是,ES在纹理绘制时选择使用glDrawElements函数,其最后一个参数是索引值,由于OPENGL是状态机驱动的,整个坐标系统是提前将状态设置好的,不用总是在困扰与这个东西是如何绘制出来,呵呵,如下是glDrawElements的使用方式
- glBindTexture(GL_TEXTURE_2D, uiTexture);
- glEnableClientState( GL_VERTEX_ARRAY );
- glEnableClientState( GL_NORMAL_ARRAY );
- glEnableClientState( GL_TEXTURE_COORD_ARRAY );
- glNormalPointer( GL_FLOAT, 0, rnormal );
- glVertexPointer(3, GL_FLOAT, 0, vertex); //注意纹理坐标体系和点坐标体系是不同的
- glTexCoordPointer(2,GL_FLOAT,0,textures );
- glDrawElements( GL_TRIANGLES,6,GL_UNSIGNED_BYTE,trivert);
- glDisableClientState( GL_TEXTURE_COORD_ARRAY );
- glDisableClientState( GL_VERTEX_ARRAY );
- opengl|es - 2D绘制
- opengl|es - 2D绘制
- OpenGL ES开发绘制2D图形
- OpenGL ES绘制3D
- OpenGL ES绘制3D图形
- OpenGL ES绘制3D图形
- OpenGL ES绘制3D图形
- OpenGL ES绘制3D图形
- OpenGL ES绘制3D图形
- OpenGL ES绘制3D图形
- OpenGL ES 绘制 3D 图形
- OpenGL ES绘制3D图形
- OpenGL ES 绘制 3D 图形
- Android OpenGL ES 3D图形绘制
- 使用OpenGL ES绘制3D图形
- OpenGL ES 绘制 3D 图形
- OpenGL ES绘制3D纹理贴图
- OpenGL ES绘制3D图形
- How to build FreeNAS from Scratch
- 項目の動割当
- 我已来到美丽的西子湖畔
- CSS引用
- java多线程
- opengl|es - 2D绘制
- SVN中Branch和tag优劣大比拼
- IIS7源码泄露及文件类型解析错误——最新解决方案
- PHP的$_env为空的原因
- Android 编译命令及选项
- WebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单
- ubuntu 不能安装jre
- Hibernate配置文件模板(.cfg.xml)
- 世界第一名写的程序!