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

0 Members and 1 Guest are viewing this topic.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Graphics in C++
« on: January 13, 2007 »


Right, I've been wanting to give C++ a go for a while but the thing I've been having problems with really is setting up the graphics and windows side of things. Initially I'm wanting to do some pixel stuff without hardware so anyone got any ideas about the best way to go about setting up something that would work like ptc?

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5098
  • Karma: 380
    • View Profile
Re: Graphics in C++
« Reply #1 on: January 13, 2007 »
There's this thread on the old yabasic forum, which is still up to date.  I think the code you're looking for is near the end where I switch away from using Windows' SetPixel and write to a buffer.
http://p205.ezboard.com/fyabasicprogrammingfrm20.showMessageRange?topicID=14.topic

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #2 on: January 13, 2007 »
Nice one Jim, that's going back a bit.

Offline rdc

  • Pentium
  • *****
  • Posts: 1480
  • Karma: 138
    • View Profile
    • Clark Productions
Re: Graphics in C++
« Reply #3 on: January 13, 2007 »
There is also PixelToaster if your looking for a PTC-type of thing. I forget who mentioned at the moment, but there is an example program here somewhere using it.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #4 on: January 13, 2007 »
Well, I've been messing around with the stuff Jim linked to and I'm getting along with it a lot better this time. Is it ok to do stuff like this:

Code: [Select]
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>


typedef struct
{
        int wwidth,height,bpp;
        unsigned int* argb;
}image_buffer;

typedef struct
{
        HWND window;
        image_buffer* buffer;
}window_struct;


image_buffer* create_image_buffer(int wwidth, int height)
{
              image_buffer* buffer=(image_buffer*)malloc(sizeof (image_buffer));
              buffer->wwidth=wwidth;
              buffer->height=height;
              buffer->argb=(unsigned int*)malloc(sizeof(unsigned int)*wwidth*height);
              buffer->bpp=32;
              return buffer;
}

void flip(window_struct* window)
{
     BITMAPINFO bmi;
     HDC hdc;
     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
     bmi.bmiHeader.biWidth = window->buffer->wwidth;
     bmi.bmiHeader.biHeight = -window->buffer->height;
     bmi.bmiHeader.biPlanes = 1;
     bmi.bmiHeader.biBitCount = window->buffer->bpp;
     bmi.bmiHeader.biCompression = BI_RGB;
     bmi.bmiHeader.biSizeImage = 0;
     bmi.bmiHeader.biXPelsPerMeter = 75;
     bmi.bmiHeader.biYPelsPerMeter = 75;
     bmi.bmiHeader.biClrUsed = 0;
     bmi.bmiHeader.biClrImportant = 0;
     hdc = GetDC(window->window);
     SetDIBitsToDevice(hdc, 0,0, window->buffer->wwidth,window->buffer->height, 0,0, 0,window->buffer->height, window->buffer->argb, &bmi,  DIB_RGB_COLORS);
     ReleaseDC(window->window, hdc);
}

void setpixel(image_buffer* buffer,int x, int y, unsigned int colour)
{
     if (x < 0 || x >= buffer->wwidth) return;
     if (y < 0 || y >= buffer->height) return;
     *(buffer->argb+x+buffer->wwidth*y)=colour;
}

unsigned int getpixel(image_buffer* buffer,int x, int y)
{
     if (x < 0 || x >= buffer->wwidth) return 0;
     if (y < 0 || y >= buffer->height) return 0;
     return *(buffer->argb+x+buffer->wwidth*y);
}

void clear_buffer(image_buffer* buffer,unsigned int colour)
{
     memset(buffer->argb, colour, buffer->wwidth*buffer->height*sizeof(int));
}

void shutdown(window_struct* window)
{
     free(window->buffer->argb);
     free(window->buffer);
     free(window);
}


void init_fireworks(void);
void do_fireworks(image_buffer*);
void draw_fireworks(image_buffer*);
void do_graphics_stuff(window_struct* window)
{
     clear_buffer(window->buffer,0);
     do_fireworks(window->buffer);
     InvalidateRect(window->window, NULL, FALSE);
     UpdateWindow(window->window);
     flip(window);
     Sleep(16);
}


int quit = FALSE;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch (uMsg)
        {
                case WM_PAINT:
                        {
                        PAINTSTRUCT paint={0};
                        paint.hdc = (HDC)wParam;
                        GetUpdateRect(hwnd, &paint.rcPaint,TRUE);
                        BeginPaint(hwnd, &paint);
                        EndPaint(hwnd, &paint);
                        break;
                        }
                case WM_DESTROY:
                        quit = TRUE;
                        PostQuitMessage(0);
                        break;
                default:
                        return DefWindowProc(hwnd, uMsg, wParam, lParam);
        }
return 0;
}

window_struct* setup_window(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow,
                     int wwidth,
                     int height,
                     TCHAR title[])
{
        WNDCLASSEX clas;
        MSG msg;

        TCHAR graphics_class[] = "SM3d";
       
        clas.cbSize = sizeof(WNDCLASSEX);
        clas.style = CS_HREDRAW | CS_VREDRAW;
        clas.lpfnWndProc = WindowProc;
        clas.cbClsExtra = 0;
        clas.cbWndExtra = 0;
        clas.hInstance = hInstance;
        clas.hIcon = NULL;
        clas.hCursor = NULL;
        clas.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        clas.lpszMenuName = NULL;
        clas.lpszClassName = graphics_class;
        clas.hIconSm = 0;
        RegisterClassEx(&clas);

        window_struct* new_window=(window_struct*)malloc(sizeof(window_struct));
        {
        RECT rect={0,0,wwidth,height};
        int style = WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE;
        AdjustWindowRectEx(&rect, style, FALSE, WS_EX_TOPMOST);
        new_window->window = CreateWindowEx(0, graphics_class, title, style, CW_USEDEFAULT, CW_USEDEFAULT, rect.right-rect.left, rect.bottom-rect.top, NULL, NULL, hInstance, 0);
        }

        ShowWindow(new_window->window, nCmdShow);
        UpdateWindow(new_window->window);
        new_window->buffer=create_image_buffer(wwidth,height);
        return new_window;
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
        MSG msg;

        window_struct* window=setup_window(hInstance,hPrevInstance,lpCmdLine,nCmdShow,640,480,"Stonemonkey");
       
        init_fireworks();
       
        while (!quit)
        {
                while (PeekMessage(&msg, window->window, 0, 0, PM_NOREMOVE))
                {
                        if (!GetMessage(&msg, window->window, 0, 0))
                                break;
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }

                do_graphics_stuff(window);
               
        }
        shutdown(window);

        return 0;
}





typedef struct
{
        float x,y,z;
} VECTOR;

typedef struct
{
        unsigned int flags;
        VECTOR posn;
        VECTOR velocity;
        float spin;
        float spin_rate;
        float life_span;
        int age;
} COIN;

enum
{
        COIN_ALIVE_F=1,
        COIN_PARENT_F=2,
};


#define MAX_COINS 5000
#define MAX_GEN 500
COIN fireworks[MAX_COINS];

#define BIG_G -9.81f

int my_rand()
{
        return rand()+(rand()<<15);
}

float rand_angle()
{
        return (float)(my_rand()%360);
}

float rand_vel()
{
        return (float)((my_rand()%201)-100);
}

float rand_yvel()
{
        return (float)(my_rand()%750)-BIG_G;
}


float rand_rate()
{
        return (float)((my_rand()%45)-23);
}

float rand_lifespan()
{
        return (float)((my_rand()%3)+1);
}

void create_a_coin(COIN *coin, int always_alive)
{
        if (always_alive)
                coin->flags = COIN_ALIVE_F;
        else
                coin->flags = my_rand()&COIN_ALIVE_F;

        if (coin->flags & COIN_ALIVE_F)
        {
                coin->posn.x = 320.0f;
                coin->posn.y = 0.0f;
                coin->posn.z = 0.0f;
                coin->spin = rand_angle();
                coin->spin_rate = rand_rate();
                coin->velocity.x = rand_vel();
                coin->velocity.z = rand_vel();
                coin->velocity.y = rand_yvel();
                coin->life_span = rand_lifespan();
                coin->age = 0;
                if ((my_rand()%10)==0)
                        coin->flags |= COIN_PARENT_F;
        }
return;
}

void create_a_system(VECTOR *pos, int age)
{
        int amount = 1+(my_rand()%MAX_GEN);
        COIN *coin = fireworks;
        int x;

        age++;
        for (x = 0; x < MAX_COINS && amount; x++, coin++)
        {
                if (!(coin->flags & COIN_ALIVE_F))
                {
                        create_a_coin(coin, TRUE);
                        coin->posn.x = pos->x;
                        coin->posn.y = pos->y;
                        coin->posn.z = pos->z;
                        coin->velocity.x = rand_vel();
                        coin->velocity.z = rand_vel();
                        coin->velocity.y = rand_yvel()/(float)(age+1);
                        coin->life_span/=(float)(age+1);
                        coin->age = age;
                        amount--;
                }
        }
}

void init_fireworks()
{
        int x;
        COIN *coin = fireworks;

        srand(time(NULL));

        for (x = 0; x < MAX_GEN; x++, coin++)
        {
                create_a_coin(coin, FALSE);
        }
        for (x = MAX_GEN, coin = fireworks+MAX_GEN; x < MAX_COINS; x++, coin++)
                coin->flags = 0;

return;
}

void process_fireworks(float elapsed_time)
{
        int x;
        COIN *coin = fireworks;

        elapsed_time /= 1000.0f;

        for (x = 0; x < MAX_COINS; x++, coin++)
        {
                if (coin->flags & COIN_ALIVE_F)
                {
                        coin->spin += coin->spin_rate;
                        coin->posn.x += coin->velocity.x * elapsed_time;
                        coin->posn.y += coin->velocity.y * elapsed_time;
                        coin->posn.z += coin->velocity.z * elapsed_time;
                        coin->velocity.y += BIG_G;
                        coin->life_span -= elapsed_time;
                        if (coin->life_span < 0.0f)
                        {
                                if ((coin->flags & COIN_PARENT_F) && coin->age < 5)
                                {
                                        create_a_system(&coin->posn, coin->age);
                                        coin->flags &= ~COIN_ALIVE_F;
                                }
                                else
                                {
                                        coin->flags &= ~COIN_ALIVE_F;
                                        //create_a_coin(coin, TRUE);
                                }
                        }
                        if (coin->posn.y < 0.0f)
                                coin->flags &= ~COIN_ALIVE_F;
                }
        }

return;
}

int get_blit_size(float z)
{

        z += 320.0;
        return (int)(64.0f*z/640.0f);
}

void draw_fireworks(image_buffer* buffer)
{
     
        int x;
        COIN *coin = fireworks;
 
        int population = 0;

        for (x = 0; x < MAX_COINS; x++, coin++)
        {
                if (coin->flags & COIN_ALIVE_F)
                {
                        setpixel(buffer,(int)coin->posn.x, 400-(int)coin->posn.y+1, 0x00ff00);
                        population++;                                                                                                   
                }
        }
       
        if (!population) init_fireworks();

return;
}

void do_fireworks(image_buffer* buffer)
{
        process_fireworks(1000.0f/60.0f);
        draw_fireworks(buffer);
}

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5098
  • Karma: 380
    • View Profile
Re: Graphics in C++
« Reply #5 on: January 13, 2007 »
Looks like it...as long as that PeekMessage loop is called every second or so it'll be fine.  You can basically do whatever you want.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #6 on: January 14, 2007 »
I've just taken my freebasic triangle code and put it in this, the code is virtually identical but it runs a fair bit slower!

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1304
  • Karma: 88
    • View Profile
Re: Graphics in C++
« Reply #7 on: January 14, 2007 »
yeah i had the same trouble gdi wasnt that fast with my triangle renders but i think it has somehing to do with vsyncing so mabey a bit of delta timing will sort things out?
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1304
  • Karma: 88
    • View Profile
Re: Graphics in C++
« Reply #8 on: January 14, 2007 »
is the sleep 16 necessary i removed it in my demo and it seemed to still work fine except the cpu usage went to 100% all the time but the code executed faster.

btw excellent code post above its a great read!
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #9 on: January 14, 2007 »
Nah, the sleep's just to stop it hogging the cpu, i've set sleep to 1 in both fb and c++ and still fb looks much faster.

Here's the c++ tri function:
Code: [Select]
void fill_gtriangle(image_buffer* buffer, float x0, float y0, unsigned int argb0,
                                          float x1, float y1, unsigned int argb1,
                                          float x2, float y2, unsigned int argb2)
{
 unsigned int *pixel_address, *last_address, *address=buffer->argb;
 int wwidth=buffer->wwidth, height=buffer->height, p0, p1, p2, y_start, y_end,x_start, x_end;
 float x[3], y[3], r[3], g[3], b[3], xx0, dx0, xx1, dx1, d;
 float rr0, dr0, gg0, dg0, bb0, db0, rr1, dr1, gg1, dg1, bb1, db1;
 float red, dred, gre, dgre, blu, dblu;
 
 x[0]=x0;
 y[0]=y0;
 r[0]=float((argb0 >> 16)&0xff);
 g[0]=float((argb0 >> 8 )&0xff);
 b[0]=float(argb0 &0xff);
 x[1]=x1;
 y[1]=y1;
 r[1]=float((argb1 >> 16)&0xff);
 g[1]=float((argb1 >> 8 )&0xff);
 b[1]=float(argb1 &0xff);
 x[2]=x2;
 y[2]=y2;
 r[2]=float((argb2 >> 16)&0xff);
 g[2]=float((argb2 >> 8 )&0xff);
 b[2]=float(argb2 &0xff);
 
 p0=0; p2=2;
 if (y1<y0) p0=1;
 if (y2<y[p0]) p0=2;
 if (y1>y2) p2=1;
 if (y0>y[p2]) p2=0;
 p1=3-p0-p2;
 
 y_start=(int)y[p0]+1;
 y_end=(int)y[p1];
 if (y_start<0) y_start=0;
 if (y_end>=height) y_end=height-1;
 
 if (y_start<=y_end) {
                    d=1.0f/(y[p1]-y[p0]);
                    dx0=(x[p1]-x[p0])*d;
                    dr0=(r[p1]-r[p0])*d;
                    dg0=(g[p1]-g[p0])*d;
                    db0=(b[p1]-b[p0])*d;
                    d=1.0f/(y[p2]-y[p0]);
                    dx1=(x[p2]-x[p0])*d;
                    dr1=(r[p2]-r[p0])*d;
                    dg1=(g[p2]-g[p0])*d;
                    db1=(b[p2]-b[p0])*d;
                    if (dx0>dx1) {
                                d=dx0;
                                dx0=dx1;
                                dx1=d;
                                d=dr0;
                                dr0=dr1;
                                dr1=d;
                                d=dg0;
                                dg0=dg1;
                                dg1=d;
                                d=db0;
                                db0=db1;
                                db1=d;
                    }
                    d=float(y_start)-y[p0];
                    xx0=x[p0]+dx0*d;
                    rr0=r[p0]+dr0*d;
                    gg0=g[p0]+dg0*d;
                    bb0=b[p0]+db0*d;
                    xx1=x[p0]+dx1*d;
                    d=1.0f/(dx1-dx0);
                    dred=(dr1-dr0)*d;
                    dgre=(dg1-dg0)*d;
                    dblu=(db1-db0)*d;
                    y_start*=wwidth;
                    y_end*=wwidth;
                    while (y_start<=y_end){
                                  x_start=(int)xx0+1;
                                  x_end=(int)xx1;
                                  if (x_start<0)  x_start=0;
                                  if (x_end>=wwidth)  x_end=wwidth-1;
                                  if (x_start<=x_end) {
                                                     pixel_address=address+(x_start+y_start);
                                                     last_address=address+(x_end+y_start);
                                                     d=float(x_start)-xx0;
                                                     red=rr0+dred*d;
                                                     gre=gg0+dgre*d;
                                                     blu=bb0+dblu*d;
                                                     while (pixel_address<=last_address){
                                                           *pixel_address=((int)red<<16)|((int)gre<<8)|(int)blu;
                                                           red+=dred;
                                                           gre+=dgre;
                                                           blu+=dblu;
                                                           pixel_address+=1;
                                                     }
                                  }
                                  xx0+=dx0;
                                  rr0+=dr0;
                                  gg0+=dg0;
                                  bb0+=db0;
                                  xx1+=dx1;
                                  y_start+=wwidth;
                    }
 }
 
 
 y_start=(int)y[p1]+1;
 y_end=(int)y[p2];
 if (y_start<0) y_start=0;
 if (y_end>=height) y_end=height-1;
 
 if (y_start<=y_end) {
                    d=1.0f/(y[p1]-y[p2]);
                    dx0=(x[p1]-x[p2])*d;
                    dr0=(r[p1]-r[p2])*d;
                    dg0=(g[p1]-g[p2])*d;
                    db0=(b[p1]-b[p2])*d;
                    d=1.0f/(y[p0]-y[p2]);
                    dx1=(x[p0]-x[p2])*d;
                    dr1=(r[p0]-r[p2])*d;
                    dg1=(g[p0]-g[p2])*d;
                    db1=(b[p0]-b[p2])*d;
                    if (dx0<dx1) {
                                d=dx0;
                                dx0=dx1;
                                dx1=d;
                                d=dr0;
                                dr0=dr1;
                                dr1=d;
                                d=dg0;
                                dg0=dg1;
                                dg1=d;
                                d=db0;
                                db0=db1;
                                db1=d;
                    }
                    d=float(y_start)-y[p2];
                    xx0=x[p2]+dx0*d;
                    rr0=r[p2]+dr0*d;
                    gg0=g[p2]+dg0*d;
                    bb0=b[p2]+db0*d;
                    xx1=x[p2]+dx1*d;
                    d=1.0f/(dx1-dx0);
                    dred=(dr1-dr0)*d;
                    dgre=(dg1-dg0)*d;
                    dblu=(db1-db0)*d;
                    y_start*=wwidth;
                    y_end*=wwidth;
                    while (y_start<=y_end){
                                  x_start=(int)xx0+1;
                                  x_end=(int)xx1;
                                  if (x_start<0) x_start=0;
                                  if (x_end>=wwidth) x_end=wwidth-1;
                                  if (x_start<=x_end) {
                                                     pixel_address=address+(x_start+y_start);
                                                     last_address=address+(x_end+y_start);
                                                     d=float(x_start)-xx0;
                                                     red=rr0+dred*d;
                                                     gre=gg0+dgre*d;
                                                     blu=bb0+dblu*d;
                                                     while (pixel_address<=last_address){
                                                           *pixel_address=((int)red<<16)|((int)gre<<8)|(int)blu;
                                                           red+=dred;
                                                           gre+=dgre;
                                                           blu+=dblu;
                                                           pixel_address+=1;
                                                     }
                                  }
                                  xx0+=dx0;
                                  rr0+=dr0;
                                  gg0+=dg0;
                                  bb0+=db0;
                                  xx1+=dx1;
                                  y_start+=wwidth;
                    }
 }
}                                   

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #10 on: January 14, 2007 »
It's the float to int conversions that are doing it, when writing a constant int value to each pixel the c++ version is now much faster.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1304
  • Karma: 88
    • View Profile
Re: Graphics in C++
« Reply #11 on: January 14, 2007 »
cool! i never knew floats to ints were slow thats probably why my tri routines were slow as there was quite a lot of conversions going on.

so is it just floats to ints thats slow or also ints to floats?

would there be any chance of having a look at the tri routine now youve got the problem fixed?
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #12 on: January 14, 2007 »
Sorry nino, it's not really fixed. I just have it filling with solid colour atm`which can be done by changing the 2 pixel filling lines to:

*pixel_address=argb0;

but it does show how much the conversions are slowing it down.

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Graphics in C++
« Reply #13 on: January 14, 2007 »
so is it just floats to ints thats slow or also ints to floats?

Nino,

Its just float to int. You do not need to worry about int to float. Its not just speed its *enormous* in size (60 bytes?). This is because of the very strict IEEE rules for floats.

One solution I found was to use lrintf which whilst not ideal (its still 20 bytes) is much faster. Another solution is to look into using the asm instruction fist and variants (float to int and store I think - ask Rbraz).

When I tried to solve this, I found this page quite useful:
http://mega-nerd.com/FPcast/

Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #14 on: January 14, 2007 »
Thanks taj, I just tried the asm method from that and it's going pretty well. There was another method Jim mentioned before using some magic number.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5098
  • Karma: 380
    • View Profile
Re: Graphics in C++
« Reply #15 on: January 15, 2007 »
It's the C rounding rules where instead of the default fpu mode of round to nearest C demands round towards zero.  So it has to switch the fpu status every time a conversion happens.  Best thing to do is not do that.  Either use fixed point or all int or all float.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #16 on: January 15, 2007 »
Well here's what I've got so far:

« Last Edit: January 15, 2007 by Stonemonkey »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5098
  • Karma: 380
    • View Profile
Re: Graphics in C++
« Reply #17 on: January 16, 2007 »
Is it still slow?  You got a couple of things that might be worth fixing.
In a lot of places you do something like
Code: [Select]
float x;
int ix;
ix=5;
x=float(ix);
That's unusual.  I've never seen float used as a macro or function before.  It's supposed to look like this
Code: [Select]
float x;
int ix;
ix=5;
x=(float)ix;
Since I don't know what the macro/function does, that might or might not make a difference.

In another place you have
Code: [Select]
float x;
x=1.0f
x=x+0.4999
That's a problem because 0.4999 is a double, not a float (64bits instead of 32) so x will get converted to a double, 0.4999 will be added, and then it'll get converted back to a float.  So change it to be
Code: [Select]
float x;
x=1.0f
x=x+0.4999f
That will make a difference.  I think you got it right in most places.

You can remove the Sleep() if you don't want to yield any CPU to the rest of the PC, but that's very unfriendly.  Try Sleep(0) as a minimum.  I set it at 16 because that's ~60Hz (1000/16) and since the drawing I was doing took well under 1ms it was the thing to do.

Are you using djgpp?   Which version?

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1215
  • Karma: 92
    • View Profile
Re: Graphics in C++
« Reply #18 on: January 16, 2007 »
Thanks Jim, It's running much better now (maybe around twice as fast as fb now) that i've changed the float-int conversions and i already noticed the missing f at the ends of some numbers. I'm using devc++ and it's not complained about the x=float(ix) or anyting but i've changed it now.

Offline rdc

  • Pentium
  • *****
  • Posts: 1480
  • Karma: 138
    • View Profile
    • Clark Productions
Re: Graphics in C++
« Reply #19 on: January 17, 2007 »
FB will be a bit than faster GDI since it uses DirectX if installed. If DX is not installed it falls back to GDI. You might want to look at GDI+, since it supposed to be optimized for drawing routines. I have used it in xblite and it seems to work quite well, plus it has a number of extra functions that GDI doesn't have.