Getting a window to change colors

Started by
5 comments, last by Barrow Boy 15 years, 9 months ago
I'm just beginning to learn DirectX and Windows programming from directxtutorial.com and I'm attempting one of the exercises which asks me to make a window's color fade from black to blue, then back to black again, etc. I can manage to get the color to fade from black to blue (by incrementing the blue value every 25 milliseconds), but I'm a bit lost on how to get the color to fade back to black again after that. Here's my code:
// include the basic windows header file and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>

// include the Direct3D Library file
#pragma comment( lib, "d3d9.lib" )

// global declarations
LPDIRECT3D9 d3d;	// the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;	// the pointer to the device class

// function prototypes
void initD3D( HWND hWnd );	// sets up and initializes Direct3D
void render_frame( DWORD r, DWORD g, DWORD b );	// renders a single frame
void cleanD3D( void );	// closes Direct3D and releases memory

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    // the handle for the window, filled by a function
    HWND hWnd;
    // this struct holds information for the window class
    WNDCLASSEX wc;

    // clear out the window class for use
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    // fill in the struct with the needed information
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = L"WindowClass1";

    // register the window class
    RegisterClassEx(&wc);

    // create the window and use the result as the handle
    hWnd = CreateWindowEx(NULL,
                          L"WindowClass1",    
                          L"Our First Direct3D Program",   
                          WS_OVERLAPPEDWINDOW,    
                          300, 200,    
                          640, 480,    
                          NULL,    
                          NULL,    
                          hInstance,    
                          NULL );    

    // display the window on the screen
    ShowWindow(hWnd, nCmdShow);

	// set up and initialize Direct3D
	initD3D( hWnd );

    // enter the main loop:

    // this struct holds Windows event messages
    MSG msg;

	DWORD a = 0, b = 0, c = 0;
	int one_or_two;

    // wait for the next message in the queue, store the result in 'msg'
    while( TRUE )
    {
        // find out the starting time of each loop
		DWORD starting_point = GetTickCount();
		
		// Check to see if any messages are waiting in the queue
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			// If the message is WM_QUIT, exit the while loop
			if( msg.message == WM_QUIT )
				break;
			
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}

		// ...
		// do neato incrementing stuff right here
		// ...

		// wait until 1/40th of a second has passed
		while( ( GetTickCount() - starting_point ) < 25 );
    }

	// clean up DirectX and COM
	cleanD3D();

    return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // sort through and find what code to run for the message given
    switch(message)
    {
        // this message is read when the window is closed
        case WM_DESTROY:
            {
                // close the application entirely
                PostQuitMessage(0);
                return 0;
            } break;
    }

    // Handle any messages the switch statement didn't
    return DefWindowProc (hWnd, message, wParam, lParam);
}

// this function initializes and prepares Direct3D for use
void initD3D( HWND hWnd )
{
	d3d = Direct3DCreate9( D3D_SDK_VERSION );	// create the direct3D interface

	D3DPRESENT_PARAMETERS d3dpp;	// create a struct to hold various device information

	ZeroMemory( &d3dpp, sizeof( d3dpp ) );	// clear out the struct foro use
	d3dpp.Windowed = TRUE;	// program windowed, not fullscreen
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;	// discard old frames
	d3dpp.hDeviceWindow = hWnd;	// set the window to be used by Direct3D

	// create a device class using this information and the info from the d3dpp struct
	d3d->CreateDevice( D3DADAPTER_DEFAULT,
					   D3DDEVTYPE_HAL,
					   hWnd,
					   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
					   &d3dpp,
					   &d3ddev );

	return;
}

// this is the function used to render a single frame
void render_frame( DWORD r, DWORD g, DWORD b )
{
	// clear the window to a deep blue
	d3ddev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( r, g, b ), 1.0f, 0 );

	d3ddev->BeginScene();	// begins the 3D scene

	// do 3D rendering on the back buffer here

	d3ddev->EndScene();		// ends the 3D scene

	d3ddev->Present( NULL, NULL, NULL, NULL );	// displays the created frame on the screen

	return;
}

// this is the function that cleans up Direct3D and COM
 void cleanD3D( void )
 {
	 d3ddev->Release();		// close and release the 3D device
	 d3d->Release();		// close and release Direct3D

	 return;
 }
The place I want to do the color changing is in the main loop, in the commented area. If someone could just point me in the right direction, that would be nice. Thanks.
Advertisement
You can create a variable that holds the state of the fade effect (are you fading in or out?), with that value you can then determine whether you want to decrease the blue value or increase it:

DWORD blue = 0; // The ammount of blue present in the clear colourbool fadingIn = false; // Are we fading into black or blue?// In your games loopif(fadingIn) // If we are fading into black{   blue -= 1; // Subtract a certain ammount from the blue colour}else // Otherwise, if we are fading to blue{   blue += 1; // Increase the ammount of blue present}// If we reach full black or blueif(blue >= 255 || blue <= 0){   fadingIn = !fadingIn; // then 'flip' the way we are fading}// Finally, clear the screen with the new colourrender_frame(0, 0, blue);


[Edited by - cNoob on July 27, 2008 7:49:36 PM]
Thanks! I got it to work out nicely.

(How do you get your code in a code block like you did in your post? I was just using [c0de][/c0de] tags.)
Quote:Original post by Barrow Boy
Thanks! I got it to work out nicely.

(How do you get your code in a code block like you did in your post? I was just using [c0de][/c0de] tags.)


The tags are [ source ][ /source ] without spaces :)
Okay, that'll be nice to know...

On a bit of a different note, I've been working on another window that is meant to change colors when you press the up and down arrow keys. I'm using a vector to store the colors, and when the up/down arrows are pressed it will iterate through the vector and show the next color. I've got it all set up, but when I run it, it gives me an error targeting my

#include <vector>


line. It says that 'no such file exists or something like that. I recently switched compilers; from Dev-C++ to Visual. Is there something I'm missing here, or why can't I include the vector header?
Erm.. You should be able to include <vector> in VS. Maybe you've deleted an include directory in the options or something went horribly wrong?
Ok, sorry, false alarm. I was forgetting to use the standard namespace because I haven't been using it for a while. It was a dumb mistake.

This topic is closed to new replies.

Advertisement