Petite précision : le problème vient tout simplement lorsque plein de surfaces sont superposées (même sans le depth test).
Voici un code utilisant glew :
10 000 carrés (20 000 triangles)
Vertex Buffer : oui
Indices Buffer : oui
Texture : non
Shader : non
#include <iostream>
#include <sstream>
#include <GL/glew.h>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <random>
#define NB_POLY 10000
using namespace std;
using namespace sf;
int main()
{
RenderWindow app(VideoMode(800,600),"OpenGL");
glewInit();
float* vertexData = new float[12*NB_POLY];
for(int i=0;i<NB_POLY;i++)
{
vertexData[0+i*12] = -0.05f;
vertexData[1+i*12] = 0.05f;
vertexData[2+i*12] = -1.0f;
vertexData[3+i*12] = 0.05f;
vertexData[4+i*12] = 0.05f;
vertexData[5+i*12] = -1.0f;
vertexData[6+i*12] = 0.05f;
vertexData[7+i*12] = -0.05f;
vertexData[8+i*12] = -1.0f;
vertexData[9+i*12] = -0.05f;
vertexData[10+i*12] = -0.05f;
vertexData[11+i*12] = -1.0f;
}
short* indiceData = new short[6*NB_POLY];
for(int i=0;i<NB_POLY;i++)
{
indiceData[0+i*6] = 0+i*4;
indiceData[1+i*6] = 1+i*4;
indiceData[2+i*6] = 2+i*4;
indiceData[3+i*6] = 0+i*4;
indiceData[4+i*6] = 2+i*4;
indiceData[5+i*6] = 3+i*4;
}
//Buffer Object
GLuint vertexBufferObject;
glGenBuffers(1,&vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER,vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*12*NB_POLY,vertexData,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
GLuint indiceBufferObject;
glGenBuffers(1,&indiceBufferObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indiceBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(short)*6*NB_POLY,indiceData,GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
Clock time;
int nbFPS = 0;
while(app.isOpen())
{
if(time.getElapsedTime().asMilliseconds() >= 1000)
{
ostringstream ss;
ss << nbFPS;
nbFPS = 0;
app.setTitle(ss.str());
time.restart();
}
else
nbFPS++;
Event event;
while(app.pollEvent(event))
{
if(event.type == Event::Closed)
app.close();
}
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,vertexBufferObject);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indiceBufferObject);
glDrawElements(GL_TRIANGLES, 6*NB_POLY, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
app.display();
}
glDeleteBuffers(1,&vertexBufferObject);
glDeleteBuffers(1,&indiceBufferObject);
return 0;
}
Avec 20 000 triangles, j'obtiens ~60 FPS.... C'est pas très optimal...
Selon ce que j'ai compris, il s'agit d'overdraw : tous les triangles sont dessinés. Cela signifie donc remplir environ 100x100x10 000 pixels à chaque frame. 100 M de pixels par frame, je crois que c'est très coûteux en ressources...
Maintenant, si je met des Z aléatoires, je tourne à 180 FPS avec 10 000 carrés :
default_random_engine generator;
uniform_real_distribution<float> distribution(-1,1);
RenderWindow app(VideoMode(800,600),"OpenGL");
glewInit();
float* vertexData = new float[12*NB_POLY];
for(int i=0;i<NB_POLY;i++)
{
float rand = distribution(generator);
vertexData[0+i*12] = -0.05f;
vertexData[1+i*12] = 0.05f;
vertexData[2+i*12] = -1.0f+rand;
vertexData[3+i*12] = 0.05f;
vertexData[4+i*12] = 0.05f;
vertexData[5+i*12] = -1.0f+rand;
vertexData[6+i*12] = 0.05f;
vertexData[7+i*12] = -0.05f;
vertexData[8+i*12] = -1.0f+rand;
vertexData[9+i*12] = -0.05f;
vertexData[10+i*12] = -0.05f;
vertexData[11+i*12] = -1.0f+rand;
}
Remarque aussi que si l'on dessine 10 000 shape :
ConvexShape shape;
shape.setPointCount(4);
shape.setPoint(0,Vector2f(0,0));
shape.setPoint(1,Vector2f(100,0));
shape.setPoint(2,Vector2f(100,100));
shape.setPoint(3,Vector2f(0,100));
for(int i=0;i<10000;i++)
app.draw(shape);
Ça tourne à 8 FPS. Sauf qu'il me semble que chaque draw(shape) est un appel à glDraw*(). Ce qui est tout à fait normal que ça coûte cher si on appelle 10 000 fois le driver par frame...
Comment faire pour gérer cela plus efficacement ?
Merci et bonne journée !