Hi all,
I’m having a little trouble with rendering to FBOs, with both PVRFrame and the actual device, a Sony Ericsson Satio. The first problem is that I’m unable to create a stencil-renderbuffer in PVRFrame (for glRenderbufferStorage with GL_STENCIL_INDEX8 it says "Error 500 (Invalid Enum): unknown or unsupported internal format), however on the device it works without any problems.
Here’s my code:
bool InitBackBuffers(iString& errorInfo){
//Create Stencil-Renderbuffer
glGenRenderbuffers(1, &stencilRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER,stencilRenderBuffer);
//This line causes Problems in PVRFrame
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, screenwidth,screenheight);
//Create depth-texture
//the functions are simply some object-oriented wrappers for the gl functions
depthTexture=new CTexture2D();
depthTexture->Bind();
depthTexture->SetData(0,GL_DEPTH_COMPONENT,screenwidth,screenheight,GL_UNSIGNED_INT,0);
IPAQRenderState::SetTextureWrappingS(GL_CLAMP_TO_EDGE);
IPAQRenderState::SetTextureWrappingT(GL_CLAMP_TO_EDGE);
IPAQRenderState::SetTextureMagFilter(GL_NEAREST);
IPAQRenderState::SetTextureMinFilter(GL_NEAREST);
IPAQRenderState::BindTexture(GL_TEXTURE_2D,0);
//BACKBUFFERCNT is one at the moment
for(int i=0; i<BACKBUFFERCNT; i++){
//gernerate color rendertarget
renderTargets = new CTexture2D();
renderTargets->SetData(0,GL_RGBA,screenwidth,screenheight,GL_UNSIGNED_BYTE,NULL);
renderTargets->Bind();
IPAQRenderState::SetTextureWrappingS(GL_CLAMP_TO_EDGE);
IPAQRenderState::SetTextureWrappingT(GL_CLAMP_TO_EDGE);
IPAQRenderState::SetTextureMagFilter(GL_NEAREST);
IPAQRenderState::SetTextureMinFilter(GL_NEAREST);
IPAQRenderState::BindTexture(GL_TEXTURE_2D,0);
//generate framebuffer
glGenFramebuffers(1,&framebuffers);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture->GetGLName(),0);
//glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_STENCIL_ATTACHMENT,GL_RENDERBUFFER,stencilRenderBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, renderTargets[0]->GetGLName(), 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status!=GL_FRAMEBUFFER_COMPLETE){
if(status==GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) errorInfo.Append("FBO incomplete.n");
if(status==GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) errorInfo.Append("FBO incomplete_Missing.n");
return false;
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
void SetRenderTarget(GLint num){
//only call gl functions if its necessary
if(num==currFramebuffer) return;
// -1 = default framebuffer
if(num==-1) glBindFramebuffer(GL_FRAMEBUFFER, 0);
else glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[num]);
currFramebuffer=num;
}
unsigned long framenum=0;
void Render(CNode** nodes, unsigned int count, CCamera& activeCam){
framenum++;
IPAQRenderState::SetClearColor(0,0,1,1);
for(int i=BACKBUFFERCNT-1; i>=0; i--){
SetRenderTarget(i);
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
}
//Render Some test objects
CRenderingEnvironment rendenv;
rendenv.framenum=framenum;
rendenv.ViewMat=activeCam.GetViewMatrix();
rendenv.ProjectionMat=activeCam.GetProjectionMatrix();
TVector<Light*> lightlist;
TVector<RenderCol> meshlist;
TMat43 identityMatrix;
GLfloat ambientLight[4]={0,0,0,0};
for(int i=0; i<count; i++)
IPAQRenderer::CollectRenderingInformation(rendenv,nodes,identityMatrix,meshlist,lightlist,ambientLight);
for(int i=0; i<meshlist.Size(); i++){
meshlist.mesh->LoadShaderDataToGL(meshlist.submeshindex,rendenv,meshlist.modelmat);
meshlist.mesh->LoadVertexDataToGL(rendenv,meshlist.modelmat);
meshlist.mesh->LoadSubmeshDataToGL(meshlist.submeshindex,rendenv,meshlist.modelmat);
meshlist.mesh->RenderSubmesh(meshlist.submeshindex,rendenv,meshlist.modelmat);
}
//Object rendering finished
// A shader for rendering a textured fullscreenquad multiplied with a color
CShaderProgram* HUDShaderProgram = IPAQShaderManager::GetHudShader();
IPAQRenderState::UseShaderProgram(*HUDShaderProgram);
//Render To system-provided Framebuffer;
SetRenderTarget(-1);
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
IPAQRenderState::SetDepthTest(false);
IPAQRenderState::SetBlendingEnabled(false);
renderFullscreenQuad(renderTargets[0]);
IPAQHudDrawer::DoDrawings();
eglSwapBuffers(iEglDisplay, iEglSurface );
}
The second problem is with sampling from a depth texture. I do this by replacing the line
with
Using PVRFrame I can see a nice grayscale image of the depth of scene, however on the device the screen is just totally black. And sometimes it changes it's color to white for a short time or another strange rendering artifact occurs: some tiles of the screen get swapped randomly, eg. I can see a part of the text rendered at the top left corner rotated about 90 degrees in the middle of the screen ^^.
BTW: The engine code for PVRFrame and symbian is exactly the same, only a small "base-layer" for out- and input is different.
Thank you for your help in advance!