Here is my minimal example:
#include <GLee.h>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
using namespace std;
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
#define QUADCOUNT 10000
#define WINDOWWIDTH 1024
#define WINDOWHEIGHT 768
struct MyQuad
{
float x1, y1, z1, nx1, ny1, nz1, tx1, ty1;
float x2, y2, z2, nx2, ny2, nz2, tx2, ty2;
float x3, y3, z3, nx3, ny3, nz3, tx3, ty3;
float x4, y4, z4, nx4, ny4, nz4, tx4, ty4;
};
sf::RenderWindow* context;
sf::Event event;
sf::Clock timer;
GLuint VBOVertices;
GLuint texture;
MyQuad* qo;
float ftime;
int fps, nfps;
float fpstime;
int main(int argc, char** argv) {
context = new sf::RenderWindow(sf::VideoMode(WINDOWWIDTH, WINDOWHEIGHT, 32), "WindowTitle");
qo = new struct MyQuad[QUADCOUNT];
for (int x=0; x<QUADCOUNT; x++) {
qo[x].x1=1; qo[x].y1=1; qo[x].z1=-5; qo[x].nx1=0; qo[x].ny1=0; qo[x].nz1=1; qo[x].tx1=1; qo[x].ty1=0;
qo[x].x2=0; qo[x].y2=1; qo[x].z2=-5; qo[x].nx2=0; qo[x].ny2=0; qo[x].nz2=1; qo[x].tx2=0; qo[x].ty2=0;
qo[x].x3=0; qo[x].y3=0; qo[x].z3=-5; qo[x].nx3=0; qo[x].ny3=0; qo[x].nz3=1; qo[x].tx3=0; qo[x].ty3=1;
qo[x].x4=1; qo[x].y4=0; qo[x].z4=-5; qo[x].nx4=0; qo[x].ny4=0; qo[x].nz4=1; qo[x].tx4=1; qo[x].ty4=1;
}
glGenBuffers(1, &VBOVertices);
glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyQuad)*QUADCOUNT, NULL, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyQuad)*QUADCOUNT, &qo[0].x1);
delete [] qo;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,(float)WINDOWWIDTH/(float)WINDOWHEIGHT,1, 100.0);
glViewport(0,0,WINDOWWIDTH,WINDOWHEIGHT);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
sf::Image surface;
if (!surface.LoadFromFile("texture.png")) return 1;
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface.GetWidth(), surface.GetHeight(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface.GetPixelsPtr() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
while (1)
{
while (context->GetEvent(event))
if (event.Type == sf::Event::KeyPressed)
{
if (event.Key.Code == sf::Key::Escape) {
context->Close();
exit(0);
}
}
ftime = timer.GetElapsedTime();
timer.Reset();
nfps++; fpstime+=ftime; if (fpstime>1.0) { fps = nfps; nfps = 0; fpstime=0; cout << fps << endl; }
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.8,0.8,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
glVertexPointer(3, GL_FLOAT, 32, BUFFER_OFFSET(0));
glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(12));
glTexCoordPointer(2, GL_FLOAT, 32, BUFFER_OFFSET(24));
glDrawArrays(GL_QUADS, 0, QUADCOUNT*4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
context->Display();
}
return 0;
}
You'll have to have a texture.png for it to run...
Here are some fps tests I did:
QUADCOUNT 10000, WINDOWWIDTH 1024, WINDOWHEIGHT 768 = 16fps
QUADCOUNT 10000, WINDOWWIDTH 800, WINDOWHEIGHT 600 = 16fps
QUADCOUNT 10000, WINDOWWIDTH 640, WINDOWHEIGHT 480 = 17fps
QUADCOUNT 10000, WINDOWWIDTH 320, WINDOWHEIGHT 240 = 63fps
QUADCOUNT 5000, WINDOWWIDTH 1024, WINDOWHEIGHT 768 = 28fps
QUADCOUNT 5000, WINDOWWIDTH 800, WINDOWHEIGHT 600 = 31fps
QUADCOUNT 5000, WINDOWWIDTH 640, WINDOWHEIGHT 480 = 32fps
QUADCOUNT 5000, WINDOWWIDTH 320, WINDOWHEIGHT 240 = 125fps
QUADCOUNT 1000, WINDOWWIDTH 1024, WINDOWHEIGHT 768 = 123fps
QUADCOUNT 1000, WINDOWWIDTH 800, WINDOWHEIGHT 600 = 143fps
QUADCOUNT 1000, WINDOWWIDTH 640, WINDOWHEIGHT 480 = 150fps
QUADCOUNT 1000, WINDOWWIDTH 320, WINDOWHEIGHT 240 = 560fps
It seems to be suffering from the same problem as my original code. In my original code, I can render 425000 quads with ease, as long as I create the VBOs before the RenderWindow.
In this minimal code, it doesn't seem to matter if I create the RenderWindow before or after. So now I'm really confused, I must be doing something wrong. :shock: