您的位置:首页 > 编程语言

将OpenGL代码移植成OpenGLES

2013-09-05 17:34 351 查看


将OpenGL代码移植成OpenGLES

分类: IOS游戏开发 Android开发2012-08-21
15:58 1869人阅读 评论(0) 收藏 举报

float图形嵌入式windowsandroidapi

首先是一些基础概念和经验分享:

1、OpenGL是一个跨平台的图形渲染标准

2、OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API
的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。

OpenGL ES 是从 OpenGL 裁剪定制而来的,去除了 glBegin/glEnd,四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性。现在主要有两个版本,OpenGL ES 1.1针对固定管线硬件的,是以 OpenGL 1.5 规范为基础的。OpenGL ES 2.x 针对可编程管线硬件,参照 OpenGL 2.0 规范定义。

3、egl提供了opengles和本地窗口之间的关联

4、OpenGLES模拟器,这里的模拟器仅仅是一套api和dll(要与android模拟器区分开)。主要用于非嵌入式平台(如windows)下运行opengles代码。



============================================正文==============================================================

1、头文件:

[cpp] view
plaincopy

#if !defined(H***E_GLES)

#include <GL/gl.h>

#else

#include <GLES/gl.h>

#endif

2、windows下可以使用eglport(http://sourceforge.net/p/eglport/code-0/3/tree/trunk/),android和ios下各有其对应实现,如果使用了SDL的话,基础框架如下:

[cpp] view
plaincopy

#if !defined(H***E_GLES)

#include <GL/gl.h>

#else

#include <GLES/gl.h>

#include "eglport.h"

#endif



#include <SDL/SDL.h>



int main( void )

{

// other stuff here



SDL_Init( SDL_INIT_VIDEO );

#if defined(H***E_GLES)

if (EGL_Open())

exit(1);

#endif



// some more initialisations

SDL_Surface* screen;



#if !defined(H***E_GLES)

screen = SDL_SetVideoMode( 800, 600, 0, SDL_HWSURFACE | SDL_OPENGL | SDL_FULLSCREEN);

#else

screen = SDL_SetVideoMode( 800, 480, 0, SDL_SWSURFACE | SDL_FULLSCREEN );

EGL_Init();

#endif



// the event loop

while( quit == 0 ) {

// management of the even and the game





#if !defined(H***E_GLES)

SDL_GL_SwapBuffers();

#else

EGL_SwapBuffers();

#endif

}



// probably some more clean-ups here



#if defined(H***E_GLES)

EGL_Close();

#endif

SDL_Quit();



return 0;

}

注意EGL_xxx系列函数的位置。



3、一些宏定义:

gles只支持浮点型

[cpp] view
plaincopy

#define GLdouble GLfloat

#define GL_CLAMP GL_CLAMP_TO_EDGE

#define glClearDepth glClearDepthf

#define glOrtho glOrthof

#define glFrustum glFrustumf



[cpp] view
plaincopy

#define glColor4fv(a) glColor4f(a[0], a[1], a[2], a[3])

#define glColor3fv(a) glColor4f(a[0], a[1], a[2], 1.0f)

#define glColor3f(a,b,c) glColor4f(a, b, c, 1.0f)

4、具体代码移植示例,因为gles去除了glBegin等函数,所以贴图、顶点绘制、画线等代码都有可能需要进行修改

a、没有颜色的普通矩形:

[cpp] view
plaincopy

#if !defined(H***E_GLES)

glBegin(GL_QUADS);

glVertex2f(-10,-10);

glVertex2f(10,-10);

glVertex2f(10,10);

glVertex2f(-10,10);

glEnd();

#else

GLfloat q3[] = {

-10,-10,

10,-10,

10,10,

-10,10

};



glEnableClientState(GL_VERTEX_ARRAY);

glVertexPointer(2, GL_FLOAT, 0, q3);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glDisableClientState(GL_VERTEX_ARRAY);

#endif

b、贴图

[cpp] view
plaincopy

glBindTexture(GL_TEXTURE_2D, carac->TextureName);

#if !defined(H***E_GLES)

glBegin(GL_QUADS);



glTexCoord2f(0,0);

glVertex3f(pos[0]-tailleX/2, pos[1]-tailleY/2, 0);

glTexCoord2f(1,0);

glVertex3f(pos[0]+tailleX/2, pos[1]-tailleY/2, 0);

glTexCoord2f(1,1);

glVertex3f(pos[0]+tailleX/2, pos[1]+tailleY/2, 0);

glTexCoord2f(0,1);

glVertex3f(pos[0]-tailleX/2, pos[1]+tailleY/2, 0);



glEnd();

#else

GLfloat vtx1[] = {

pos[0]-tailleX/2, pos[1]-tailleY/2, 0,

pos[0]+tailleX/2, pos[1]-tailleY/2, 0,

pos[0]+tailleX/2, pos[1]+tailleY/2, 0,

pos[0]-tailleX/2, pos[1]+tailleY/2, 0

};

GLfloat tex1[] = {

0,0,

1,0,

1,1,

0,1

};



glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);



glVertexPointer(3, GL_FLOAT, 0, vtx1);

glTexCoordPointer(2, GL_FLOAT, 0, tex1);

glDrawArrays(GL_TRIANGLE_FAN,0,4);



glDisableClientState(GL_VERTEX_ARRAY);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

#endif

c、颜色渐变:

[cpp] view
plaincopy

