My OpenGL application (written in Java using LWJGL) works fine when rendering the scene normal. Now i have implemented deferred rendering an it’s running only at about 30 fps. I havent got many models in my 3D scene.
Sadly it is very difficult to debug those performance issues cause i’m not able to measure the time of each method call in code, cause they’re not executed immediatley. Also i’m not able to use gdebugger with my java application (or very difficult).
Rendering-Code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GraphicsData.camera.setView();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
multipleRenderTarget.start();
drawEntities();
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
multipleRenderTarget.stop();
if(1==0)
{
multipleRenderTarget.showTexture(0, 512, 384, 0, 0);
multipleRenderTarget.showTexture(1, 512, 384, 512, 0);
multipleRenderTarget.showTexture(2, 512, 384, 0, 384);
}
else
{
DeferredRendering.render();
}
Object that manages the Framebufferobject: (called multipleRenderTarget)
private int fbo;
private int diffuseRT;
private int positionRT;
private int normalsRT;
private int depthBuffer;
private int diffuseTexture;
private int positionTexture;
private int normalsTexture;
//Constructor
public FBORenderTexture() throws Exception
{
fbo = glGenFramebuffers();
diffuseRT = glGenRenderbuffers();
positionRT = glGenRenderbuffers();
normalsRT = glGenRenderbuffers();
depthBuffer = glGenRenderbuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, diffuseRT);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, GraphicsData.WIDTH, GraphicsData.HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, diffuseRT);
glBindRenderbuffer(GL_RENDERBUFFER, positionRT);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, GraphicsData.WIDTH, GraphicsData.HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, positionRT);
glBindRenderbuffer(GL_RENDERBUFFER, normalsRT);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, GraphicsData.WIDTH, GraphicsData.HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, normalsRT);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, GraphicsData.WIDTH, GraphicsData.HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
diffuseTexture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GraphicsData.WIDTH, GraphicsData.HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, diffuseTexture, 0);
positionTexture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, positionTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, GraphicsData.WIDTH, GraphicsData.HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionTexture, 0);
normalsTexture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, normalsTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, GraphicsData.WIDTH, GraphicsData.HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsTexture, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw new Exception(“Can’t initialize FBO!”);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void start()
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, GraphicsData.WIDTH, GraphicsData.HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0f, 0f, 0f, 1f);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
IntBuffer buffers = BufferUtils.createIntBuffer(3);
buffers.put(0, GL_COLOR_ATTACHMENT0);
buffers.put(1, GL_COLOR_ATTACHMENT1);
buffers.put(2, GL_COLOR_ATTACHMENT2);
glDrawBuffers(buffers);
glUseProgram(shaderEngine.mrt);
shaderEngine.loadMatrix(glGetUniformLocation(shaderEngine.mrt, “projectionMatrix”), GraphicsData.camera.projectionMatrix);
shaderEngine.loadMatrix(glGetUniformLocation(shaderEngine.mrt, “viewMatrix”), GraphicsData.camera.viewMatrix);
}
public void stop()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopAttrib();
glUseProgram(0);
}
[FONT=arial]Final rendering code:
[/FONT]//Projection setup
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,GraphicsData.WIDTH,0,GraphicsData.HEIGHT,0.1f,2);
//Model setup
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glUseProgram(shaderEngine.rendering);
glUniform3f(glGetUniformLocation(shaderEngine.rendering, “cameraPosition”), GraphicsData.camera.x, GraphicsData.camera.y, GraphicsData.camera.z);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, renderEngine.multipleRenderTarget.getDiffuseTexture());
glUniform1i(glGetUniformLocation(shaderEngine.rendering, “diffuseTexture”), 0);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, renderEngine.multipleRenderTarget.getPositionTexture());
glUniform1i(glGetUniformLocation(shaderEngine.rendering, “positionTexture”), 1);
glActiveTexture(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, renderEngine.multipleRenderTarget.getNormalsTexture());
glUniform1i(glGetUniformLocation(shaderEngine.rendering, “normalsTexture”), 2);
//Render the quad
glLoadIdentity();
glColor4f(1f, 1f, 1f, 1f);
glTranslatef(0f, 0f, -1.0f);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0 );
glVertex3f( 0.0f, 0.0f, 0.0f);
glTexCoord2f( 1, 0 );
glVertex3f( (float) GraphicsData.WIDTH, 0.0f, 0.0f);
glTexCoord2f( 1, 1 );
glVertex3f( (float) GraphicsData.WIDTH, (float) GraphicsData.HEIGHT, 0.0f);
glTexCoord2f( 0, 1 );
glVertex3f( 0.0f, (float) GraphicsData.HEIGHT, 0.0f);
glEnd();
//Reset OpenGL state
glActiveTexture(GL_TEXTURE0);
// glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE2);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glUseProgram(0);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
Deffered shading vertex shader:
#version 130
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat3 normalMatrix;
out vec3 normals;
out vec4 position;
void main()
{
//use normalMatrix calculated on CPU
//mat4 worldMatrix = modelMatrix;
//mat3 worldRotationInverse = transpose(mat3(worldMatrix));
gl_Position = projectionMatrix * viewMatrix * modelMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
normals = normalize(normalMatrix * gl_Normal);
position = modelMatrix * gl_Vertex;
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
}
[FONT=arial]Deferred shading fragment shader:
#version 130
uniform sampler2D tex;
in vec3 normals;
in vec4 position;
void main()
{
gl_FragData[0] = vec4(texture2D(tex, gl_TexCoord[0].st).rgb, 1);
gl_FragData[1] = vec4(position.xyz, 1);
gl_FragData[2] = vec4(normals.xyz,1);
}
Deffered rendering vertex shader:
[/FONT][FONT=arial][FONT=courier new]#version 130
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
}
Deffered rendering fragment shader:
[/FONT]#version 130
uniform sampler2D diffuseTexture;
uniform sampler2D positionTexture;
uniform sampler2D normalsTexture;
uniform vec3 cameraPosition;
void main()
{
vec4 image = texture2D(diffuseTexture, gl_TexCoord[0].xy);
vec4 position = texture2D(positionTexture, gl_TexCoord[0].xy);
vec3 normal = texture2D(normalsTexture, gl_TexCoord[0].xy).xyz;
vec3 light = vec3(0, 0, 0);
vec3 lightDir = light - position.xyz;
normal = normalize(normal);
lightDir = normalize(lightDir);
vec3 eyeDir = normalize(cameraPosition - position.xyz);
vec3 vHalfVector = normalize(lightDir.xyz + eyeDir);
vec4 diffuseComponent = max(dot(normal,lightDir),0.0) * image;
float specularComponent = pow(max(dot(normal,vHalfVector),0.0), 100) * 1.5;
gl_FragColor = diffuseComponent + specularComponent;
}
How can i speed the rendering process up? Which tools may i use to debug it?[/FONT]