您的位置:首页 > 其它

EGL笔记--未完全看懂 好好理解 2011-12-6

2011-12-06 18:46 120 查看
EGL是OpenGL和平台显示相关的部分的封装。http://www.khronos.org/egl/

OpenGL ES的初始化过程如下图所示意:

DISPLAY → CONFIG → SURFACE



CONTEXT



OpenGL ES Command

EGL工作步骤如下:

1。获取显示设备并初始化EGL

EGLDisplay 是一个系统物理屏幕的通用数据类型。系统可能有多个物理显示设备,EGLDisplay 就是确定用哪个物理设备

EGLDisplay 操作设备显示的 API 。

EGLDisplay eglGetDisplay (NativeDisplayType display); 其中 display 参数是 native
系统的窗口显示句柄。在windows下为窗口的

DC,在linux下为打开framebuffer设备返回的设备描述符。如果想得到一个系统默认的Display ,就可以用EGL_DEFAULT_DISPLAY

参数。如果系统中没有,函数将返回 EGL_NO_DISPLAY 。

获取后调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,

并传回EGL版本号(major.minor)。

2。 配置EGL

其实就是配置FrameBuffer的参数,在Windows下对应于PixelFormat,

用EGLboolean eglChooseConfig(),其中有个参数是以EGL_NONE结束的参数数组,通常以id,value依次存放。

对于特定平台,可以先用GLboolean eglGetConfigs() 来获得支持的配置,eglGetConfigs()中间两个参数为0时可以得到支持的配

置总个数。配置有很多属性,可以用eglGetConfigAttrib ()来读取。

见egl.h

/* Config attributes */

#define EGL_BUFFER_SIZE 0x3020

#define EGL_ALPHA_SIZE 0x3021

#define EGL_BLUE_SIZE 0x3022

#define EGL_GREEN_SIZE

。。。。

http://www.khronos.org/egl/

3。 构造Surface。

Surface实际上就是一个FrameBuffer,有多种surface

要在某个窗口中显示怎用EGLSurface eglCreateWindowSurface() 来创建,只有这种是在物理显示设备上显示的。

要在内存中以位图保存,则用eglCreatePixmapSurface()来创建,该类型只用于离屏渲染.

要保存在显存中的帧, 则用eglCreatePbufferSurface()来创建。

Surface的属性可以用eglSurfaceAttrib()来设置,用和eglQuerySurface()来获取。egl.h中有定义

/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */

#define EGL_HEIGHT 0x3056

#define EGL_WIDTH 0x3057

#define EGL_LARGEST_PBUFFER 0x3058

#define EGL_TEXTURE_FORMAT 0x3080

#define EGL_TEXTURE_TARGET 0x3081

#define EGL_MIPMAP_TEXTURE 0x3082

。。。。。。。。

具体见 http://www.khronos.org/egl/

4。创建Context。

OpenGL ES的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,

这些状态作用于 程序提交的顶点坐标等图元从而形成帧缓冲内的像素。在OpenGL ES的编程接口中,Context就代表这个状态机,

程序的主要工作就是向Context提供图元、设置状态,偶尔也从Context里获取一些信息。

用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建

一个Context。然后用eglMakeCurrent激活context

5. 绘制。

应用程序通过OpenGL ES API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。

如果显示之前处理,则不调用次函数,调glFlush()后调glReadPixels()

例子:

OpenGLwindows下WGL初始化代码如下:

#include <GL/gl.h>

#include <GL/egl.h>

int CheckHardwareSupport(HDC hdc)

{

int PixelFormat = GetPixelFormat(hdc);

PIXELFORMATDESCRIPTOR pfd;

DescribePixelFormat(hdc,PixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);

if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))

return 0; // Software acceleration OpenGL

else if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && (pfd.dwFlags & PFD_GENERIC_ACCELERATED))

return 1; // Half hardware acceleration OpenGL (MCD driver)

else if ( !(pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))

return 2; // Full hardware acceleration OpenGL

return -1; // check error

}

bool windows_opengl_init()

{

HDC oglDC = NULL;

HGLRC hRC = NULL;

int pixelFormat;

PIXELFORMATDESCRIPTOR pfd;

int res;

char *opengl_modes[3]={"software","half hardware (MCD driver)","hardware"};

if(oglAlreadyInit == true) return true;

oglDC = GetDC (MainWindow->getHWnd());

memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR));

pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);

pfd.nVersion = 1;

pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

pfd.iPixelType = PFD_TYPE_RGBA;

pfd.cColorBits = 24;

pfd.cDepthBits = 24;

pfd.cAlphaBits = 8;

pfd.cStencilBits = 8;

pfd.iLayerType = PFD_MAIN_PLANE ;

pixelFormat = ChoosePixelFormat(oglDC, &pfd);

if (pixelFormat == 0)

return false;

if(!SetPixelFormat(oglDC, pixelFormat, &pfd))

return false;

hRC = wglCreateContext(oglDC);

if (!hRC)

return false;

if(!wglMakeCurrent(oglDC, hRC))

return false;

res=CheckHardwareSupport(oglDC);

if (res>=0&&res<=2)

INFO("OpenGL mode: %s/n",opengl_modes[res]);

else

INFO("OpenGL mode: uknown/n");

oglAlreadyInit = true;

return true;

}

OpenGL ES在windows下EGL初始化的例子

bool windows_opengl_init()

{

EGLDisplay dpy;

EGLConfig config;

EGLSurface surface;

EGLContext context;

EGLint major;

EGLint minor;

EGLint cfg_attr_list[3] = { EGL_BUFFER_SIZE, 16, EGL_NONE};

EGLBoolean ret;

HDC oglDC = NULL;

if(oglAlreadyInit == true) return true;

oglDC = GetDC (MainWindow->getHWnd());

dpy = eglGetDisplay(oglDC); //得到DC所在的显示器

if (dpy==EGL_NO_DISPLAY) {

return false;

}

ret = eglInitialize(dpy, &major, &minor);

if(ret==EGL_FALSE) {

return false;

}

int num = 0;

ret = eglChooseConfig(dpy, cfg_attr_list, &config, 1, &num);

if ( ret== EGL_FALSE || num == 0 )

{

return false;

}

surface = eglCreateWindowSurface(dpy, config, MainWindow->getHWnd(), 0);

if ( surface == EGL_NO_SURFACE )

{

return false;

}

// create context

// EGLint ctx_attr_list[] = { EGL_NONE };

context = eglCreateContext(dpy, config, NULL, NULL);

// active context (make current)

oglAlreadyInit = eglMakeCurrent(dpy, surface, surface, context);

return true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: