将OpenGL代码移植成OpenGLES

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

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、头文件:

#if !defined(HAVE_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的话,基础框架如下:

#if !defined(HAVE_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(HAVE_GLES)
       	if (EGL_Open())
		exit(1);
#endif
 
	// some more initialisations
        SDL_Surface* screen;
 
#if !defined(HAVE_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(HAVE_GLES)
        	SDL_GL_SwapBuffers();
#else
		EGL_SwapBuffers();
#endif
        }
 
	// probably some more clean-ups here
 
#if defined(HAVE_GLES)
	EGL_Close();
#endif
        SDL_Quit();
 
        return 0;
}

注意EGL_xxx系列函数的位置。

 

3、一些宏定义:

gles只支持浮点型

#define GLdouble     GLfloat
#define GL_CLAMP     GL_CLAMP_TO_EDGE
#define glClearDepth glClearDepthf
#define glOrtho      glOrthof
#define glFrustum    glFrustumf

 

#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、没有颜色的普通矩形:

#if !defined(HAVE_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、贴图

glBindTexture(GL_TEXTURE_2D, carac->TextureName);
#if !defined(HAVE_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、颜色渐变:

#if !defined(HAVE_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、三角形扇面:

#if !defined(HAVE_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

#if !defined(HAVE_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

#ifndef HAVE_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渲染模式对应关系

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 ); 来规避这个问题。(并没有完美解决问题,只是大多数情况下正常显示)

你可能感兴趣的:(windows,android,api,嵌入式,float,图形)