OpenGL ES2 的Off-Screen实现

OpenGL ES2需要的库:libGLESv2, libEGL

其中libEGL是用于和不同系统的窗口打交道的,是一个标准。如果需要让你显示在窗口中,如调用eglCreateWindowSurface;若off-screen,则eglCreatePbufferSurface。

直接上一下代码:

void esInitContext(ESContext *esContext)

{

   if ( esContext != NULL )

   {

      memset( esContext, 0, sizeof( ESContext) );

   }

}



GLboolean esCreateOffScreen( ESContext *esContext, GLint width, GLint height)

{

   EGLint numConfigs;

   EGLint majorVersion;

   EGLint minorVersion;

   EGLDisplay display;

   EGLContext context;

   EGLSurface surface;

   EGLConfig config;

   EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };



   EGLint cfgAttribs[] =  

   {  

        EGL_SURFACE_TYPE,    EGL_PBUFFER_BIT, 

           EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  

        //EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,

        EGL_RED_SIZE,        5,  

        EGL_GREEN_SIZE,      6,  

        EGL_BLUE_SIZE,       5,  

        EGL_DEPTH_SIZE,      1,  

        EGL_NONE  

    };  



    EGLint PBufAttribs[] =  

    {  

        EGL_WIDTH,  width,  

        EGL_HEIGHT, height,  

        EGL_LARGEST_PBUFFER, EGL_TRUE,  

        EGL_NONE  

    };  

   // Get Display

   display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

   if ( display == EGL_NO_DISPLAY )

   {

       return EGL_FALSE;

   }

   // Initialize EGL

   if ( !eglInitialize(display, &majorVersion, &minorVersion) )

   {

       return EGL_FALSE;

   }



   // Get configs

   if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )

   {

       return EGL_FALSE;

   }



   // Choose config

   if ( !eglChooseConfig(display, cfgAttribs, &config, 1, &numConfigs) )

   {

       return EGL_FALSE;

   }



   // Create a surface

   //surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL);

   //surface = eglCreatePixmapSurface(display, config, pixmap, NULL);

   surface = eglCreatePbufferSurface(display, config, PBufAttribs);  

   if ( surface == EGL_NO_SURFACE )

   {

       return EGL_FALSE;

   }



   // Check to see what size pbuffer we were allocated

   EGLint os_width;

   EGLint os_height;

   if(!eglQuerySurface(display, surface, EGL_WIDTH, &os_width) ||

        !eglQuerySurface(display, surface, EGL_HEIGHT, &os_height))

   {

       return EGL_FALSE;

   }



   // Create a GL context

   context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs );

   if ( context == EGL_NO_CONTEXT )

   {

       return EGL_FALSE;

   }   ;



   // Make the context current

   if ( !eglMakeCurrent(display, surface, surface, context) )

   {

       return EGL_FALSE;

   }



   esContext->eglContext = context;

   esContext->eglDisplay = display;

   esContext->eglSurface = surface;

   esContext->width = os_width;

   esContext->height = os_height;

}



void esDipose(ESContext *esContext)

{

    if(esContext->eglContext != EGL_NO_CONTEXT)

        eglDestroyContext(esContext->eglDisplay, esContext->eglContext);

    if(esContext->eglSurface != EGL_NO_SURFACE)

        eglDestroySurface(esContext->eglDisplay, esContext->eglSurface);

    if(esContext->eglDisplay != EGL_NO_DISPLAY)

        eglTerminate(esContext->eglDisplay);



    esContext->eglDisplay = EGL_NO_DISPLAY;

    esContext->eglContext = EGL_NO_CONTEXT;

    esContext->eglSurface = EGL_NO_SURFACE;

}

// Drawing something

画完后,可以用glReadPixels来读取

   GLint size;

   size = esContext->width * esContext->height * 4;

   GLubyte *data = (GLubyte*)malloc(size);

   glPixelStorei(GL_PACK_ALIGNMENT, 4);

   glReadPixels(0,0,esContext->width,esContext->height,GL_RGB,GL_UNSIGNED_BYTE,data);

可以把读出来的位图流写到一个bmp文件中(bmp在windows下默认是按BGR存的,故需要RGB->BGR)

bmp_write(data, esContext->width, esContext->height, "C:\\SimpleTexture2D");

int bmp_write(unsigned char *image, int xsize, int ysize, char *filename) 

{

	unsigned char header[54] = 

	{

		0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,

		54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0, 

		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

		0, 0, 0, 0

	};

	long file_size = (long)xsize * (long)ysize * 3 + 54;

	long width, height;

	char fname_bmp[128];

	FILE *fp;



	header[2] = (unsigned char)(file_size &0x000000ff);

	header[3] = (file_size >> 8) & 0x000000ff;

	header[4] = (file_size >> 16) & 0x000000ff;

	header[5] = (file_size >> 24) & 0x000000ff;



	width = xsize;

	header[18] = width & 0x000000ff;

	header[19] = (width >> 8) &0x000000ff;

	header[20] = (width >> 16) &0x000000ff;

	header[21] = (width >> 24) &0x000000ff;



	height = ysize;

	header[22] = height &0x000000ff;

	header[23] = (height >> 8) &0x000000ff;

	header[24] = (height >> 16) &0x000000ff;

	header[25] = (height >> 24) &0x000000ff;



	sprintf(fname_bmp, "%s.bmp", filename);



	if (!(fp = fopen(fname_bmp, "wb"))) 

		return -1;



	// switch the image data from RGB to BGR

	for(unsigned long imageIdx = 0; imageIdx < file_size; imageIdx+=3)

	{

		unsigned char tempRGB = image[imageIdx];

		image[imageIdx] = image[imageIdx + 2];

		image[imageIdx + 2] = tempRGB;

	}

	

	fwrite(header, sizeof(unsigned char), 54, fp);

	fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);



	fclose(fp);

	return 0;

}

  

你可能感兴趣的:(openGL ES)