Monday, July 27, 2009

Simple Keyboard Input Wih DirectX

Since I'm learning DirectX, I thought I'd be posting tons of little examples of all the things I'm learning Very Happy Here we make a fullscreen window, and I set it up to receive simple input from my keyboard. Press the "Up arrow" key and it changes to one color, press the "Down arrow" key, and it'll switch to another

Here's the code (It's pretty well commented)(It looks like a lot of code for something rather simple, but most of this is tedious, not hard):
// include the basic windows header files and the Direct3D header file
#include
#include
#include

// define the screen resoution and keyboard macros
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// 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(void); // renders a single frame
void render_frame2(void);
void render_frame3(void);
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)
{
HWND hWnd;
WNDCLASSEX wc;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // not needed any more
wc.lpszClassName = "WindowClass";

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL,
"WindowClass",
"Our Direct3D Program",
WS_EX_TOPMOST | WS_POPUP, // fullscreen values
0, 0, // the starting x and y positions should be 0
SCREEN_WIDTH, SCREEN_HEIGHT, // set the window to 640 x 480
NULL,
NULL,
hInstance,
NULL);

ShowWindow(hWnd, nCmdShow);

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

// enter the main loop:

MSG msg;
render_frame();

while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if(msg.message == WM_QUIT)
break;


// check the 'escape' key
if(KEY_DOWN(VK_ESCAPE))
PostMessage(hWnd, WM_DESTROY, 0, 0);

if (KEY_DOWN(VK_UP))
{
Beep(500, 400);
render_frame2();
}

if (KEY_DOWN(VK_DOWN))
{
Beep(700, 300);
render_frame3();
}
}

// 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)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}

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 for use
d3dpp.Windowed = FALSE; // program fullscreen, not windowed
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit
d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer
d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer


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


// this is the function used to render a single frame
void render_frame(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(50, 50, 50), 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
}

void render_frame2(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(30, 0, 150), 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
}

void render_frame3(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(100, 0, 20), 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
}


// 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
}


Enjoy
~ mike

Share/Save/Bookmark

Sorry I haven't been posting

I'm learning DirectX right now, and well it's kinda tedious if you will :P

I'm just starting to learn about rendering and 3D objects, but I'll be sure to start posting examples as soon as I can. Keep checking the site :D

~ mike

Share/Save/Bookmark

Friday, July 17, 2009

Exponents in C++

Yeah yeah yeah, I know there's a CMath exp() declared in math.h, but I was really bored :D So enjoy:

#include <iostream>

using namespace std;

template
T expo(T &number, T timesToExpo)
{
T tmp = 0;
tmp = timesToExpo*(number*number);
return tmp;
};

int main(void)
{
int x = 50;
int &ref = x;

cout << expo (ref, 4);

return 0;
}



I used a template so you can use this for multiple types too

Share/Save/Bookmark

Wednesday, July 8, 2009

Using Assert To Imporve Code

Something I found interesting, I was looking for a bug in my code, and I decided to try using assert(). It surprisingly was a very useful function. Helps a lot, and I plan on using it more as I come to bigger problems

#include <assert.h>

using namespace std;

int main()
{
int datafile = 3000;
assert (datafile == 4000);
return 0;
}


Share/Save/Bookmark

Monday, July 6, 2009

Deleting Files Easily in C/C++!

Ever have a file to delete, but not sure how? Well, I always thought that you had to do stuff with the OS. But the C Library comes with a really useful function declared in stdio.h :D It's called remove().

Here's an example on how to use it:
#include <stdio.h>

int main ()
{
if( remove( "time.h" ) != 0 )
perror( "Error deleting file" );
else
puts( "File successfully deleted" );
return 0;
}


This example is in C, but it'll definitely work in C++ too :D

Enjoy
Share/Save/Bookmark

Sunday, July 5, 2009

Getting LXDE for Ubuntu

Tired of GNOME or KDE??? Why not try a new desktop enviornment? I found a pretty good one; it's called LXDE and you should really try it out:

sudo apt-get install LXDE


Screenshot:

Share/Save/Bookmark

Saturday, July 4, 2009

AUGGGHHHH!!! Terrible Bug!!!

