In Android, the Java layer needs to create a surface,
Class mobileviewgles extends glsurfaceview implements callback
{
Public void surfacecreated (surfaceholder holder)
{
Log. E ("mobileviewgles", "surfacecreated ");
// New thread (this). Start ();
Initrendergles (getholder (). getsurface ());
}
Public void surfacechanged (surfaceholder holder, int format, int width, int height)
{
Log. E ("mobileviewgles", "surfacechanged ");
}
Public void surfacedestroyed (surfaceholder holder)
{
Log. E ("mobileviewgles", "surfacedestroyed ");
Termrendergles ();
}
Public native void initrendergles (surface );
Public native void termrendergles ();
}
Initrendergles is a native function. It is implemented at the C ++ layer. This function mainly creates the gles environment and draws the surface and display. The implementation functions are as follows:
Static void mobileviewgles_initrendergles (jnienv * ENV, jobject thiz, jobject surface)
{
Ganativewindow = anativewindow_fromsurface (ENV, surface );
Glesinitdisplay ();
Createglesenv ();
Glesenvchanged (gwidth, gheight );
Setdrawoffscreen (false );
// Glesdrawframe ();
// Glestermdisplay ();
Return;
}
Glesinitdisplay () is as follows:
Int glesinitdisplay ()
{
Const eglint attribs [] =
{
Egl_surface_type,
Egl_window_bit,
Egl_blue_size, 8,
Egl_green_size, 8,
Egl_red_size, 8,
Egl_none
};
Eglconfig config;
Eglint numconfigs;
Eglint format;
Eglint width;
Eglint height;
Eglint contextatt [] = {egl_context_client_version, 2, egl_none, egl_none };
Gdisplay = eglgetdisplay (egl_default_display );
Eglinitialize (gdisplay, 0, 0 );
Eglchooseconfig (gdisplay, attribs, & config, 1, & numconfigs );
Eglgetconfigattrib (gdisplay, config, egl_native_visual_id, & format );
Anativewindow_setbuffersgeometry (ganativewindow, 0, 0, format );
Gsurface = eglcreatewindowsurface (gdisplay, config, ganativewindow, null );
Gcontext = eglcreatecontext (gdisplay, config, egl_no_context, contextatt );
If (eglmakecurrent (gdisplay, gsurface, gsurface, gcontext) = egl_false)
{
LogE ("unable to eglmakecurrent ");
Return-1;
}
Eglquerysurface (gdisplay, gsurface, egl_width, & width );
Eglquerysurface (gdisplay, gsurface, egl_height, & height );
Return 0;
}
Glint createglesenv ()
{
Static char vshaderstr [] =
"Uniform mat4 u_transmatrix; \ n"
"Attribute vec4 a_position; \ n"
"Attribute vec2 a_texcoord; \ n"
"Varying vec2 v_texcoord; \ n"
"Void main () \ n"
"{\ N"
"Gl_position = u_transmatrix * a_position; \ n"
"V_texcoord = a_texcoord; \ n"
"} \ N ";
Static char fshaderstr [] =
"Precision mediump float; \ n"
"Varying vec2 v_texcoord; \ n"
"Uniform sampler2d s_imgtexture; \ n"
"Uniform int speccolorflag; \ n"
"Uniform vec4 speccolor; \ n"
"Void main () \ n"
"{\ N"
// "Gl_fragcolor = texture2d (s_imgtexture, v_texcoord); \ n"
"If (speccolorflag = 0) \ n"
"{Gl_fragcolor = texture2d (s_imgtexture, v_texcoord);} \ n"
"Else {gl_fragcolor = speccolor;} \ n"
"} \ N ";
// Esortho (& gorthographic,-100,100,-100,100, 5.0f,-5.0f );
Gluint vertexshader;
Gluint fragmentshader;
Gluint programobject;
Glint linked;
// Load the vertex/fragment shaders
Vertexshader = esloadshader (gl_vertex_shader, vshaderstr );
If (vertexshader = 0)
Return 0;
Fragmentshader = esloadshader (gl_fragment_shader, fshaderstr );
If (fragmentshader = 0)
{
Gldeleteshader (vertexshader );
Return 0;
}
Gproobject = glcreateprogram ();
Glattachshader (gproobject, vertexshader );
Glattachshader (gproobject, fragmentshader );
// Link the program
Gllinkprogram (gproobject );
// Check the link status
Glgetprogramiv (gproobject, gl_link_status, & linked );
If (! Linked)
{
Glint infolen = 0;
Glgetprogramiv (gproobject, gl_info_log_length, & infolen );
If (infolen> 1)
{
Char * infolog = (char *) malloc (sizeof (char) * infolen );
Glgetprograminfolog (gproobject, infolen, null, infolog );
Free (infolog );
}
Gldeleteprogram (gproobject );
Return 0;
}
// Free up no longer needed shader Resources
Gldeleteshader (vertexshader );
Gldeleteshader (fragmentshader );
Gshaderposition = glgetattriblocation (gproobject, "a_position ");
Gshadertexcoord = glgetattriblocation (gproobject, "a_texcoord ");
Gvpmatrix = glgetuniformlocation (gproobject, "u_transmatrix ");
Gshaderimgtexture = glgetuniformlocation (gproobject, "s_imgtexture ");
Gcolorflag = glgetuniformlocation (gproobject, "speccolorflag ");
Gcolorloc = glgetuniformlocation (gproobject, "speccolor ");
// Glenable (gl_blend );
// Glblendfunc (gl_src_alpha, gl_one_minus_src_color );
Glgentextures (1, & gmaintexture );
Glgentextures (1, & gtexturetmp );
Glesbindoffscreen ();
Glpixelstorei (gl_unpack_alignment, 1 );
Glbindtexture (gl_texture_2d, gtexturetmp );
Gltexparameteri (gl_texture_2d, gl_texture_min_filter, gl_nearest );
Gltexparameteri (gl_texture_2d, gl_texture_mag_filter, gl_nearest );
Gltexparameteri (gl_texture_2d, gl_texture_wrap_s, gl_clamp_to_edge );
Gltexparameteri (gl_texture_2d, gl_texture_wrap_t, gl_clamp_to_edge );
Glteximage2d (gl_texture_2d,
0,
Gl_rgba,
Gwidth,
Gheight,
0,
Gl_rgba,
Gl_unsigned_byte,
Null );
Return gproobject;
}
Void glesenvchanged (INT width, int height)
{
Gwidthd2 = width/2;
Gheightd2 = height/2;
Esmatrixloadidentity (& gorthographic );
// Esortho (& gorthographic, 0, mwidth,-mheight, 0, 5.0f,-5.0f );
Esortho (& gorthographic,-gwidthd2, gwidthd2,-gheightd2, gheightd2, 5.0f,-5.0f );
Esmatrix modelview;
Esmatrixloadidentity (& gmatrix );
Esmatrixloadidentity (& modelview );
Esmatrixmultiply (& gmatrix, & modelview, & gorthographic );
Glviewport (0, 0, width, height );
}
Void setdrawoffscreen (bool boffscreen)
{
If (boffscreen)
{
Glbindframebuffer (gl_framebuffer, gframebuffer );
}
Else
{
Glbindframebuffer (gl_framebuffer, 0 );
}
}
After the gles environment is created, draw
Case xwm_repaint:
{
If (eglmakecurrent (gdisplay, gsurface, gsurface, gcontext) = egl_false)
{
Logwheremsg ("makecurrent error ");
Break;
}
Logwheremsg ("xwm_repaint ");
Xrect clip (m_clip );
Glclearcolor (0.0f, 0.0f, 0.0f, 1.0f );
Glbindframebuffer (gl_framebuffer, gframebuffer );
Bool B = paint (m_draw );
If (B)
{
Glclearcolor (0.0f, 0.0f, 0.0f, 1.0f );
Glbindframebuffer (gl_framebuffer, 0 );
Glespaint (gmaintexture );
Flushbuffer ();
Logwheremsg ("xwm_repaint ");
}
Else
{
Invalidaterect (CLIP );
}
Break;
}
During the painting process, glbindframebuffer (gl_framebuffer, gframebuffer) is set to be drawn in the off-screen cache area, while glbindframebuffer (gl_framebuffer, 0) is drawn on the screen.
Finally, call the termrendergles () function at the end to destroy the surface. The function is implemented as follows:
Int glestermdisplay ()
{
If (gdisplay! = Egl_no_display)
{
Eglmakecurrent (gdisplay, egl_no_surface, egl_no_surface, egl_no_context );
If (gcontext! = Egl_no_context)
{
Egldestroycontext (gdisplay, gcontext );
}
If (gsurface! = Egl_no_surface)
{
Egldestroysurface (gdisplay, gdisplay );
}
Eglterminate (gdisplay );
}
}