//============================== // OvrGazeCursorLocal:: void OvrGazeCursorLocal::Init() { LOG( "OvrGazeCursorLocal::Init" ); ASSERT_WITH_TAG( Initialized == false, "GazeCursor" ); if ( Initialized ) { LOG( "OvrGazeCursorLocal::Init - already initialized!" ); return; } CreateCursorGeometry(); TimerGeometry = BuildTesselatedQuad( 1, 1 ); int w = 0; int h = 0; char const * const cursorStateNames[ CURSOR_STATE_MAX ] = { //"res/raw/color_ramp_test.tga", //"res/raw/color_ramp_test.tga", //"res/raw/gaze_cursor_dot.tga", //"res/raw/gaze_cursor_dot_hi.tga" //"res/raw/gaze_cursor_cross.tga", //"res/raw/gaze_cursor_cross_hi.tga" "res/raw/gaze_cursor_cross.tga", "res/raw/gaze_cursor_cross.tga", // for now, hilight is the same because the graphic needs work "res/raw/gaze_cursor_cross.tga", "res/raw/gaze_cursor_hand.tga" }; for ( int i = 0; i < CURSOR_STATE_MAX; ++i ) { CursorTextureHandle[i] = LoadTextureFromApplicationPackage( cursorStateNames[i], TextureFlags_t(), w, h ); } TimerTextureHandle = LoadTextureFromApplicationPackage( "res/raw/gaze_cursor_timer.tga", TextureFlags_t(), w, h ); ColorTableHandle = LoadTextureFromApplicationPackage( "res/raw/color_ramp_timer.tga", TextureFlags_t(), w, h ); CursorProgram = BuildProgram( GazeCursorVertexSrc, GazeCursorFragmentSrc ); TimerProgram = BuildProgram( GazeCursorTimerVertexSrc, GazeCursorColorTableFragmentSrc );//GazeCursorFragmentSrc ); Initialized = true; }
// Called by TimeWarp before adding the KHR sync object. void ImageServer::EnterWarpSwap( int eyeTexture ) { ImageServerRequest request = Request.GetState(); if ( request.Sequence <= SequenceCaptured ) { return; } SequenceCaptured = request.Sequence; // create GL objects if necessary if ( !ResampleProg.program ) { ResampleProg = BuildProgram( "uniform highp mat4 Mvpm;\n" "attribute vec4 Position;\n" "attribute vec2 TexCoord;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_Position = Position;\n" " oTexCoord = vec2( TexCoord.x, 1.0 - TexCoord.y );\n" // need to flip Y "}\n" , "uniform sampler2D Texture0;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_FragColor = texture2D( Texture0, oTexCoord );\n" "}\n" ); } if ( !UnitSquare.vertexArrayObject ) { UnitSquare = BuildTesselatedQuad( 1, 1 ); } // If resolution has changed, delete and reallocate the buffers // These might still be in use, do we trust the driver or try to // deal with it ourselves? if ( request.Resolution != CurrentResolution ) { CurrentResolution = request.Resolution; FreeBuffers(); } // Allocate any resources we need if ( !ResampleRenderBuffer ) { LOG( "Alloc %i res renderbuffer", CurrentResolution ); glGenRenderbuffers( 1, &ResampleRenderBuffer ); glBindRenderbuffer( GL_RENDERBUFFER, ResampleRenderBuffer ); glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB565, CurrentResolution, CurrentResolution ); } if ( !FrameBufferObject ) { LOG( "Alloc FrameBufferObject" ); glGenFramebuffers( 1, &FrameBufferObject ); glBindFramebuffer( GL_FRAMEBUFFER, FrameBufferObject ); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ResampleRenderBuffer ); const GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); if (status != GL_FRAMEBUFFER_COMPLETE ) { LOG( "FBO is not complete: 0x%x", status ); } } if ( !PixelBufferObject ) { LOG( "Alloc PixelBufferObject" ); glGenBuffers( 1, &PixelBufferObject ); glBindBuffer( GL_PIXEL_PACK_BUFFER, PixelBufferObject ); glBufferData( GL_PIXEL_PACK_BUFFER, CurrentResolution*CurrentResolution*2, NULL, GL_DYNAMIC_READ ); glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 ); } // Render the FBO glBindFramebuffer( GL_FRAMEBUFFER, FrameBufferObject ); glDisable( GL_DEPTH_TEST ); glDisable( GL_SCISSOR_TEST ); GL_InvalidateFramebuffer( INV_FBO, true, false ); glViewport( 0, 0, CurrentResolution, CurrentResolution ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, eyeTexture ); glUseProgram( ResampleProg.program ); UnitSquare.Draw(); glUseProgram( 0 ); // unmap the previous PBO mapping if ( PboMappedAddress ) { glBindBuffer( GL_PIXEL_PACK_BUFFER, PixelBufferObject ); glUnmapBuffer_( GL_PIXEL_PACK_BUFFER ); glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 ); PboMappedAddress = NULL; } // Issue an async read into our PBO #if 1 glBindBuffer( GL_PIXEL_PACK_BUFFER, PixelBufferObject ); glReadPixels( 0, 0, CurrentResolution, CurrentResolution, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0 ); // back to normal memory read operations glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 ); #else GL_CheckErrors( "before read" ); static short pixels[256*256]; glReadPixels( 0, 0, CurrentResolution, CurrentResolution, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (GLvoid *)pixels ); ImageServerResponse response; response.Data = (void *)pixels; response.Resolution = CurrentResolution; response.Sequence = request.Sequence; Response.SetState( response ); #endif glBindFramebuffer( GL_FRAMEBUFFER, 0 ); GL_CheckErrors( "after read" ); CountdownToSend = 2; }
void MediaSurface::Update() { if ( !AndroidSurfaceTexture ) { LOG( "!AndroidSurfaceTexture" ); return; } if ( TexId <= 0 ) { //LOG( "TexId <= 0" ); return; } AndroidSurfaceTexture->Update(); if ( AndroidSurfaceTexture->nanoTimeStamp == LastSurfaceTexNanoTimeStamp ) { return; } LastSurfaceTexNanoTimeStamp = AndroidSurfaceTexture->nanoTimeStamp; // don't mess up Unity state GLStateSave stateSave; // If we haven't allocated our GL objects yet, do it now. // This isn't done at Init, because GL may not be current then. if ( UnitSquare.vertexArrayObject == 0 ) { LOG( "Allocating GL objects" ); UnitSquare = BuildTesselatedQuad( 1, 1 ); CopyMovieProgram = BuildProgram( "uniform highp mat4 Mvpm;\n" "attribute vec4 Position;\n" "attribute vec2 TexCoord;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_Position = Position;\n" " oTexCoord = TexCoord;\n" "}\n" , "#extension GL_OES_EGL_image_external : require\n" "uniform samplerExternalOES Texture0;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_FragColor = texture2D( Texture0, oTexCoord );\n" "}\n" ); } // If the SurfaceTexture has changed dimensions, we need to // reallocate the texture and FBO. glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_EXTERNAL_OES, AndroidSurfaceTexture->textureId ); // FIXME: no way to get texture dimensions even in ES 3.0??? int width = 960; int height = 540; if ( width != TexIdWidth || height != TexIdHeight ) { LOG( "New surface size: %ix%i", width, height ); TexIdWidth = width; TexIdHeight = height; if ( Fbo ) { glDeleteFramebuffers( 1, &Fbo ); } glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, TexId ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TexIdWidth, TexIdHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glBindTexture( GL_TEXTURE_2D, 0 ); glActiveTexture( GL_TEXTURE0 ); glGenFramebuffers( 1, &Fbo ); glBindFramebuffer( GL_FRAMEBUFFER, Fbo ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TexId, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } glBindFramebuffer( GL_FRAMEBUFFER, Fbo ); glDisable( GL_DEPTH_TEST ); glDisable( GL_SCISSOR_TEST ); glDisable( GL_STENCIL_TEST ); glDisable( GL_CULL_FACE ); glDisable( GL_BLEND ); const GLenum fboAttachments[1] = { GL_COLOR_ATTACHMENT0 }; glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, fboAttachments ); glViewport( 0, 0, TexIdWidth, TexIdHeight ); glUseProgram( CopyMovieProgram.program ); UnitSquare.Draw(); glUseProgram( 0 ); glBindTexture( GL_TEXTURE_EXTERNAL_OES, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glBindTexture( GL_TEXTURE_2D, TexId ); glGenerateMipmap( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, 0 ); }