About glTexImage2D

Hi,

I get every frame from function ViewFinderFrameReady in symbian os. i want to render the
frame as backgroud. So i used these codes:

TBitmapUtil* pBmpUtil=new (ELeave)TBitmapUtil(iBitmap);
	
	pBmpUtil->Begin(TPoint(0,0));

	TUint8* aCamFrameData=(TUint8*)iBitmap->DataAddress(); 

	pBmpUtil->End();
	
	delete pBmpUtil;
	

	// Textures are initialized in OpenGL ES API by this function.
   glGenTextures( 1, iTexturesID );	
   

   //Bind the background texture to iTexturesID[0], set the texture environment. 
   glBindTexture( GL_TEXTURE_2D, iTexturesID[0] );
   
   
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
   
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
   
   
   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
   
   glTexImage2D(  GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 
		   0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)aCamFrameData );

   glViewport( 0, 0, size.iWidth, size.iHeight);

   // Recalculate the view frustrum
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
   GLfloat aspectRatio = (GLfloat)(size.iWidth) / (GLfloat)(size.iHeight);
   glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
   FRUSTUM_BOTTOM, FRUSTUM_TOP,
   FRUSTUM_NEAR, FRUSTUM_FAR );
   glMatrixMode( GL_MODELVIEW );

   // Switch to our projection matrix so that we can change it to ortho mode, not perspective.
   glMatrixMode(GL_PROJECTION);						
   // Push on a new matrix so that we can just pop it off to go back to perspective mode
   glPushMatrix();			

   glDisable( GL_DEPTH_TEST );
   glDisable( GL_CULL_FACE  );
  
   // Reset the current matrix to our identify matrix
   glLoadIdentity();								
   // Pass in our 2D ortho screen coordinates (left, right, bottom, top, near, far).  
   glOrthof( 0, 1, 0, 1, -1, 1 );	
	
   // Switch to model view so that we can render the texture
   glMatrixMode(GL_MODELVIEW);								
   // Initialize the current model view matrix with the identity matrix
   glLoadIdentity();
   
   glPushMatrix();
   // Enable vertex arrays.
   glEnableClientState( GL_VERTEX_ARRAY );
   // Set array pointers.
   glVertexPointer( 2, GL_BYTE, 0, bgverts );
   // Enable texture arrays 
   glEnableClientState( GL_TEXTURE_COORD_ARRAY );
   // Set texture coords
   glTexCoordPointer( 2, GL_BYTE, 0, bgtex );
   glEnable(GL_TEXTURE_2D);
   glBindTexture( GL_TEXTURE_2D, iTexturesID[0] );
   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   glDisable(GL_TEXTURE_2D);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glDisableClientState(GL_VERTEX_ARRAY);
   glPopMatrix();
   
   
   // Load our projection matrix
   glMatrixMode( GL_PROJECTION );							
   glEnable( GL_DEPTH_TEST );
   glEnable( GL_CULL_FACE  );
	
   // Get rid of ortho mode which was lst pushed in the projection matrix mode
   glPopMatrix();											
   // Go back to model view matrix
   glMatrixMode( GL_MODELVIEW );
   

   

// Call eglSwapBuffers, which blit the graphics to the window
CImageConverterContainer* instance = (CImageConverterContainer*) this;
eglSwapBuffers( instance->iEglDisplay, instance->iEglSurface );

but the result is out of my expectation.[attachment=0:3seaevl5]001.jpg[/attachment:3seaevl5]
could anyone help me ? Thank you

Mia

What exactly do you need TBitmapUtil for? Before you call iBitmap->DataAddress() you should call iBitmap->LockHeap(), and call iBitmap->UnlockHeap() after glTexImage2D. Are you sure the bitmap is in 24-bit RGB format?

Hi,

it’s EColor16M,which means that it is true colour display mode (32 bpp, but top byte is unused and unspecified) . Could i use setdispay() function to set it is EColor16M(RGB24)?
Or any other ways?
Thank you for your help.

Mia

What you’re describing is EColor16MU. EColor16M is 24bpp without the unused byte.

Assuming this was a typo and you actually meant EColor16MU, using (GL_RGB, GL_UNSIGNED_BYTE) is certainly wrong since that means OpenGL ES will expect 3 bytes per pixel, not 4. I don’t know whether you can change the output mode of the camera, but if it’s possible I’d recommend using EColor64K and (GL_RGB, UNSIGNED_SHORT_5_6_5). If you can’t change the output mode you’ll have to convert the data to some format OpenGL ES accepts.

Hi,

I use SetDisPlayMode() function to set it EColor16M successfully. I want to know if it in
BBBBBBBBGGGGGGGGRRRRRRRR format. If it is , then i need to swap B and R bytes.
Another question, i also find that in glTexImage2D functin there is GL_RGBA as internalformat and format of image, so could i use glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes) without change the image’s display mode? I tried but it didn’t work. Thank you for your help.

Mia

Hi,
I still haven’t sovle my problem. I donn’t know where is the erro. Could anyone help me?
i get every frame form ViewFinderFrameBuffer function. I make a copy of this frame and swap R and B value. And i want to use this frame as texture. but it always is strange. You can see the video on :http://www.youtube.com/watch?v=mVrWornQPpA,it seems that it can render something in vertical direction .
These are the codes i used:


static const GLbyte bgverts[8] = 
	{ 
        0, 0,
        1, 0,
        0, 1,
        1, 1
	};
 
static const GLubyte bgtex[8] =
	{
	0, 1,
	1, 1,
	0, 0,
	1, 0
	};






void CCameraAppBaseContainer::DrawImageNow(CFbsBitmap& aBitmap,double* gl_para)
    {
    iBitmap = &aBitmap;
    
   
    TDisplayMode Mode=iBitmap->DisplayMode();
    

    TBuf<15> formName;
    
    TInt iWidth,iHeight;
    iWidth=iBitmap->SizeInPixels().iWidth; //264
    iHeight=iBitmap->SizeInPixels().iHeight;//198
    TUint stride=iBitmap->ScanLineLength(iWidth,EColor16MU);
    
    
    TUint8 temp;
    
    
    /*
     * copy the iBitmap to iDescToBmp*/
 
    TBuf8<264*4> aBuf;
    TPoint Pt(0,0); 
   
    
    CFbsBitmap* iDescToBmp;
    iDescToBmp = new(ELeave)CFbsBitmap();
     
    iDescToBmp->Create(iBitmap->SizeInPixels(),EColor16MU);
  

    for (TInt i = 0;i < iHeight ; i++) 
   {
       Pt.iY=i;
       
       iBitmap->GetScanLine(aBuf,Pt,iWidth,EColor16MU);

       iDescToBmp->SetScanLine(aBuf,i);
       
    }
    
    TUint8* data;
    iDescToBmp->LockHeap();
    data=(TUint8*)iDescToBmp->DataAddress();
    
    for (TInt i = 0;i < 198*264*4-4 ; i=i+4) {
        
 	     
            temp=data[i];
            data[i]=data[i+2];
            data[i+2]=temp;
 	   
 	     
    }
    iDescToBmp->UnlockHeap();
  
   
    RenderTextureBG(*iDescToBmp);

    CCameraAppBaseContainer* instance=(CCameraAppBaseContainer*)this;
    
    /* Call eglSwapBuffers, which blit the graphics to the window */
    eglSwapBuffers( instance->iEglDisplay, instance->iEglSurface );
    
    delete iDescToBmp;
    iDescToBmp=NULL;
}
void CCameraAppBaseContainer::RenderTextureBG(CFbsBitmap& aBitmap)
	{
	
	
	
	
	// Textures are initialized in OpenGL ES API by this function.
    glGenTextures( 1, iTexturesID );	
    

    //Bind the background texture to iTexturesID[0], set the texture environment. 
    glBindTexture( GL_TEXTURE_2D, iTexturesID[0] );
    
    aBitmap.LockHeap();
    TUint8* aCamFrameData=(TUint8*)aBitmap.DataAddress();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, aCamFrameData);  
    aBitmap.UnlockHeap();

    
    
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);       
   
   		    
    // Before drawing the background texture, we need to switch to ortho (2D) mode.  
    // Passing 1 instead of the implicit size of screen will make OpeGL use the full size of screen (1:1)
    OrthoMode(0, 1, 0, 1);	
    DrawBGPoly();
    PerspectiveMode();
		    
    glDeleteTextures(1, iTexturesID);


}