I was working on the game tutorial; and i as i was coding i found/created a terrible bug :O(

Basically the ball doesn't work at all, and well I have an idea on how to fix it, but it could take a while. Once the bug is fixed and everything is settled we'll continue with the tutorial. I will continue posting other thing though :D

~ mike

Share/Save/Bookmark

Thursday, July 2, 2009

Sleeping in Linux - ZZZZZZZZZZZZZ!!!!

One of my favorite functions offered to me by the Windows OS is sleep(); It's easy to use, and really useful for seeing things to fast for our eyes to catch. Now, what happens if we're using Linux? Do we lose this? Nope, we get something too :D It's called usleep(); It's pretty much the equivalent of sleep(). The code below illustrates this:


#include <iostream>

using namespace std;

main(void)
{
cout << "First Beep! \a\n";
cout << "Next Beep in 8 seconds \a\n";
usleep(8000000);

cout << "Second Beep! \a\n";
cout << "All Done";

return 0;
}


Get it? Please not, this takes a parameter of number of microseconds!!! Not MILLISECONDS!!!! Keep this in mind :D

Share/Save/Bookmark

Monday, June 29, 2009

Game Tutorial Part 3 - Getting the Paddles to Move!

Ok Everyone,

I brushed up a little on Cairo, and spent a little time rewriting the game. It now has more structure, and is easier to work with.

Here's the current code we use to make the player paddle move via click(I explain any major modifications to the files):

main.cpp
// The Includes
#include <iostream>
#include <cairo.h>
#include <math.h>
#include <gtk/gtk.h>
#include "paddle.h"
#include "defines.h"
#include "prototypes.h"

/*** The widgets we'll be using ***/
GtkWidget *win = NULL;
GtkWidget *score = NULL;
GtkWidget *box = NULL;
cairo_t *canvas = NULL;

int coordx = DEFAULT_X;
int coordy = DEFAULT_Y;



int main (int argc, char *argv[])
{

/*** Initialize GTK+ ***/
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
gtk_init (&argc, &argv);
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

/*** Create the main window ***/
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_window_set_title (GTK_WINDOW (win), "Ping Pongo!");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
gtk_widget_realize (win);
gtk_window_set_default_size(GTK_WINDOW (win), 850, 400);
/*** This undecorates the window ***/
gtk_window_set_decorated(GTK_WINDOW (win), FALSE);
gtk_widget_set_app_paintable(win, TRUE);
gtk_widget_add_events (win, GDK_BUTTON_PRESS_MASK);


/*** This adds a fixed box ***/
box = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(win), box);

/*** Setting up player 1's paddle ***/
playerpaddle play1pad(); // player1's paddle, and its default position

/*** Setting up the computers paddle ***/
paddle compad; // computers paddle, and its default position


/*** Callbacks ***/
g_signal_connect (win, "destroy", gtk_main_quit, NULL);
g_signal_connect(win, "button-press-event", G_CALLBACK(moveplay1), NULL);
g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(on_expose_event), NULL);



/*** Enter the main loop ***/
gtk_widget_show_all (win);

gtk_main ();
return 0;
}

gboolean moveplay1(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
coordx = event->x;
coordy = event->y;

if (coordy < playerpaddle::getcoordy())
{
playerpaddle::moveup(win, coordy);
};
if (coordy > playerpaddle::getcoordy())
{
playerpaddle::movedown(win, coordy);
}

return TRUE;

};


/*** This functions is everything that needs to be done as soon as the window is ready ***/
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
int width, height;
gtk_window_get_size(GTK_WINDOW(widget), &width, &height);

canvas = gdk_cairo_create(widget->window);

cairo_set_source_rgb(canvas, 0, 0, 0);
cairo_rectangle(canvas, 0, 0, 850, 400);
cairo_fill(canvas);
playerpaddle play1pad(win);
}



paddle.h
#ifndef PADDLE_H_INCLUDED
#define PADDLE_H_INCLUDED

class paddle
{
public:
paddle();
~paddle();

private:
// none right now
};



class playerpaddle : public paddle
{
public:
/*** This is the advanced destructor it takes a widget, and positions for the paddle ***/
playerpaddle(GtkWidget *widget);
~playerpaddle();

static void moveup(GtkWidget *widget, int coordy);
static void movedown(GtkWidget *widget, int coordy);
static int getcoordy();


private:
static bool beenCalled; // this evaluates to true in the constructor and false in destructor
static int currentX; // This get's the current x pos of the paddle
static int currentY; // This get's the current y pos of the paddle

static cairo_t *cr;

static int timesMoved; // this tells us the number of times move() has been called
};




class compaddle : public paddle
{
public:
compaddle();
~compaddle();

private:
// none as of now
};


#endif // PADDLE_H_INCLUDED


paddle.cpp(Improved Constructor)
#include <iostream>
#include <cairo.h>
#include <math.h>
#include <gtk/gtk.h>
#include "paddle.h"
#include "defines.h"

/*** definitions of paddle class ***/
paddle::paddle()
{
g_print("Deafult Constructor\n");
};


paddle::~paddle()
{
g_print("Paddle Destructor\n");
};




/*** Definitions of playerpaddle class ***/
bool playerpaddle::beenCalled = false;
int playerpaddle::currentX = 0;
int playerpaddle::currentY = 0;
int playerpaddle::timesMoved = 0;
cairo_t* playerpaddle::cr;

