_Silver_

08-05-2015, 10:37 AM

Hello everyone,

Currently working on a robot simulation project, I come to you after many days of work to get into OpenGL, build my environment and optimize render time. My aim is to get several objects (spheres, cubes, tubes, perhaps some simple VRML models displays in special cases) displayed and updated quickly. Most of them would be static and I would never get more than around 50~100 of them so it should be simple, right ? :)

Here is how I processed : for reasons unrelated to OpenGL integration to my project, my classes are structured as shown in the following figure. I simplified it and isolated the visual / OpenGL-related classes for this help request.

2035

For now, my objects are generated from a config file with the following format :

OBSTACLE = >SPHERE

POSITION = 1,1,0

ROTATION = 90,90,0

TRANSPARENCY = 1.0

COLOR = 0,60,100

DRAWTYPE = >STREAM

RADIUS = 0.1

OBSTACLE = >SPHERE

POSITION = 0.0,0,1

ROTATION = 10,20,40

TRANSPARENCY = 1.0

COLOR = 255,0,0

DRAWTYPE = >STREAM

RADIUS = 0.1

OBSTACLE = >PATH

POSITION = 0,0,1

ROTATION = 20,0,0

TRANSPARENCY = 0.6

COLOR = 0,120,220

DRAWTYPE = >STATIC

RADIUS = 0.05

From this, I instanciate my classes, generate the vertices, colors, normal vectors, etc. An example (screenshot while I set a movement trajectory for both spheres) looks like this :

2036

First, I displayed around 10 shapes like this following the simplest tutorials, with simple diffuse + ambient lighting. The uniforms I would then send would approximately take 100ms per frame (CPU clock) ... But I feel it isn't a surprise to start like that since I'm a beginner.

Now, I implemented VBOs, VAOs and UBOs to get better results and it did work. I'm not satisfied yet though since it takes between 20 and 50ms to render a single frame (CPU clock) with the previous config (3 objects : 1 tube & 2 spheres).

I feel I am doing at least a few things wrong which lead to this unsatisfying computing time.

Here are some initialization stuff and the main loop I use to render the scene :

/************************************/

/******** INITIALIZING STUFF ********/

/************************************/

bool loop = true;

/* Sunlight parameters */

sunlight.fAmbientIntensity = glm::vec4(0.25);

sunlight.vColor = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);

glm::vec3 sunlightPos(10.0f,11.0f,12.0f);

glm::vec3 sunlightTmp = -glm::normalize(sunlightPos);

sunlight.vDirection = glm::vec4(sunlightTmp.x, sunlightTmp.y, sunlightTmp.z, 0.0f);

glm::mat4 projection;

glm::mat4 modelview;

glm::mat4 normalMatrix;

glm::mat4 camera;

projection = glm::perspective(70.0, (double) getWindowWidth()/getWindowHeight(), 1.0, 100.0);

modelview = glm::mat4(1.0);

camera = glm::lookAt(glm::vec3(2, 2, 2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));

initUbos();

glBindBuffer(GL_UNIFORM_BUFFER, lightUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Light), &sunlight);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBuffer(GL_UNIFORM_BUFFER, staticMatricesUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), &projection);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

/****************************/

/******** MAIN LOOP *********/

/****************************/

while(loop){

/* Cleaning window */

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for(int i=0;i<env.getNObstacles();i++){

modelview = glm::mat4(1.0);

glUseProgram(env.getObstacle(i).getShape()->getGraph().getShader().getProgramId());

/* Translate element*/

modelview = glm::translate(modelview,glm::vec3(env.getObstacle (i).getShape()->getPosition(0),env.getObstacle(i).getShape()->getPosition(1),env.getObstacle(i).getShape()->getPosition(2)));

/* Rotate element */

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(2), glm::vec3(0.0,0.0,1.0)); // Z axis

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(1), glm::vec3(0.0,1.0,0.0)); // Y axis

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(0), glm::vec3(1.0,0.0,0.0)); // X axis

/* Normal matrix - for lighting purposes */

normalMatrix = glm::transpose(glm::inverse(modelview));

