[SOLVED - thanks] Problems with Direct3D

Started by deee, Mon 27/06/2011 14:39:20

Previous topic - Next topic

deee

Hello everyone,

I have tried out both Direct3D 9 and DirectDraw 5 Graphics Drivers with the game I am working on (AGS 3.2.)

Direct3D provides way better optical results in displaying the characters with the option "smooth scaled sprites."
So I wanted to keep it running with Direct3D. While testing the game and the debugging features, I just came across the FPS and saw that the game was running very slowly with Direct3D (~26 Frames, whereas in DirectDraw, I always had an average of ~40 FPS.)

The weirdest thing in Direct3D is: while a function is active, that draws an image onto the background surface every 3rd game loop (first, it was every game loop, but i reduced it to every 3rd, because of the performance), the FPS goes up to 40 and the overall speed of the game just seems accurately smooth.
Does anybody know a solution to this issue?
It would be great to have the game running under Direct3D, but there must be a better workaround than using drawimage (maybe with an empty sprite) every game loop, or there must be a reason why the game is running that slowly while not using drawimage every cycle.

Greetz,

Deee


suicidal pencil

#1
Quote from: AGS Editor, General Settings panel...Direct3D allows fast high-resolution alpha-blended sprites, but DirectDraw is better at RawDrawing

RawDrawing can eat FPS if not done efficiently in both D3D-9 and DirectDraw-5, especially if the image is large with lots of changing pixels. Using DirectDraw-5 mitigates the FPS loss but can still get bogged down if you're using RawDraw a lot. D3D-9 is used for fast rendering of complicated sprites but doesn't deal with RawDrawing very well.

A trick I found to minimizing the amount of RawDrawing is to preload the sprites into memory.

So for example, lets say you had one sprite that you wanted to be able to rotate 360 degrees, one degree every loop. Instead throwing 360 separate images into an animation or rotating it as a DynamicSprite one degree every game loop, rotate and save every image into an array before the sprite is ever needed.

Code: ags

DynamicSprite *sprite[360];
int Angle = 0;

function CreateSpriteRotationIndex()
{
   sprite[0] = DynamicSprite.CreateFromExistingSprite(StartingSprite);

   int counter = 1;
   while(counter <= 359)
   {
      sprite[counter] = DynamicSprite.CreateFromExistingSprite(StartingSprite);
      sprite[counter].Rotate(counter); 
      counter++;
   }
}

//before the sprite is to be used, create and save all possible variations.
function game_start()
{
  CreateSpriteRotationIndex();
}

//then, in the game loop
function repeatedly_execute()
{
  //lets just say that object 7 is being used to display the rotating sprite
  if(Angle == 359) Angle = 0;
  object[7].Graphic = sprite[Angle].Graphic;
  Angle++;
}


This is just one example and you could potentially do this with any DynamicSprite modification, not just rotating  ;D

cheers

deee

#2
Thanks very much. This seems to be a great method to improve the performance at runtime and I WILL use it for some of my script parts :)
However, in this case, the on-the-fly-creation of sprites does not seem to be the problem. Just like i wrote, the framerate seemed to be better when rawdrawing a lot.
By now, i have found out, that is has nothing to do with the rawdrawing and i am still not sure what is really is, that makes my FPS go up when certain events occur.

Differences:

Direct Draw 5:   ~38 FPS when running around, ~40 FPS when detecting the range between the player and the mouse (for spellcasting) and showing the maximum range as a circle around the player (by rawdrawing a a sprite at scaled size, dependant on the actual player scaling)

Direct 3D 9:   ~27(!) FPS when running around, ~40 FPS when detecting the range between the player and the mouse

I guess, in the case of rawdrawing resized sprites, your method makes no sense, pencil, because we need no modified sprite, as the drawimage-function allows the user to set the width and height.

best wishes

*Update: activating/deactivating of smooth scaled sprites and vertical sync has no effect on the FPS when running the game in Direct 3D
**Update: Finally found the problem. There was a function in rep_exe, creating a backup of the background-drawingsurface every game cycle (so the old drawn range sprite could be removed when updating).
This one really ate my frames when running it in Direct3D mode.
Solved it by adding a bg_restored flag that is being set to true after the function in rep_exe is called once, and setting it back to false when the background is being drawn on again. :)

Thanks again for the help


SMF spam blocked by CleanTalk