views:

332

answers:

5

First off, I'm programming a game. Currently in the render function there are two calls to two different functions. One renders some text, one renders sprites.

On my computer (AMD Phenom(tm) II X4 955 Processor (4 CPUs), ~3.2GHz, 4096MB RAM DDR2, NVIDIA GeForce GTX 285) I have a render speed of ~2200 FPS when rendering around 200 sprites and about 100 FPS when rendering about 14,500.

I'm using a vector to store the information of each object I'm rendering and using one sprite with many draw calls.

VS2008 release mode with full optimization for C++. I know I've heard left and right don't optimize prematurely, but at this point, it's running great for me, but not so well on certain computers.

I can't imagine changing vectors out for arrays since I'm pushing and pulling things from the vector every frame, in an indeterminable method. Nearly randomly.

I've tried floats and doubles and the speed is no different.

Would it be different using DirectDraw rather than DirectX and the Sprite Render method? Since I've no idea the differences between DirectDraw and DirectX, I'm not 100% what I should be thinking about that.

The game runs fine on average computers, but what I'm comparing my game to is Touhou. Touhou runs at 60 FPS on the weakest computer I've tried, but my game won't run faster than 36~42 FPS. I can't imagine what I'm doing wrong, being so new to DirectX and C++.

Any assistance in this matter would be great, unfortunately I won't be around for awhile to add information or answers questions.

+1  A: 

I'm using a vector to store the information of each object I'm rendering and using one sprite with many draw calls.

I'm not sure I understand what you're saying, but this sounds like you're drawing essentially the same object in a lot of different places. If that's the case, you probably want to look up DirectX Instancing. The basic idea is you specify 1) the geometry to draw, and 2) a number of places to draw it. This saves re-specifying the geometry every time you draw the object, so it can improve speed considerably.

Jerry Coffin
I'll have to look more into Instancing and dX in general, because from what I've read (admittedly not enough) I'm not sure how I would do such a thing with sprites. I understand where you're coming from though, I just have to look more into this.
+1  A: 

I can't imagine changing vectors out for arrays since I'm pushing and pulling things from the vector every frame, in an indeterminable method. Nearly randomly.

Are you inserting and/or removing things from positions other than the back of the vector? In a vector, insertions and removals from the middle take O(n) time, that is, the amount of time it takes is proportional to the size of your vector.

If that is the case, then consider using an std::list instead. Note that with 10k+ objects this could easily be causing your performance issues, depending on how often you do it.

Peter Alexander
It is often quicker to add them to the end of a vector and then sort it. As long as the sort only happens once a frame this can provide lovely performance boost.
Goz
I am creating objects and adding them to the end of the vector. They move at random speeds and in random directions. Once they reach any area outside of a defined rectangle, they are removed. Meaning, they will be removed from any spot in the array, not just the end. Does this still warrant the use of a list?
Yes, removals from random locations in the vector still has a substantial cost. Note that lists also have their costs, so I would recommend to at least try it out if it isn't too much trouble and see what the difference is.
Peter Alexander
+5  A: 

You need a profiler.

There's some good performance advice in the responses, but it doesn't matter. Trying to optimize a program without a profiler is like trying to write a program without a compiler. Do not guess, measure.

Now with that said, profiling graphics code is an infamous pain in the neck, and there aren't (to my knowledge) any good, free tools to help with it. So never mind that for now: start with an ordinary CPU profiler, and find out which of your calls is really taking up all your time.

David Seiler
Pix is very useful for optimising DirectX btw. You need to have a DAMNED good understanding of how DirectX works to see the performance issues though. Failing that, if you are on an nVidia card, NV's Perf HUD is the mutz nutz.
Goz
+1  A: 

Profile your application, and determine if your bottleneck is the CPU or the GPU (or the transfer BUS between the two) When determined you have a few choices :

1) If its the CPU, you can try instancing to reduce the number of draws call. Or if your target machine does not support Hardware instancing, try a kind of batching. To instance or Batch a sprite you have to use a QUAD (2 triangle orientated) as the default interface does.

2) If its the GPU, try to understand if its a shader causing the slowdown. If that's the case try to optimize it. If its not the shader, try to reduce overdraw. IF part of your objects are not transparent using front-to-back drawing.

3) If its the BUS, try to do as with the CPU, as with batching you reduce the number of Locks/Unlocks you need to transfer the data. (with instancing you would not need to update the buffer at all)

That's all. :P

P.S. A warning...DO NOT TRY TO PROFILE DirectX calls with a CPU profiler. (but use PerfHud from nVidia or GPUPerfStudio from ATI, or GPA from Intel) Its just time losed, DirectX has a command buffer and you are not assured that a call made now it is executed that time. Most of the time it returns immediately and do nothing.

feal87
A: 

Check out this gpu profiling tool: http://busyray.com/dxprof/index.html

Shows you what part of your code is the slowest for the hardware. Extremely useful one, I didn't see anything better.

Sergey