modelview = camera*modelview;

glBindVertexArray(env.getObstacle(i).getShape()->getGraph().getVaoId());

glBindBuffer(GL_UNIFORM_BUFFER, streamingMatricesUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), &modelview);

glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), &normalMatrix);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

glDrawArrays(GL_TRIANGLES, 0, env.getObstacle(i).getShape()->getGraph().getN());

glBindVertexArray(0);

glUseProgram(0);

}

// Refreshing window

SDL_GL_SwapWindow(window);

}

Just in case, here is my vertex shader :

#version 150

in vec3 in_Vertex;

in vec4 in_Color;

in vec3 in_Normal;

layout(std140) uniform StaticMatrices

{

mat4 projection;

};

layout(std140) uniform StreamingMatrices

{

mat4 modelview;

mat4 normalMatrix;

};

out vec4 color;

smooth out vec3 vNormal;

void main() {

gl_Position = projection * modelview * vec4(in_Vertex, 1.0);

color = in_Color;

vec4 vTemp = normalMatrix * vec4(in_Normal,0.0);

vNormal = vTemp.xyz;

}

And my fragment shader :

#version 150

in vec4 color;

smooth in vec3 vNormal;

out vec4 out_Color;

layout(std140) uniform Light

{

vec3 vColor;

vec3 vDirection;

float fAmbientIntensity;

};

void main() {

float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -vDirection));

out_Color = color*vec4(vColor*(fAmbientIntensity+fDiffuseInten sity), 1.0);

}

Here is my computer's configuration in case I am being too optimistic about my render resources :

CPU : Intel Core 2 Duo CPU E6750 2.66GHz

RAM : 4Go

GPU : NVIDIA GeForce GT 630

OS : Windows 7 SP1 32bits

IDE : Visual Studio Express 2012

What do you think I do wrong that causes useless resources consumption ?

Many thanks for your time. I hope I have been concise and provided all the necessary data and if not, I shall answer quickly to complete my post.

_Silver_

Currently working on a robot simulation project, I come to you after many days of work to get into OpenGL, build my environment and optimize render time. My aim is to get several objects (spheres, cubes, tubes, perhaps some simple VRML models displays in special cases) displayed and updated quickly. Most of them would be static and I would never get more than around 50~100 of them so it should be simple, right ? :)

Here is how I processed : for reasons unrelated to OpenGL integration to my project, my classes are structured as shown in the following figure. I simplified it and isolated the visual / OpenGL-related classes for this help request.

2035

For now, my objects are generated from a config file with the following format :

OBSTACLE = >SPHERE

POSITION = 1,1,0

ROTATION = 90,90,0

TRANSPARENCY = 1.0

COLOR = 0,60,100

DRAWTYPE = >STREAM

RADIUS = 0.1

OBSTACLE = >SPHERE

POSITION = 0.0,0,1

ROTATION = 10,20,40

TRANSPARENCY = 1.0

COLOR = 255,0,0

DRAWTYPE = >STREAM

RADIUS = 0.1

OBSTACLE = >PATH

POSITION = 0,0,1

ROTATION = 20,0,0

TRANSPARENCY = 0.6

COLOR = 0,120,220

DRAWTYPE = >STATIC

RADIUS = 0.05

From this, I instanciate my classes, generate the vertices, colors, normal vectors, etc. An example (screenshot while I set a movement trajectory for both spheres) looks like this :

2036

First, I displayed around 10 shapes like this following the simplest tutorials, with simple diffuse + ambient lighting. The uniforms I would then send would approximately take 100ms per frame (CPU clock) ... But I feel it isn't a surprise to start like that since I'm a beginner.

Now, I implemented VBOs, VAOs and UBOs to get better results and it did work. I'm not satisfied yet though since it takes between 20 and 50ms to render a single frame (CPU clock) with the previous config (3 objects : 1 tube & 2 spheres).

I feel I am doing at least a few things wrong which lead to this unsatisfying computing time.

Here are some initialization stuff and the main loop I use to render the scene :

/************************************/

/******** INITIALIZING STUFF ********/

/************************************/

bool loop = true;

/* Sunlight parameters */

sunlight.fAmbientIntensity = glm::vec4(0.25);

sunlight.vColor = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);

glm::vec3 sunlightPos(10.0f,11.0f,12.0f);

glm::vec3 sunlightTmp = -glm::normalize(sunlightPos);

sunlight.vDirection = glm::vec4(sunlightTmp.x, sunlightTmp.y, sunlightTmp.z, 0.0f);

glm::mat4 projection;

glm::mat4 modelview;

glm::mat4 normalMatrix;

glm::mat4 camera;

projection = glm::perspective(70.0, (double) getWindowWidth()/getWindowHeight(), 1.0, 100.0);

modelview = glm::mat4(1.0);

camera = glm::lookAt(glm::vec3(2, 2, 2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));

initUbos();

glBindBuffer(GL_UNIFORM_BUFFER, lightUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Light), &sunlight);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBuffer(GL_UNIFORM_BUFFER, staticMatricesUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), &projection);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

/****************************/

/******** MAIN LOOP *********/

/****************************/

while(loop){

/* Cleaning window */

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for(int i=0;i<env.getNObstacles();i++){

modelview = glm::mat4(1.0);

glUseProgram(env.getObstacle(i).getShape()->getGraph().getShader().getProgramId());

/* Translate element*/

modelview = glm::translate(modelview,glm::vec3(env.getObstacle (i).getShape()->getPosition(0),env.getObstacle(i).getShape()->getPosition(1),env.getObstacle(i).getShape()->getPosition(2)));

/* Rotate element */

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(2), glm::vec3(0.0,0.0,1.0)); // Z axis

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(1), glm::vec3(0.0,1.0,0.0)); // Y axis

modelview = glm::rotate(modelview,(float) env.getObstacle(i).getShape()->getRotation(0), glm::vec3(1.0,0.0,0.0)); // X axis

/* Normal matrix - for lighting purposes */

normalMatrix = glm::transpose(glm::inverse(modelview));

modelview = camera*modelview;

glBindVertexArray(env.getObstacle(i).getShape()->getGraph().getVaoId());

glBindBuffer(GL_UNIFORM_BUFFER, streamingMatricesUboId);

glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), &modelview);

glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), &normalMatrix);

glBindBuffer(GL_UNIFORM_BUFFER, 0);

glDrawArrays(GL_TRIANGLES, 0, env.getObstacle(i).getShape()->getGraph().getN());

glBindVertexArray(0);

glUseProgram(0);

}

// Refreshing window

SDL_GL_SwapWindow(window);

}

Just in case, here is my vertex shader :

#version 150

in vec3 in_Vertex;

in vec4 in_Color;

in vec3 in_Normal;

layout(std140) uniform StaticMatrices

{

mat4 projection;

};

layout(std140) uniform StreamingMatrices

{

mat4 modelview;

mat4 normalMatrix;

};

out vec4 color;

smooth out vec3 vNormal;

void main() {

gl_Position = projection * modelview * vec4(in_Vertex, 1.0);

color = in_Color;

vec4 vTemp = normalMatrix * vec4(in_Normal,0.0);

vNormal = vTemp.xyz;

}

And my fragment shader :

#version 150

in vec4 color;

smooth in vec3 vNormal;

out vec4 out_Color;

layout(std140) uniform Light

{

vec3 vColor;

vec3 vDirection;

float fAmbientIntensity;

};

void main() {

float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -vDirection));

out_Color = color*vec4(vColor*(fAmbientIntensity+fDiffuseInten sity), 1.0);

}

Here is my computer's configuration in case I am being too optimistic about my render resources :

CPU : Intel Core 2 Duo CPU E6750 2.66GHz

RAM : 4Go

GPU : NVIDIA GeForce GT 630

OS : Windows 7 SP1 32bits

IDE : Visual Studio Express 2012

What do you think I do wrong that causes useless resources consumption ?

Many thanks for your time. I hope I have been concise and provided all the necessary data and if not, I shall answer quickly to complete my post.

_Silver_