playerpaddle::playerpaddle(GtkWidget *widget)
{
currentX = DEFAULT_X;
currentY = DEFAULT_Y;
g_print("Playerpaddle Constructor\n");
beenCalled = true; // this let's us know that a paddle exsists

cr = gdk_cairo_create(widget->window);

cairo_set_source_rgb(cr, 255, 255, 255);
cairo_rectangle(cr, DEFAULT_X, DEFAULT_Y, 15, 100);
cairo_fill(cr);
};

playerpaddle::~playerpaddle()
{
g_print("Playerpaddle Destructor\n");

};

void playerpaddle::moveup(GtkWidget *widget, int coors)
{
g_print("MoveUp was called\n");


while(currentY > coors)
{

cairo_t *cr2 = NULL;
cr2 = gdk_cairo_create(widget->window);

/*** First we cover up the current rectangle ***/
cairo_set_source_rgb(cr2, 0, 0, 0);
cairo_rectangle(cr2, DEFAULT_X, currentY, 15, 100);
cairo_fill(cr2);

currentY = currentY - 5;

cairo_set_source_rgb(cr2, 0, 0, 255);
cairo_rectangle(cr2, DEFAULT_X, currentY, 15, 100);
cairo_fill(cr2);

}
};

void playerpaddle::movedown(GtkWidget *widget, int coordy)
{
cairo_t *cr2 = NULL;
cr2 = gdk_cairo_create(widget->window);

g_print("MoveDown was called\n");

while(currentY < coordy)
{
/*** First we cover up the current rectangle ***/
cairo_set_source_rgb(cr2, 0, 0, 0);
cairo_rectangle(cr2, DEFAULT_X, currentY, 15, 100);
cairo_fill(cr2);

currentY = currentY + 5;

cairo_set_source_rgb(cr2, 0, 0, 255);
cairo_rectangle(cr2, DEFAULT_X, currentY, 15, 100);
cairo_fill(cr2);
}
};


/*** compaddle definitions ***/
compaddle::compaddle()
{
g_print("ComPaddle Constructor");
};

compaddle::~compaddle()
{
g_print("ComPaddle Constructor");
};

int playerpaddle::getcoordy()
{
return currentY;
}


defines.h (We now have defined ZERO)
// Default Paddle Position for Player 1
#ifndef DEFAULT_X
#define DEFAULT_X 45
#endif


#ifndef DEFAULT_Y
#define DEFAULT_Y 140
#endif

// Default Paddle Position for Computer
#ifndef COMP_DEFAULT_Y
#define COMP_DEFAULT_Y 140
#endif

#ifndef COMP_DEFAULT_X
#define COMP_DEFAULT_X 775
#endif

#ifndef ZERO
#define ZERO 0
#endif


prototypes.h
#ifndef PROTOTYPES_H_INCLUDED
#define PROTOTYPES_H_INCLUDED

gboolean moveplay1(GtkWidget *widget, GdkEventButton *event, gpointer user_data);
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);


#endif // PROTOTYPES_H_INCLUDED


Here are some images of it running(The white paddle is the default position, I made it turn blue once it has been moved for demonstrative purposes)

Before:


After:


Enjoy! :D


Share/Save/Bookmark

Changing A Window's Background Color in CAIRO and Gtk+

A lot of times, we need to draw on a window that isn't the default color of a Gtk+ Window. Looking for how to do this was boring and hard (and the only answer i found was to edit the widget itself, which I personally this is a bunch of BS)

I found a much better way to do it, here's an example of it:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <cairo.h>

static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
cairo_t *cr = NULL;
cr = gdk_cairo_create(widget->window);

cairo_set_source_rgb(cr, 0, 0, 3);
/*** make the rectangle start at (0,0) an make it take up the whole window ***/
cairo_rectangle(cr, 0, 0, 600, 300);
/*** Fill it in ***/
cairo_fill(cr);

return FALSE;
};


int main (int argc, char *argv[])
{
GtkWidget *win = NULL;
cairo_t *cr = NULL;

/* Initialize GTK+ */
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
gtk_init (&argc, &argv);
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

/* Create the main window */
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_window_set_title (GTK_WINDOW (win), "Hello World");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
gtk_widget_realize (win);
gtk_window_set_default_size(win, 600, 300);

gtk_widget_set_app_paintable(win, TRUE);

g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(on_expose_event), NULL);
g_signal_connect (win, "destroy", gtk_main_quit, NULL);



/* Enter the main loop */
gtk_widget_show_all (win);
gtk_main ();
return 0;
}


Here's a pic of it running :D


I'll be posting some more CAIRO tutorials and snippets as I move along with the tutorial I'm following


Share/Save/Bookmark