C++

Direct X Squares and Lighting

Okay So, I actually did this more then a week ago. But decided to include it since well I spent a few hours working out lighting and Squares in 3d space. I was surprised how much trial and error was involved. While this demo video below isn’t perfect since I actually have to figure how much light is needed to bounce off of every side of the square. I ended up understanding but tried for another effect. In the video you’ll see two squares rotating. They have an ambient light lighting them constantly so we can see them, but I included a spot light….

The interesting thing about the spot light is that in direct x, you don’t just say “I want my spot light (X,Y,Z) and facing a certain way”. You actually have to indicate which vectors triangles are going to be lit. That means if I was to set random vectors to be lit, I could get a sort of random effect of light fading in and out of certain sides. While this is nothing really special it give a strange lighting effect. that I somewhat enjoy. Anyways, Why I haven’t been doing much with direct x for the last week as I stated above, was because I have been working on more of my coding  intermediate “basics”. This I am hoping will help me understand more later on down the road. Once I finish this book, I should be back to focusing more on graphical programming, as I need an engine to run my games…

Anyways here is the video.

One other thing is I forgot to deselect the option to record what you are listening to, As I was listening to some music it was recorded as well. It is also quite loud before starting the video turn your speakers down.

If you did like it… The guy is called DNTEL. Very good music to listen to.

Advertisements

DirectX and a Colorful Triangle

So I think its better if I keep my text short as I have included a video that will explain most of what I have been up to lately. I feel that I am actually making some progress with DirectX (finally) as it is very complex. The neat thing, once you watch the video, is that these principles can be applied to more complex structures and matrix-es. The triangle in the video is simple. I will soon be able to import other objects and then map out keystrokes to camera movement which then would basically emulate player movement. Anyways any questions? Ask away, I’ll try my best.

Oh, I will also include the source code for this, so if you want to fool around with it also. Go right ahead, take it.

VIDEO:

 

Sorry for the terrible quality. I know you can’t really see anything… this is because vimeo only allows me to upload one HD video per week… sadly I did one right before this one. So… This is what I am stuck with. If you really want to see the video goto the video on vimeo website is there is a HD download version  you’ll just have to download it… It’s not big. Probably like 25 megs or so. Anyways, my apologies.

CODE:

// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>

// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

// include the Direct3D Library files
#pragma comment (lib, “d3d9.lib”)
#pragma comment (lib, “d3dx9.lib”)

// global declarations
LPDIRECT3D9 d3d;    // the pointer to Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;    // the pointer to the vertex buffer

// function prototypes
void initD3D(HWND hWnd);    // sets up and initializes Direct3D
void render_frame(void);    // renders a single frame
void cleanD3D(void);    // closes Direct3D and releases memory
void init_graphics(void);    // 3D declarations

struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)

// 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.lpszClassName = L”WindowClass”;

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L”WindowClass”, L”Spinning Triangle YAAAAHHHH”,
WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

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

// enter the main loop:

MSG msg;

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

if(msg.message == WM_QUIT)
break;

render_frame();
}

// 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);

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

// 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);

init_graphics();    // call the function to initialize the triangle

d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);    // turn off the 3D lighting
d3ddev->SetRenderState(D3DRS_CULLMODE, TRUE); // render both sides of the Triangle

}

// this is the function used to render a single frame
void render_frame(void)
{

int R = 0;
int G = 0;
int B = 0;

int xColor = 255;

for ( xColor; xColor <= 255; xColor–)
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(R, G, B), 1.0f, 0);

d3ddev->BeginScene();

// select which vertex format we are using
d3ddev->SetFVF(CUSTOMFVF);

// SET UP THE PIPELINE

//D3DXMATRIX matRotateX;    // a matrix Pointers to store the rotation information
//D3DXMATRIX matTranslate;
D3DXMATRIX matRotateY;
//D3DXMATRIX matRotateZ;

