×

Discussion Board

Results 1 to 12 of 12
  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    OpenGL render to texture

    I'm trying to render a scene to a texture so i can later put it in a mesh and to deform it. The secret for this appears to be the pbuffer, I've made 2 surfaces (EGLSurface) and contexts (EGLContext) one for the screen and the other for the pbuffer.
    This in theory allows me to play with the current rendering context with eglMakeCurrent and render particular parts of the scene in the pbuffer or the window.
    I assume everything up to this point is done, I get no errors and i can render something to the window just fine.
    Here is where i have my problem, I create a texture and bind it to the pbuffer, I've read in another forum that we only need to do this once, here is the code.
    Code:
    iPBuffer = eglCreatePbufferSurface( iDisplay, iPConfig, attrib_list2 ); glGenTextures(1, &pbufferTex); glBindTexture(GL_TEXTURE_2D, pbufferTex); eglBindTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER); glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    After this I initialize some stuff in the pbuffer's context, here is the code:
    Code:
        glClearColor( 1.f, 0.f, 0.f, 1.f );
        // Enable back face culling.
        glEnable( GL_CULL_FACE  );
        // Enable vertex arrays.
        glEnableClientState( GL_VERTEX_ARRAY );
        // Set array pointers.
        glVertexPointer( 3, GL_BYTE, 0, vertices );
        // Enable color arrays.
        glEnableClientState( GL_COLOR_ARRAY );
        // Set color pointers.
        glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colors );
        // Set the initial shading mode
        glShadeModel( GL_FLAT );
        // Do not use perspective correction
        glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
    I do something similar in the windows surface
    After all this I go to the rendering cycle
    Here is the code:
    Code:
    void CTarget::renderLoop(TInt aFrame) {
    	glBindTexture(GL_TEXTURE_2D, pbufferTex);
    	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, iWidth, iHeight, 0);
            
            // render to pbuffer
    	switchCurrent(1); // switch to the pbuffer's context
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    	glLoadIdentity();
    	glTranslatex( 0 , 0 , -100 << 16 );
    	glRotatex( aFrame << 16, 1 << 16,    0   ,    0    );
    	glRotatex( aFrame << 15,    0   , 1 << 16,    0    );
    	glRotatex( aFrame << 14,    0   ,    0   , 1 << 16 );
    	glScalef( 15.f, 15.f, 15.f );
    	glDrawElements( GL_TRIANGLES, 12 * 3, GL_UNSIGNED_BYTE, triangles );
    
    	// render to window
    	switchCurrent(0); // switch to the windows' context
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    	glLoadIdentity();
    	glTranslatex( 0 << 16, 0, -100 << 16 );
    	glScalex( 10 << 16, 10 << 16, 10 << 16 );
    	glRotatex( aFrame << 16, 1 << 16,    0   ,    0    );
    	glRotatex( aFrame << 15,    0   , 1 << 16,    0    );
    	glRotatex( aFrame << 14,    0   ,    0   , 1 << 16 );
    	
    	glBindTexture(GL_TEXTURE_2D,pbufferTex);
    
    	glDrawElements( GL_TRIANGLES, NUM_FACES_CUBE * 3, GL_UNSIGNED_BYTE, objFacedataCube );
            eglSwapBuffers( iDisplay, iWindow );
    }
    The objective was to use the contents of the pbuffer as a texture for the cube, but when i try it the cube is just white.
    No matter what i try, it either isn't copying the frame data from the pbuffer or nothing is being written to the pbuffer.

    I'm using the S60 3rd edition fp2 sdk 1.1, right now I'm working on the emulator, but the target device is an N95.

    If anyone could point me somewhere with a code example of a render to texture demo working on symbian it would also be a great help.

    Thanks
    Roberto
    Last edited by Daemoniorum; 2009-02-23 at 20:14.

  2. #2
    Regular Contributor
    Join Date
    Apr 2004
    Posts
    96

    Re: OpenGL render to texture

    Where do you use eglMakeCurrent ? There is no code for rendering into pbuffer also. If you don't render anything you have nother in the pbuffer texture.

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Re: OpenGL render to texture

    the eglMakeCurrent is in the switchCurrent function.
    Code:
    void COpenGLES::switchCurrent(TInt surface) {
    	if (surface == 0) {
    		if ( eglMakeCurrent( iDisplay, iWindow, iWindow, iWContext ) == EGL_FALSE ) {
    			_LIT(KMakeCurrentFailed, "eglMakeCurrent failed");
    			User::Panic( KMakeCurrentFailed, 0 );
    		}
    	} else {
    		if ( eglMakeCurrent( iDisplay, iPBuffer, iPBuffer, iPContext ) == EGL_FALSE ) {
    			_LIT(KMakeCurrentFailed, "eglMakeCurrent failed");
    			User::Panic( KMakeCurrentFailed, 0 );
    		}
    	}
    }
    One thing that I noticed is that I'm using two contexts iWContext and iPContext for the windows and the pbuffer.
    At first I wanted to use just one, but when i tried to create it like this
    Code:
    const EGLint attrib_list[] = {
    
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_BUFFER_SIZE, iBufferSize, EGL_DEPTH_SIZE, 16, EGL_NONE };
    eglChooseConfig( iDisplay, attrib_list, configList, configSize, &numOfConfigs )
    He can't find any configs, so i was forced to do two contexts one with only EGL_WINDOW_BIT and the other with EGL_PBUFFER_BIT.
    Also here is the attribute list for the pbuffer
    Code:
    EGLint attrib_list[] = {
    	EGL_CONFIG_CAVEAT, EGL_NONE,
            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
            EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE,
            EGL_NONE
        };

  4. #4
    Regular Contributor
    Join Date
    Apr 2004
    Posts
    96

    Re: OpenGL render to texture

    IIRC eglBindTexImage should be called not during the initialization but after the rendering into texture.
    see http://www.khronos.org/opengles/sdk/...ndTexImage.xml
    Also had you initialized render texture with glTexImage2D ?

  5. #5
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Re: OpenGL render to texture

    OK i think we are getting somewhere I made the changes you said and now the cube is completely black except for the edges that have some white pixels.
    Here is the code of what I changed.
    Pbuffer initialization
    Code:
    	iPBuffer = eglCreatePbufferSurface( iDisplay, iPConfig, attrib_list2 );
        if ( iPBuffer == NULL ) {
            _LIT(KCreatePbufferSurfaceFailed, "eglCreatePbufferSurface failed");
            User::Panic( KCreatePbufferSurfaceFailed, 0 );
        }
    
    	glGenTextures(1, &pbufferTex);
    	glBindTexture(GL_TEXTURE_2D, pbufferTex);
    	glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	rgbxBuffer = new TUint[256 *256];
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256 ,256 , 0, GL_RGB, GL_UNSIGNED_BYTE, rgbxBuffer);
    and the render loop
    Code:
    void CTarget::renderLoop(TInt aFrame) {
    	front->switchCurrent(1);
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    	glLoadIdentity();
    	glTranslatex( 0 , 0 , -100 << 16 );
    	glRotatex( aFrame << 16, 1 << 16,    0   ,    0    );
    	glRotatex( aFrame << 15,    0   , 1 << 16,    0    );
    	glRotatex( aFrame << 14,    0   ,    0   , 1 << 16 );
    	glScalef( 15.f, 15.f, 15.f );
    	glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colors );
    	glVertexPointer( 3, GL_BYTE, 0, vertices );
    	glDrawElements( GL_TRIANGLES, 12 * 3, GL_UNSIGNED_BYTE, triangles );
    
    	// render to window
    	front->switchCurrent(0);
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    	glLoadIdentity();
    	glTranslatex( 0 << 16, 0, -100 << 16 );
    	glScalex( 10 << 16, 10 << 16, 10 << 16 );
    	glRotatex( aFrame << 16, 1 << 16,    0   ,    0    );
    	glRotatex( aFrame << 15,    0   , 1 << 16,    0    );
    	glRotatex( aFrame << 14,    0   ,    0   , 1 << 16 );
    	glBindTexture(GL_TEXTURE_2D, front->pbufferTex);
    	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);
    	glVertexPointer( 3, GL_FLOAT, 0, objVertexdata );
    	glNormalPointer( GL_BYTE, 0, objNormaldata );
    	glTexCoordPointer( 2, GL_BYTE, 0, objTexdata );
    	glDrawElements( GL_TRIANGLES, NUM_FACES_CUBE * 3, GL_UNSIGNED_BYTE, objFacedataCube );
    	eglSwapBuffers( front->iDisplay, front->iWindow );
    }
    Thanks for your help

    EDIT: when I change all the GL_RGB to GL_RGBA the cube becomes invisible except for the white pixels in the borders.
    Last edited by Daemoniorum; 2009-02-24 at 12:14.

  6. #6
    Regular Contributor
    Join Date
    Apr 2004
    Posts
    96

    Re: OpenGL render to texture

    Pbuffer initialization:
    I don't think you have to actually create texture - only initialize it.
    Try instead dummy texture, without reserving videomemory
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256 ,256 , 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

    renderLoop:
    I don't see actual binding after rendering into pbuffer.
    Add
    glBindTexture(GL_TEXTURE_2D, front->pbufferTex);
    eglBindTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER);
    before
    // render to window

    For debug:
    replace *all* rendering into pbuffer with
    front->switchCurrent(1);
    glClearColor(1, 0, 0, 1);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glBindTexture(GL_TEXTURE_2D, front->pbufferTex);
    eglBindTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER);
    only.
    That way if you will get red cube you will now the rendering into texture work correctly.
    Otherwise you have to worry if the bug is in the first rendering into pbuffer.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Re: OpenGL render to texture

    If i use
    Code:
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256 ,256 , 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    and
    Code:
    eglBindTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER);
    It renders one frame and fails the change to the pbuffer context on the second frame.
    Same thing happens with the glTexImage2D(...,rgbxBuffer);
    I'm thinking it's something about the EGL_BACK_BUFFER.
    The initialization code is exactly the same as before with the exception of the glTexImage2D.
    The render code has the changes you said to make:
    Code:
    void CTarget::renderLoop(TInt aFrame) {
    	// render to pbuffer
    	front->switchCurrent(1);
    	glClearColor(1, 0, 0, 1);
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    
    	glBindTexture(GL_TEXTURE_2D, pbufferTex);
    	eglBindTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER);
    
    
    	// render to window
    	front->switchCurrent(0);
    	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    	glLoadIdentity();
    	glTranslatex( 0 << 16, 0, -100 << 16 );
    	glScalex( 10 << 16, 10 << 16, 10 << 16 );
    	glRotatex( aFrame << 16, 1 << 16,    0   ,    0    );
    	glRotatex( aFrame << 15,    0   , 1 << 16,    0    );
    	glRotatex( aFrame << 14,    0   ,    0   , 1 << 16 );
    		
    	glBindTexture(GL_TEXTURE_2D, pbufferTex);
    	
    	glVertexPointer( 3, GL_FLOAT, 0, objVertexdata );
    	glNormalPointer( GL_BYTE, 0, objNormaldata );
    	glTexCoordPointer( 2, GL_BYTE, 0, objTexdata );
    	glDrawElements( GL_TRIANGLES, NUM_FACES_CUBE * 3, GL_UNSIGNED_BYTE, objFacedataCube );
    	eglSwapBuffers( iDisplay, iWindow );
    }
    I need to bind pbufferTex again in the render to window block, I don't think that affects anything, but just to note it.

    Thanks

  8. #8
    Regular Contributor
    Join Date
    Apr 2004
    Posts
    96

    Re: OpenGL render to texture

    Aha.
    You should release pbuffer after using it as texture.
    call
    eglReleaseTexImage(iDisplay, iPBuffer, EGL_BACK_BUFFER) after rendering into *windows*
    probably after eglSwapBuffers( iDisplay, iWindow );

    Also, are you setting depth buffer bit then choosing config during pbuffer initialization?
    Also, I'm not sure it necessary, but try to put glViewport (0, 0,256, 256); after front->switchCurrent(1); and another glViewport after front->switchCurrent(0);
    btw EGL_BACK_BUFFER is the only possible value.

  9. #9
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Re: OpenGL render to texture

    It changes context perfectly now but it is still a completely black cube, though I noticed that when I use glTexImage2D(..., 0); it is indeed completely black, when i use glTexImage2D(..., rgbxBuffer); the white pixels on the borders return.
    Every thing else remains the same except for the changes you asked me to do.

    As for setting the depth buffer bit, if you mean configure the viewport and frustum and all those scene specific things then the answer is no, I create the surfaces and context then I handle all of that according to which context is currently active.

    Basically the program is structured like:
    Create display
    Create windows surface
    Create windows context
    Make windows current
    Create pbuffer survace
    Create pbuffer context
    Initialize pbuffer
    Make pbuffer current
    initialize scene related opengl functions like glShadeModel( GL_FLAT );
    calculate viewport and frustrum for pbuffer
    make window current
    initialize scene related opengl functions like glShadeModel( GL_FLAT );
    calculate viewport and frustrum for window
    render loop

    EDIT: I noticed that I'm making the window's context current right after I create it and the pbuffer's initialization is occurring when the window is current. I removed that and the cube went from black to completely white.
    Last edited by Daemoniorum; 2009-02-24 at 22:00. Reason: Extra bit of info

  10. #10
    Regular Contributor
    Join Date
    Apr 2004
    Posts
    96

    Re: OpenGL render to texture

    You could have some problem in initialization
    1. You should try to use the same context for pbuffer and win. Don't create pbuffer context at all, use win. What config are you using ?
    2. What param list are you using for eglChooseConfig for creating pbuffer surface ?

    PS Better post all you initialization code. It may help.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    29

    Re: OpenGL render to texture

    For two EGLSurfaces to be compatible with the same EGLContext they do not need to use the same EGLConfig. So it's best to query the window and pbuffer configs separately. They should have the same colour bit depth, though, otherwise you will indeed need two contexts.

    You should not call glTexImage2D or glCopyTexImage2D on the texture object to which the pbuffer is currently bound. These calls will implicitly release the pbuffer from the texture. The pbuffer should not be bound to a texture and bound as the current draw surface at the same time.

    In case you need two contexts, the structure should be as follows:
    Initialization:
    - Create display
    - Create window surface and context
    - Create pbuffer surface and context
    - Make window context/surface current
    - Set base GL state for window context
    - Create a texture object and set its parameters (glGenTexture, glBindTexture, glTexParameter)
    - Make pbuffer context/surface current
    - Set base GL state for pbuffer context
    Render loop:
    - Make pbuffer context/surface current
    - Render to pbuffer (glDraw*)
    - Make window context/surface current
    - bind texture and bind pbuffer to it (glBindTexture, eglBindTexImage)
    - Render to window (uses pbuffer as texture)
    - release pbuffer from texture (eglReleaseTexImage)
    - eglSwapBuffers

  12. #12
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Re: OpenGL render to texture

    My first thought was to use the same context for both the pbuffer and the window, using this attribute list
    Code:
    const EGLint attrib_list[] = {
    	EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
    	EGL_BUFFER_SIZE,  iBufferSize,
    	EGL_DEPTH_SIZE,   16,
    	EGL_NONE
        };
    but it couldn't find any configs using the above, so i was forced to do two contexts one for the window using
    Code:
    const EGLint attrib_list[] = {
    	EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    	EGL_BUFFER_SIZE,  iBufferSize,
    	EGL_DEPTH_SIZE,   16,
    	EGL_NONE
        };
    and the other for the pbuffer using
    Code:
    const EGLint attrib_list[] = {
    	EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    	EGL_BUFFER_SIZE,  iBufferSize,
    	EGL_DEPTH_SIZE,   16,
    	EGL_NONE
    };
    and just for completions sake here are the attribute list i used to create the pbuffer
    Code:
    EGLint attrib_list2[] = { 
    	EGL_WIDTH,	256,
    	EGL_HEIGHT,	256,
    	EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
    	EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, 
    	EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
    	EGL_NONE
    };
    serg3d if you want anymore say the word.
    Xmas I still haven't tried what you said, I'm going to do it now and I'll comeback with the results.

    Thanks.

    EDIT: That did it Xmas, it's perfect
    Thanks a lot the both of ya, this was driving me crazy.
    Last edited by Daemoniorum; 2009-02-25 at 15:33.

Similar Threads

  1. Using camera frame as OpenGL texture, problem!!
    By abolfoooud in forum Symbian Media (Closed)
    Replies: 29
    Last Post: 2009-06-18, 02:58
  2. Series 60 BMP Texture Mapping With OpenGL ES Problem
    By abolfoooud in forum Symbian Media (Closed)
    Replies: 7
    Last Post: 2008-06-13, 03:53
  3. Does OpenGL ES texture have dedicated mem on Phones with 3D Hardware?
    By limingchina in forum Symbian Media (Closed)
    Replies: 0
    Last Post: 2008-01-16, 23:03
  4. load texture in Opengl ES
    By alabama83 in forum Symbian Media (Closed)
    Replies: 0
    Last Post: 2005-10-07, 16:14
  5. Series 60 BMP Texture Mapping With OpenGL ES Problem
    By abolfoooud in forum Mobile Java Media (Graphics & Sounds)
    Replies: 1
    Last Post: 2005-09-13, 16:13

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×