#if !defined(H***E_GLES)

glBegin(GL_QUADS);

glColor3d( .1, .1, .7);

glVertex3d(0, 0, 0);

glVertex3d(0, -pbarheight, 0);

glColor3d( 0, 0, 0.5);

glVertex3d((startupProgress / startupProgressSteps) * pbarwidth, -pbarheight, 0);

glVertex3d((startupProgress / startupProgressSteps) * pbarwidth, 0, 0);

glEnd();

#else

GLfloat vtx1[] = {

0, 0, 0,

0, -pbarheight, 0,

(startupProgress / startupProgressSteps) * pbarwidth, -pbarheight, 0,

(startupProgress / startupProgressSteps) * pbarwidth, 0, 0

};

GLfloat col1[] = {

.1, .1, .7, 1.0f,

.1, .1, .7, 1.0f,

0, 0, 0.5, 1.0f,

0, 0, 0.5, 1.0f

};



glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_COLOR_ARRAY);



glVertexPointer(3, GL_FLOAT, 0, vtx1);

glColorPointer(4, GL_FLOAT, 0, col1);

glDrawArrays(GL_TRIANGLE_FAN,0,4);



glDisableClientState(GL_COLOR_ARRAY);

glDisableClientState(GL_VERTEX_ARRAY);

#endif

d、三角形扇面:

[cpp] view
plaincopy

#if !defined(H***E_GLES)

glBegin(GL_QUAD_STRIP);

// Front

glVertex3f(-left, 0, front); // bottom left

glVertex3f(-left-wider, height, front+wider); // top left

glVertex3f( right, 0, front); // bottom right

glVertex3f( right+wider, height, front+wider); // top right



// Right

glVertex3f( right, 0,-back); // bottom r

glVertex3f( right+wider, height,-back-wider); // top r



// Back

glVertex3f(-left, 0, -back); // bottom right

glVertex3f(-left-wider, height, -back-wider); // top right



// Left

glVertex3f(-left, 0, front); // bottom r

glVertex3f(-left-wider, height, front+wider); // top r

glEnd();

#else

{

GLfloat vtx1[] = {-left, 0, front, -left-wider, height, front+wider, right, 0, front, right+wider, height, front+wider};

GLfloat vtx2[] = {right, 0, front, right+wider, height, front+wider, right, 0,-back, right+wider, height,-back-wider};

GLfloat vtx3[] = {right, 0,-back, right+wider, height,-back-wider, -left, 0, -back, -left-wider, height, -back-wider};

GLfloat vtx4[] = {-left, 0, -back, -left-wider, height, -back-wider, -left, 0, front, -left-wider, height, front+wider};

glEnableClientState(GL_VERTEX_ARRAY);

glVertexPointer(3, GL_FLOAT, 0, vtx1);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glVertexPointer(3, GL_FLOAT, 0, vtx2);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glVertexPointer(3, GL_FLOAT, 0, vtx3);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glVertexPointer(3, GL_FLOAT, 0, vtx4);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glDisableClientState(GL_VERTEX_ARRAY);

}

#endif

e、使用int/short

[cpp] view
plaincopy

#if !defined(H***E_GLES)

glBegin(GL_QUADS);

glTexCoord2i(0, 1); glVertex2i(-256, -256);

glTexCoord2i(0, 0); glVertex2i(-256, 256);

glTexCoord2i(1, 0); glVertex2i(256, 256);

glTexCoord2i(1, 1); glVertex2i(256, -256);

glEnd();

#else

GLshort vtx1[] = { -256, -256, -256, 256, 256, 256, 256, -256 };

GLshort tex1[] = { 0, 1, 0, 0, 1, 0, 1, 1 };

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);



glVertexPointer(2, GL_SHORT, 0, vtx1);

glTexCoordPointer(2, GL_SHORT, 0, tex1);

glDrawArrays(GL_TRIANGLE_FAN,0,4);



glDisableClientState(GL_VERTEX_ARRAY);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

#endif

f、glRect

[cpp] view
plaincopy

#ifndef H***E_GLES

glRecti ( dx + min[0], dy + min[1],

dx + max[0], dy + max[1] ) ;

#else

GLshort vtx1[] = { dx + min[0], dy + min[1], dx + min[0], dy + max[1], dx + max[0], dy + max[1], dx + max[0], dy + min[1]};

glEnableClientState(GL_VERTEX_ARRAY);

glVertexPointer(2, GL_SHORT, 0, vtx1);

glDrawArrays(GL_TRIANGLE_FAN,0,4);

glDisableClientState(GL_VERTEX_ARRAY);

#endif

5、glDrawArrays渲染模式对应关系

[cpp] view
plaincopy

GL_POINTS -> GL_POINTS

GL_TRIANGLES -> GL_TRIANGLES (or GL_LINE_LOOP if glPolygonMode is set to GL_LINE)

GL_QUADS -> GL_TRIANGLE_FAN

GL_LINE_STRIP -> GL_LINE_STRIP

GL_LINE -> GL_LINE

GL_POLYGON -> GL_TRIANGLE_FAN

6、所有贴图必须是2的整次幂,某些特殊情况会有更高的需求(如powervr显卡使用pvr贴图必须是正方形以及2的整次幂大小)。

7、部分情况下贴图会有黑边,可以使用参数 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 来规避这个问题。(并没有完美解决问题,只是大多数情况下正常显示)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: