View Full Version: i DoubleBuffer...&& only 2 colours appeared

C++ Learning Community > win32 api C++ programming > i DoubleBuffer...&& only 2 colours appeared


Title: i DoubleBuffer...&& only 2 colours appeared
Description: {cancel} Problem Solved


aab - January 21, 2005 09:49 PM (GMT)
When i try to use my (first) Double Buffer Class, it works fine with the exception that only 0x00FFFFFF and 0x000000 are drawn to the window.

When Drawing a BitMap it only draws pixels of the monochrome colours.
When using Rectangle(), or SetPixel..(i think..) it rounds the pixel colour to the nearest of the two....


so somehow my buffers formats are...Monochrome.... eherm.
CODE






#include <windows.h>



#define DOUBLEBUFFER DBUFF //just to write a clearer name for the member function

class DBUFF{

public:
 
 DBUFF();
 ~DBUFF();

 //used to initialise Double Bufferring
 bool SetBackBuffer(HWND hwnd);

 //used to close Double Buffering
 bool FreeBackBuffer();

 bool GetState();

 BOOL Flip();

 
 bool ClsBackBuffer(const COLORREF);
 
 HDC GetBackBuffer();

 HDC GetFrontBuffer();

 HBITMAP GetBackImage();

 BOOL DrawHbitmap(HBITMAP,int,int,int,int);

 #define BUFFER backhdc
 HDC backhdc; //the BACKBUFFER of course

private:

 RECT Rectb;  //Rect for the window
 HDC fronthdc;  //the windows hdc
 HWND Winb;  //the window
 HBITMAP backsPixels; //the backbuffer pixels
 
 HBITMAP ReservedPixels; //the pixels already in the created HDC backhdc

 bool on;
 
 
};




#define ZeroRect(rectangle_rect) (rectangle_rect).left=0; (rectangle_rect).right=0; (rectangle_rect).top=0; (rectangle_rect).bottom=0

DBUFF::DOUBLEBUFFER(){

ZeroRect(this->Rectb);
this->fronthdc=NULL;
this->backhdc=NULL;
this->Winb=NULL;
this->backsPixels=NULL;

this->ReservedPixels=NULL;



this->on=false;

}

DBUFF::~DOUBLEBUFFER(){

//Remove access to the windows hdc
ReleaseDC(this->Winb,this->fronthdc);

//Destroy after removing access to.. the backimage

SelectObject(this->backhdc,this->ReservedPixels);
DeleteObject(this->backsPixels);

//Destroy the Back HDC

DeleteDC(this->backhdc);


}

bool DOUBLEBUFFER::SetBackBuffer(HWND hwnd){
//Check hwnd
if(!hwnd){return false;}

//Equate Window
this->Winb=hwnd;



//Get the Windows Rectangle
if(!GetClientRect(hwnd,&this->Rectb)){return false;}

//Get the Windows HDC
this->fronthdc=GetDC(hwnd); if(!this->fronthdc){return false;}


//Create the HDC compatible with the front hdc
this->backhdc=CreateCompatibleDC(this->fronthdc); if(!this->backhdc){return false;}

//Create the Image that that HDC will be the selector of..
this->backsPixels=CreateCompatibleBitmap(this->backhdc,this->Rectb.right,this->Rectb.bottom); if(!this->backsPixels){return false;}

//Allocate them to each other, and save off into the Reserve
this->ReservedPixels=(HBITMAP)SelectObject(this->backhdc,this->backsPixels); if(!this->ReservedPixels){return false;}

this->on=true;
return true;
}


bool DOUBLEBUFFER::FreeBackBuffer(){

this->on=false;

//Remove access to the windows hdc
ReleaseDC(this->Winb,this->fronthdc);

//Destroy after removing access to.. the backimage

SelectObject(this->backhdc,this->ReservedPixels);
DeleteObject(this->backsPixels);

//Destroy the Back HDC

DeleteDC(this->backhdc);


return true;
}

#define DB_ON 1
#define DB_OFF 0
bool DOUBLEBUFFER::GetState(){
return this->on;
}


BOOL DBUFF::Flip(){
return BitBlt(this->fronthdc,this->Rectb.left,this->Rectb.top,this->Rectb.right,this->Rectb.bottom,this->backhdc,0,0,SRCCOPY);
}






bool DBUFF::ClsBackBuffer(const COLORREF colorref){
 
HBRUSH hbr=CreateSolidBrush(colorref);

FillRect(this->backhdc,&this->Rectb,hbr);

DeleteObject(hbr);

return true;
}



HDC DBUFF::GetBackBuffer(){
return this->backhdc;
}

HDC DBUFF::GetFrontBuffer(){
return this->fronthdc;
}

HBITMAP DBUFF::GetBackImage(){
return this->backsPixels;
}

BOOL DBUFF::DrawHbitmap(HBITMAP hbmp,int x,int y,int width,int height){

BOOL ReturnBOOL=false;

//Create an HDC to use for the HBITMAP
HDC BMPhdc=CreateCompatibleDC(this->backhdc);



//Select the image into it
HBITMAP oldBMP=(HBITMAP)SelectObject(BMPhdc,hbmp);

//Blit the HDC against the BackBuffer

ReturnBOOL=BitBlt(this->backhdc,x,y,width,height,BMPhdc,0,0,SRCCOPY);

SelectObject(BMPhdc,oldBMP);

//release the handle to the BMPS DC
ReleaseDC(this->Winb,BMPhdc);

return ReturnBOOL;
}




Please Help!

Im at the largest Chasm ive reached yet, while learning to program.
Time may be desired for many 'things' to sink in. but if the 'things' dont work....

:blink:

C-Man - January 22, 2005 09:56 AM (GMT)
strange... i don't realy have an explanation for it excep if you window DC is monochrome somehow

aab - January 23, 2005 03:43 PM (GMT)
Heres how i Create the window (Might Help...)
CODE

#define MYCLASSNAME "aabs_DB_test_window"
#define SCREEN_W 640
#define SCREEN_H 480

LRESULT CALLBACK WndProc(HWND,unsigned int,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){

HWND hwnd;
MSG msg;
DWORD dwWndStyle=WS_OVERLAPPEDWINDOW;
RECT rect={0,0,SCREEN_W,SCREEN_H};
bool inval=true; //this is set to true if the screen is to be redrawn
DBUFF dbuff;

WNDCLASSEX wndclass={0};

 wndclass.cbClsExtra  =NULL;
 wndclass.cbSize   =sizeof(wndclass);
 wndclass.cbWndExtra  =NULL;
 wndclass.hbrBackground =(HBRUSH)GetStockObject(BLACK_BRUSH);
 wndclass.hCursor  =LoadCursor(hInstance,IDC_ARROW);
 wndclass.hIcon   =LoadIcon(hInstance,IDI_WINLOGO);
 wndclass.hIconSm  =LoadIcon(hInstance,IDI_WINLOGO);
 wndclass.hInstance  =hInstance;
 wndclass.lpfnWndProc =WndProc;
 wndclass.lpszClassName =MYCLASSNAME;
 wndclass.lpszMenuName =NULL;
 wndclass.style   =CS_VREDRAW|CS_HREDRAW;

RegisterClassEx(&wndclass);

hwnd=CreateWindowEx(NULL,
  MYCLASSNAME,
  MYCLASSNAME,
  dwWndStyle,
  0,0,SCREEN_W,SCREEN_H,
  NULL,
  NULL,
  hInstance,
  NULL
 );

ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);


if(!dbuff.SetBackBuffer(hwnd)){
 MessageBox(hwnd,"SetBackBuffer Failed","Error!",MB_OK | MB_ICONERROR);
}


HBITMAP boxBMP;
boxBMP=(HBITMAP)LoadImage(hInstance,"hbitmap.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

int charX=SCREEN_W/2;
int charY=SCREEN_H/2;
int charSpeed=3;
int hcharW=20;
int hcharH=20;

while(!KeyHit(VK_ESCAPE)){

 

 if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE)){
 
  if(msg.message==WM_QUIT){break;}

  TranslateMessage(&msg);
  DispatchMessage(&msg);
 
 }else{


  if(KeyDown(VK_LEFT)){
   charX-=charSpeed; inval=true;
  }else if(KeyDown(VK_RIGHT)){
   charX+=charSpeed; inval=true;
  }
  if(KeyDown(VK_UP)){
   charY-=charSpeed; inval=true;
  }else if(KeyDown(VK_DOWN)){
   charY+=charSpeed; inval=true;
  }
 
  if(inval||true){

    dbuff.ClsBackBuffer(0);

    //previous test
    //Rectangle(dbuff.BUFFER,charX-hcharW,charY-hcharH,charX+hcharW,charY+hcharH);

    dbuff.DrawHbitmap(boxBMP,charX-64,charY-64,charX+64,charY+64);
   

    //appears white
    SetPixel(dbuff.BUFFER,charX-66,charY-66,0x00FF00FF);
   

    dbuff.Flip();

   inval=false;
  }

 }



}


DeleteObject(boxBMP);

dbuff.FreeBackBuffer();

UnregisterClass(MYCLASSNAME,hInstance);



return msg.wParam;
}

//Basic as it gets
LRESULT CALLBACK WndProc(HWND hwnd,unsigned int message,WPARAM wparam,LPARAM lparam){

static PAINTSTRUCT Paint;

switch(message){
case WM_PAINT:
 BeginPaint(hwnd,&Paint);
 EndPaint(hwnd,&Paint);
 return 0;
case WM_CLOSE:
case WM_DESTROY:
 PostQuitMessage(0);
 return 0;
}


return DefWindowProc(hwnd,message,wparam,lparam);
}

Edit: its definately the format of the Backbuffer: when i draw directly to the Windows HDC its in True Colour, but when i BitBlt the BackBuffer to the Front its only taking in Monchrome=> BitBlt paramater issue..or..a CompatibleHDC thats not set with the screens pallette.
I even tried changing my screen colour display modes, just in case.. no luck

aab - January 26, 2005 11:39 PM (GMT)
YAHOOOOO:: fixed it!

I left this for a day to learn how to use Fmod (isnt it easy?)
and looking at this, i decided to make the Created Compatible Bitmap Compatible with the FrontHDC,Not the BackHDC, even though it would be Selected Into thje Back HDC...and it works..

Now...Im incredibly happy!

Nintendofreak88 - January 27, 2005 12:04 AM (GMT)
Isn't it weird how those small things can make your program act so strange? :blink:

aab - January 27, 2005 12:59 AM (GMT)
Yeah...even more though: while messing about, i was blitting the background Magenta, only as it was Monochrome, a cross hatch pattern appeared, and so when i tested drawing directly to the front buffer (i used Magenta), only withought clearing, then the Magenta somehow fused into the pattern, to make a colour pattern as i moved the Square (drawn at the mouse) over the screen.
The hatch might have only been drawing eg: the white pixels on.. or the blacks...i dunno. and i probobly never will need to know..but its there if i need it. Eherm.




* Hosted for free by InvisionFree