void CCameraAppBaseContainer::OrthoMode(TInt aLeft,TInt aRight,TInt aBottom,TInt aTop)
	{
	// Switch to our projection matrix so that we can change it to ortho mode, not perspective.
    glMatrixMode(GL_PROJECTION);						
    // Push on a new matrix so that we can just pop it off to go back to perspective mode
    glPushMatrix();			

    glDisable( GL_DEPTH_TEST );
    glDisable( GL_CULL_FACE  );
   
    // Reset the current matrix to our identify matrix
    glLoadIdentity();								
    // Pass in our 2D ortho screen coordinates (left, right, bottom, top, near, far).  
    glOrthof( aLeft, aRight, aBottom, aTop, -1, 1 );	
	
    // Switch to model view so that we can render the texture
    glMatrixMode(GL_MODELVIEW);								
    // Initialize the current model view matrix with the identity matrix
    glLoadIdentity();

	}

void CCameraAppBaseContainer::PerspectiveMode()
	{
	// Load our projection matrix
    glMatrixMode( GL_PROJECTION );							
    glEnable( GL_DEPTH_TEST );
    glEnable( GL_CULL_FACE  );
	
    // Get rid of ortho mode which was lst pushed in the projection matrix mode
    glPopMatrix();											
    // Go back to model view matrix
    glMatrixMode( GL_MODELVIEW );

	}

void CCameraAppBaseContainer::DrawBGPoly()
	{
	glPushMatrix();
    // Enable vertex arrays.
    glEnableClientState( GL_VERTEX_ARRAY );
    // Set array pointers.
    glVertexPointer( 2, GL_BYTE, 0, bgverts );
    // Enable texture arrays 
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    // Set texture coords
    glTexCoordPointer( 2, GL_BYTE, 0, bgtex );
    glEnable(GL_TEXTURE_2D);
    glBindTexture( GL_TEXTURE_2D, iTexturesID[0] );
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glPopMatrix();

}

Please help me, it puzzlled me for several days.
Thank you for your help.
Mia

You’re taking a 264x198 image and pass it to OpenGL as if it was 256x128. That can’t work, each line in the texture will appear shifted 8 pixels further to the right. You need to copy a subrectangle of the image which is 256x128 pixels in size.

what do that mean? I make a copy of the frame image :

CFbsBitmap* iDescToBmp;
    iDescToBmp = new(ELeave)CFbsBitmap();
    TSize  iSize;
    iSize.iWidth=256;
    iSize.iHeight=128;
    iDescToBmp->Create(iSize,EColor16MU);
  
    TBitmapUtil* pBmpUtil=new (ELeave)TBitmapUtil(iBitmap);
 	//CleanupStack::PushL(pBmpUtil);
 	
 	TBitmapUtil* pBmpUtil2=new (ELeave)TBitmapUtil(iDescToBmp);
 	//CleanupStack::PushL(pBmpUtil2);
 	
	pBmpUtil->Begin(TPoint(0,0));
	
	pBmpUtil2->Begin(TPoint(0,0),*pBmpUtil);
	
	
	TUint8* pBitmapDatas=(TUint8*)iBitmap->DataAddress();//typedefind ARUint8 unsigned char
	
	TUint8* pnewBitmapDatas=(TUint8*)iDescToBmp->DataAddress();
	
	TUint8* temp;
	TUint8* newtemp;
	
	  
    
  for(TInt j=35;j<=162;j++) //make a center rectage of the image 
 	   {
 	   for(TInt i=4;i<=259;i++)
 		   {
 		   temp=(TUint8 *)pBitmapDatas+264*j+i;
 		   
 		   newtemp=(TUint8 *)pnewBitmapDatas+256*(j-35)+(i-4);
 	
 		   *(newtemp)=*(temp);
 		    	 
 			   
 		   }
 	   }
    
    pBmpUtil->End();
	pBmpUtil2->End();
	
	delete pBmpUtil;
	delete pBmpUtil2;

It seems that it only render the right side on the screen. And the bottom appears on the top of the scrren.The most part of the left scrren is whrite. These are the mode i use to render:

aBitmap.LockHeap();
    TUint8* aCamFrameData=(TUint8*)aBitmap.DataAddress();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, aCamFrameData);  
    aBitmap.UnlockHeap();

    
    
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR  );  

Why? did i make a wrong copy or a wrong render mode?
Looking forward your replying fast.

Mia

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.