static float index = 0.0f; index+=0.05f;    // an increasing float value
static float zoom = 45.0; zoom-=0.05f;
// build a matrix to rotate the model based on the increasing float value
//D3DXMatrixRotationX(&matRotateX, D3DXToRadian(-90));
D3DXMatrixRotationY(&matRotateY, index);
//D3DXMatrixTranslation(&matTranslate,0.0f, index, 0.0f);
//D3DXMatrixRotationZ(&matRotateZ, index);

// tell Direct3D about our matrix
d3ddev->SetTransform(D3DTS_WORLD, &matRotateY);

D3DXMATRIX matView;    // the view transform matrix

D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 0.0f, 20.0f),    // the camera position
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),    // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction

d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView

D3DXMATRIX matProjection;     // the projection transform matrix

D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(zoom),    // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f,    // the near view-plane
200.0f);    // the far view-plane

d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection

// select the vertex buffer to display
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

// copy the vertex buffer to the back buffer
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);
R++;
}
}

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

// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX vertices[] =
{
{ 3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 0.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ -3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
};

// create a vertex buffer interface called v_buffer
d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);

VOID* pVoid;    // a void pointer

// lock v_buffer and load the vertices into it
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
}


C++ and DirectX 9

So, Sadly I wrote out a whole post only to have wordpress lose it somehow, So now I am unwillingly typing this post out again. Definitely with less excitement. Though I will try my best to keep it interesting. So I have been working lately with C++ and Less C#. Mainly I have been wanting to learn how to draw with Directx. So as I thought the best way to start making something appear on screen would be through drawing one single pixel to screen. I made it so I could choose colors and make it available to me if I wanted to change these colors, that I could.

Anyways I succeeded, with some reading, in actually drawing a white pixel to the screen, Now I started thinking if I wanted to draw a line to the screen how would I go about this. Have you guessed it. YES! That is correct. I will need to string multiple pixels together to created a line. Now I could have just repeated the code I wrote and changed the pixel coordinates by one every time one is drawn. That would work, but would take a long time. Think about it this way. If you wanted to make a line that was 100 pixels long you would have to copy the code 100 times, change each value 100 times then hope that there isn’t any typos in that code that could introduce bugs. What I am getting at is there is an easier way!

LOOPS!

The for loop is excellent for this. Basically for those that don’t know, A for loop will take value and increment it for however long I want it to go for. (very true to the name, “for loop”). ANYWAYS I stuck the code to draw a pixel into the loop and told it to go for about 200 pixels… this is what I got.

A line drawn.

Yup. pretty boring. But my theory worked. and I am positive this is how it is normally done… At least I think it is. Anyways next I thought it would be cool to resize and manipulate this line just to see how it would react. I know most have heard of the equation Y = mx+b. me too. I didn’t think I needed to know or remember it ever again. Well surprise I do. If I want to Draw “graph” a line that has some sort of slope, I need to use this equation. After some trial and error, I got it to work. I will post the code below for those that are interested. Can you find the equation in the code?! A fun challenge.

Here is another picture of the Line at an angle. One disclaimer, you might be wondering why I am even doing this. Fundamentals my boy! This code can apply to some rather cool things down the road that I will probably hit on later on.

Angled Line

Also Here is a video of the Line movement.

Enjoy.

CODE:

void D3DGraphics::DrawLine( int x1, int y1, int x2, int y2, int r, int g, int bl )
{
int dy = y2 -y1;
int dx = x2 – x1;

if (abs( dy ) > abs ( dx ) )
{
if (y1 > y2)
{
int temp = y2;
y2 = y1;
y1 = temp;
temp = x2;
x2 = x1;
x1 = temp;
}
float m = (float)dx / (float)dy;
float b = x1 – m*y1;
for ( int y = y1; y <= y2; y++)
{
int x = m*y + b + 0.5f;
PutPixel(x,y,r,g,bl);
}
}
else
{
if ( x1 > x2 )
{
int temp = y2;
y2 = y1;
y1 = temp;
temp = x2;
x2 = x1;
x1 = temp;
}
float m = (float)dy / (float)dx;
float b = y1 – m*x1;
for ( int x = x1; x <= x2; x++ )
{
int y = m*x + b + 0.5f;
PutPixel( x,y,r,g,bl );
}
}

}