Author Topic: Graphics in C++  (Read 23759 times)

0 Members and 1 Guest are viewing this topic.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #20 on: January 17, 2007 »
I think GDI's SetDIBitsToDevice is at least as quick as FB memcpying into a DirectX surface.  I'd have to try it to be sure though.  Never looked at GDI+ before.  How easy is it to move a 32bit window sized memory buffer into a window and have it displayed.

->Fryer.  Shame you're not using Visual Studio Express.  Now you could turn on SSE or SSE2 and get another 2-4x speed up :P  Which version of devc++ is it (which is what I meant to ask last time, doh!)

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #21 on: January 19, 2007 »
I'm using VC++ express now but it's slower for this than devc and for some reason much slower in release mode and I've tried with SSE/SSE2 on.
Anyway, I've also compared with using a bit of asm for the scanline loops which is a massive improvement but could there be any way to get the compiler to compete with this? I'm not wanting to get into fixed point with this btw.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #22 on: January 19, 2007 »
How are you measuring the performance?

Jim
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #23 on: January 19, 2007 »
I've stuck it in vtune.  The piece the optimizer is having trouble with is this, especially the pixel munging.  Your assembler is much faster but it shouldn't be.  Otherwise, the optimizer is beating the other chunk of assembler easily.
Code: [Select]
"" "367" "                 d=float(x_start)-xx0;" "" ""
"" "368" "                 red=rr0+dred*d;" "" ""
"" "369" "                 gre=gg0+dgre*d;" "" ""
"" "370" "                 blu=bb0+dblu*d;" "" ""
"" "371" "                 while (pixel_address<=last_address){" "" ""
"" "372" "                     *pixel_address=((int)red<<16)|((int)gre<<8)|(int)blu;" "" ""
"" "373" "                     red+=dred;" "" ""
"" "374" "                     gre+=dgre;" "" ""
"" "375" "                     blu+=dblu;" "" ""
"" "376" "                     pixel_address+=1;" "" ""
"" "377" "                 }" "" ""

I get about 150ms for 1000 tris with assembler, and 450ms without, Release or Debug doesn't make any difference.
I'm timing it like this

Code: [Select]
unsigned long long thetime(void)
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return li.QuadPart;
}

unsigned long long freq;

void inittime(void)
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
freq = li.QuadPart;
}

void do_graphics_stuff(...)
{
...
char tmp[256];
unsigned long long t = thetime();
...thing to time
sprintf(tmp, "%I64ums\n", ((thetime()-t)*1000)/freq);
OutputDebugString(tmp);
}


You need to call inittime() somewhere in WinMain first.  I'm not timing the flip, just the triangles.
OutputDebugString() writes its output into the debugger output window in VS Express.

Jim
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #24 on: January 19, 2007 »
Almost certainly to do with float->int rounding for red,gre,blu, which isn't in the asm version, and is inside this tight loop.  Need to look at that.  I know you don't want to, but I'd seriously consider fixed point for the colours, because of this.  Keep it in float and see what you can do.

Jim
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Graphics in C++
« Reply #25 on: January 21, 2007 »
If you want I have a C routine that does float to int using asm. I have one for cl somewhere and I have a macro for gcc somehwre too. Let me know...
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #26 on: January 21, 2007 »
Here's what I've done.  I've got this rounding routine
Code: [Select]
static inline unsigned int myfrnd(float f)
{
static const double magic = 6755399441055744.0;
double d;
d = f + magic;
return *(unsigned int *)&d;
}

#define float_to_int(in) myfrnd(in)
And I've changed the pixel line to read
Code: [Select]
*pixel_address=(float_to_int(red)<<16)|(float_to_int(gre)<<8)|float_to_int(blu);
That's just as quick as the asm version.

The magic constant is 2^51+2^52.  Adding that to a double makes the lower 32bits of the mantissa of the double equal to the integer part of the fp number.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #27 on: January 22, 2007 »
Cool, thanks Jim. I was just looking into doing it that way but it wasn't quite as neat as that.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Graphics in C++
« Reply #28 on: January 22, 2007 »
Sadly, that trick doesn't work with SSE2 enabled, so here's how to do it using SSE2 intrinsic functions
Code: [Select]
#include <intrin.h>
static inline unsigned int myfrnd(float f)
{
return _mm_cvt_ss2si(_mm_load_ss(&f));
}
mm_load_ss loads a float into an SSE register, and mm_cvt_ss2si converts the single precision float to a 32bit int.
I had to comment out 2 lines in the intrin.h that conflict with winnt.h (_interlockedbittestandset and _interlockedbittestandreset) to get it to work.  The great thing is that these macros work well with the optimiser, meaning this version is about 25% faster than the asm.

You can use the _M_IX86_FP to detect what mode it's building in
Code: [Select]
#if _M_IX86_FP == 0
//fpu used
#elif _M_IX86_FP == 1
//sse used
#elif _M_IX86_FP == 2
//sse2 used
#else
#error unknown fpu architecture
#endif

That way you can have different builds for different platforms.

Jim

Actually, this works in SSE mode too.  Both the instructions it generates are SSE not SSE2.
« Last Edit: January 22, 2007 by Jim »
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Graphics in C++
« Reply #29 on: February 09, 2007 »
Here's what I've done.  I've got this rounding routine
Code: [Select]
static inline unsigned int myfrnd(float f)
{
static const double magic = 6755399441055744.0;
double d;
d = f + magic;
return *(unsigned int *)&d;
}

#define float_to_int(in) myfrnd(in)
And I've changed the pixel line to read
Code: [Select]
*pixel_address=(float_to_int(red)<<16)|(float_to_int(gre)<<8)|float_to_int(blu);
That's just as quick as the asm version.

The magic constant is 2^51+2^52.  Adding that to a double makes the lower 32bits of the mantissa of the double equal to the integer part of the fp number.

Jim



Karma++++++++
nothing else to say, except that goes on my list for best post of the year.
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Graphics in C++
« Reply #30 on: February 09, 2007 »
Jim, you are awesome.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Graphics in C++
« Reply #31 on: February 09, 2007 »
Jim, you are awesome.
Indeed  8)
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #32 on: March 15, 2007 »
Example of what I've got so far with a couple of 2d drawing functions, this works in both DevC and VC but there is some asm (sorry Jim) that can be used if it's in VC.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Graphics in C++
« Reply #33 on: March 15, 2007 »
Mmm. wouldn't compile in dev..

Undefined reference to setDIbitstodevice @48..

I'm thinking that it can't initialise the direct x screen.. I need to install this. Thanks for posting though! I'll look forward to seeing it when I have my compiler set up!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #34 on: March 15, 2007 »
It's not direct x, did you create it as a windows application?

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Graphics in C++
« Reply #35 on: March 15, 2007 »
lol, no I will try that.
I created it as an empty project! Sorry.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Graphics in C++
« Reply #36 on: March 15, 2007 »
Mmm. Created a windows app, it's over my head at the moment, I'll have to come back to this when I know what I am doing as I don't even know where to insert the code :P

I'm sure it looks great  :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #37 on: March 15, 2007 »
delete all the code from the project and paste mine in. It doesn't really look great though.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Graphics in C++
« Reply #38 on: March 15, 2007 »
Thanks :)

Looks a lot better than my hello worlds!!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Graphics in C++
« Reply #39 on: March 15, 2007 »
There's a lot of that sort of thing I should look into, doubt i could manage hello world without looking it up.