Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: I think SFML can be faster if it use gl buffers  (Read 8431 times)

0 Members and 2 Guests are viewing this topic.

Yuki

  • Newbie
  • *
  • Posts: 1
    • View Profile
I think SFML can be faster if it use gl buffers
« on: October 27, 2007, 04:02:07 pm »
Hi ,I am new here and I am very interested in SFML . and I think it could run faster if it use gl buffers . In my D engine.I use vertex buffer to accumulate the vertex and redner all the buffer when texture or render state changes. You can see the HGE for example . I think it will make SFML run faster.
first I check the gl versions : if it support buffer object ,enable buffer rendering .else if it support vertex array . enable vertex array .else use the begin end method.
second my video driver has a function " void drawQuadList(Quad * list,int length)" and draw the quad list .

 
Code: [Select]

// create the buffer
if (rm == RenderMethod.RM_BUFFER)
            {
                glGenBuffers(1,&buffer);
                glBindBuffer(GL_ARRAY_BUFFER,buffer);

                // pre-alloc the buffer
                bufferSize = RM_BUFFER_SIZE;
                glBufferData(GL_ARRAY_BUFFER,bufferSize,null,GL_STREAM_DRAW);

                glEnableClientState(GL_COLOR_ARRAY);
                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);

                Vertex v;
                glVertexPointer(3,GL_FLOAT,Vertex.sizeof,cast(void *) (0 ));
                glColorPointer(4,GL_FLOAT,Vertex.sizeof,cast(void *)( cast(ubyte *)(&(v.r)) - cast(ubyte *)(&(v.x)) ) );
                glTexCoordPointer(2,GL_FLOAT,Vertex.sizeof,cast(void *) ( cast(ubyte*)(&(v.tx)) - cast(ubyte *)(&(v.x)) ) );
            }
            else if (rm == RenderMethod.RM_VERTEXARRAY)
            {
                glEnableClientState(GL_COLOR_ARRAY);
                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            }
            else if (rm == RenderMethod.RM_BEGINEND)
            {
            }


//videoDriver's draw
void drawQuadList(Quad * list,int length)
        {
            if (rm == RenderMethod.RM_BUFFER)
            {
                //glBufferData(GL_ARRAY_BUFFER,length * Quad.sizeof,cast(void*)list,GL_STREAM_DRAW);

                if (length * Quad.sizeof > bufferSize)
                {
                    bufferSize = length * Quad.sizeof;
                    glBufferData(GL_ARRAY_BUFFER,bufferSize,null,GL_STREAM_DRAW);
                }

                glBufferSubData(GL_ARRAY_BUFFER,0,length * Quad.sizeof,cast(void *)list);
                glDrawArrays(GL_QUADS,0,length * 4);
            }
            else if (rm == RenderMethod.RM_VERTEXARRAY)
            {
                glVertexPointer(3,GL_FLOAT,Vertex.sizeof,cast(void *)(&(list[0].points[0].x)));
                glColorPointer(4,GL_FLOAT,Vertex.sizeof,cast(void *)(&(list[0].points[0].r)));
                glTexCoordPointer(2,GL_FLOAT,Vertex.sizeof,cast(void *)(&(list[0].points[0].tx)));

                glDrawArrays(GL_QUADS,0,length * 4);
            }
            else if (rm == RenderMethod.RM_BEGINEND)
            {
                glBegin (GL_QUADS);
                int i;
                for (i = 0; i < length; i++)
                {
                    int j;
                    for (j = 0; j < 4; j ++ )
                    {
                        glTexCoord2f(list[i].points[j].tx,list[i].points[j].ty);
                        glColor4f(list[i].points[j].r,list[i].points[j].g,list[i].points[j].b,list[i].points[j].a);
                        glVertex3f(list[i].points[j].x,list[i].points[j].y,list[i].points[j].z);
                    }
                }
                glEnd ();
            }

        }


third I use a 2D render to render the quads

Code: [Select]

// quad's render
        void renderEx(float x,float y,float angle,float scale)
        {
            Quad q = quad;
            for (int i = 0; i < 4; i ++)
            {
                // scale
                q.points[i].x *= scale;
                q.points[i].y *= scale;
                // rotate
                float tempx = q.points[i].x;
                float tempy = q.points[i].y;
                q.points[i].x = cos(angle) * tempx - sin(angle) * tempy;
                q.points[i].y = sin(angle) * tempx + cos(angle) * tempy;
                // translate
                q.points[i].x += x;
                q.points[i].y += y;
            }
            SceneRenderer.getInstance().renderQuad(q,texture);
        }


// scenerenderer's renderQuad
 void renderQuad(in Quad q,Texture t)
        {
            if ((currentTexture !is t) || bufferSize >= BUFFER_LENGTH)
            {
                currentTexture = t;
                renderBuffer();
                videoDriver.applyTexture(t);
            }
            buffer[bufferSize] = q;
            bufferSize ++;
        }
        void beginRender()
        {
            currentTexture = null;
        }
        void endRender()
        {
            renderBuffer();
        }

// render buffer
 void renderBuffer()
        {
            if (bufferSize > 0)
            {
                videoDriver.drawQuadList(cast(Quad *)buffer,bufferSize);
            }
            bufferSize = 0;
        }


hope my code helps. And you can see HGE as a example for quad accumulate method .

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
I think SFML can be faster if it use gl buffers
« Reply #1 on: October 27, 2007, 04:14:32 pm »
I know, I know.

In fact, nothing related to OpenGL has been heavily optimized in SFML. I want to keep things simple until the API has a robust and fixed design. Then, if people ask for better performances (will it ever happen ? 2D rendering is quite cheap whatever you do), I'll be able to optimize it and make people happy.
Laurent Gomila - SFML developer

lzr

  • Newbie
  • *
  • Posts: 48
    • View Profile
    • http://lzr.cc
I think SFML can be faster if it use gl buffers
« Reply #2 on: May 02, 2008, 01:01:39 am »
If better performance is an option, and all you need is people to ask, then I'm definitely asking. The game I'm porting has some levels that have fairly simple particle effects that involve drawing a lot of sprites. Under my old Direct3d engine, I got great performance, but on the same computer, under SFML, the game slows down very significantly. So much so that it is unplayable. Any speed enhancements you can think of would be great.

Slightly unrelated, but still important, my sprite loading times are also quite a bit slower than they were with D3DX.

SFML is a great, simple API, but in terms of performance there is a lot of room for improvement.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
I think SFML can be faster if it use gl buffers
« Reply #3 on: May 02, 2008, 04:39:13 am »
Building a particle system with sprites is definitively overkill. For performances, it should be built with direct OpenGL calls (using a dynamic VBO, or at least vertex arrays). However, it doesn't mean you can't include this thing in a regular SFML program ; just put it in a custom sf::Drawable.

If I wanted to include fast particles in SFML, I'd have to build a specific class for it, which is out of scope.

For image loading, is the difference significant ?
Laurent Gomila - SFML developer

lzr

  • Newbie
  • *
  • Posts: 48
    • View Profile
    • http://lzr.cc
I think SFML can be faster if it use gl buffers
« Reply #4 on: May 02, 2008, 08:35:30 am »
Ok, well when I say particle systems, I mean really simple ones, not big ones. Anyways, I made some optimizations in my code and now it works a lot better. Better performance would still be a plus, although not as necessary. Load times, on the other hand, could use some tweaking. Currently you keep the pixels for the image in an STL vector. I think everything would go much faster if you kept them in a simple byte array. That way, you don't need to loop through all the pixels every time you load an image, you can just take the direct output from SOIL. Also, including a way to load a subset of an image would be convenient.

dabo

  • Sr. Member
  • ****
  • Posts: 260
    • View Profile
    • http://www.dabostudios.net
I think SFML can be faster if it use gl buffers
« Reply #5 on: May 02, 2008, 12:26:17 pm »
I also find loading images a bit slow, but I have nothing to compare it to so I don't know if it is "too slow". Not a big issue though, but if it could be speeded up relatively easy I wouldn't say no.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
I think SFML can be faster if it use gl buffers
« Reply #6 on: May 02, 2008, 01:33:06 pm »
I'll see if I can improve images loading. There might be some places to optimize ;)
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
I think SFML can be faster if it use gl buffers
« Reply #7 on: May 02, 2008, 03:13:24 pm »
It wasn't long to test : there's only one thing that could be slightly optimized (the code is 115% faster now), the rest is up to SOIL internal code.

But image loading is quite fast in my opinion, what kind of loading times do you experience, and with what type / size of images ? The only weird thing I found is BMP loading, which take a huge amount of time compared to other formats (even JPEG) ; it's probably because the file is 10x bigger on disk.
Laurent Gomila - SFML developer