Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    6
  • comments
    6
  • views
    4820

Entries in this blog

 

Reflecting on Shadows

Slowly but surely I have been progressing with my project or should I say projects as I jump around and do different things depending on my mood.

Anyway, the latest addition to my source code collection is my Stencil class.

Using the relevant chapters in 'Introduction to 3D Game Programming' by Frank Luna I have built up a stencil class to handle reflections and shadows. At least at a basic level with room for growth.

Here is the resulting output of my project with the stencil class in use:



There is a slight problem with the shadowing technique but I am sure that will get worked out in due course.

For those interested here is a snipping of my Stencil class functionality:


#pragma once

#include
#include "DirectXObject.h"

class CDXStencil : public IDirectXObject
{
public:
enum enStencilType
{
Reflection = 0x0001,
Shadow = Reflection 1,
Nothing = 0xFFFF
};
protected:
enStencilType m_enType;
private:
public:

CDXStencil(IDirect3DDevice9* pDevice, enStencilType enType);
~CDXStencil();

bool Initialise(void);
void DeInitialise(void);

void Start(void); // Sets the Stencil render states
void End(void); // Restores the render states

void SetReflectionStates(); // Sets the Reflection special states

D3DXMATRIX GetShadowMatrix(float ax, float by, float cz, float dw, D3DXVECTOR3 lDirection, float lType);
D3DXMATRIX GetReflectiveMatrix(float ax, float by, float cz, float dw);
};



As you can see from the header file there isn't much to work with but this is how the class is used within a project:


// Declare
CDXStencil* gpReflection = NULL;
CDXStencil* gpShadow = NULL;

// Create
gpReflection = new CDXStencil(gpDirectX->Device(),CDXStencil::Reflection);
gpShadow = new CDXStencil(gpDirectX->Device(),CDXStencil::Shadow);

// Use

// Draw Normal Scene
DrawTeapot(false,false);
DrawMirror();
DrawFloor();
// End of Normal Scene

// Draw Shadow Scene
gpShadow->Start();
DrawTeapot(false,true);
gpShadow->End();
// End of Shadow Scene

// Draw Reflection Scene
gpReflection->Start();
DrawMirror();
gpReflection->SetReflectionStates();
DrawTeapot(true,false);
gpReflection->End();
// End of Reflection Scene

// Finished with
delete gpShadow;
delete gpReflection;




The DrawTeapot routine is where the fancy work is utilised:

// draw teapot
gpTeapotWorld->Initialise();
gpTeapotWorld->Position(TeapotPosition);
gpMaterial->SetColor(true,true,true,true,1.0f,1.0f,1.0f,0.0f);
if (bReflection)
{
gpMaterial->SetColor(true,true,true,true,0.8f,0.8f,0.8f,0.0f);
gpTeapotWorld->Reflection(gpReflection->GetReflectiveMatrix(0.0f,0.0f,1.0f,0.0f));
}
if (bShadow)
{
gpMaterial->SetColor(true,true,true,true,0.2f,0.2f,0.2f,0.0f);
gpTeapotWorld->Shadow(gpShadow->GetShadowMatrix(0.0f,-1.0f,0.0f,0.0f,D3DXVECTOR3(0.0f,-1.0f,-1.0f),0.0f));
}
gpTeapotWorld->UpdateWorld();
gpMaterial->Use();
gpTexture->StopUsing(0);
gpTeapot->DrawSubset(0);



TeapotWorld is an instance of the WorldObject class I use to handle the Matrix Transformations for each object that requires it.

The code for the GetReflective and GetShadow routines are as follows:

D3DXMATRIX CDXStencil::GetReflectiveMatrix(float ax, float by, float cz, float dw)
{
D3DXMATRIX matReflection;
D3DXPLANE plane(ax, by, cz, dw); // xy plane
D3DXPlaneNormalize(&plane,&plane);
D3DXMatrixReflect(&matReflection, &plane);
return matReflection;
}

D3DXMATRIX CDXStencil::GetShadowMatrix(float ax, float by, float cz, float dw, D3DXVECTOR3 lDirection, float lType)
{
D3DXMATRIX matShadow;
D3DXVECTOR4 lightDirection;
lightDirection.x = lDirection.x;
lightDirection.y = lDirection.y;
lightDirection.z = lDirection.z;
lightDirection.w = lType;
D3DXPLANE plane(ax,by,cz,dw);
D3DXPlaneNormalize(&plane,&plane);
D3DXMatrixShadow(&matShadow,&lightDirection,&plane);
return matShadow;
}



Now to post the query regarding the shadow offset.

Xrystal

Xrystal

 

GUI Update

Well, finished the last of the interface controls. Well, apart from check boxes but may be able to get away with copying the CloseBox class for that and use either CloseBox visual and ScrollBox visual depending on selectability.

The screen components currently look like this:



Next step, figure out what user interaction is needed, set up clickable areas for each control (probably via their sub controls base information).

Xrystal

Xrystal

 

Beginnings of a GUI System

The last couple of weeks I've been working on a GUI system and after the first pitfall moved onto another way of creating a GUI.

It currently looks like this but has no functionality of yet. The coloring is generated from an effect file so we can play with that later and make things snazzy.

The last 3 controls to consider is text box, list box and combo box which visually won't be a problem but functionality will have to be added later.

Xrystal

Xrystal

 

Been Busy of Late

Just in case anyone was wondering. Probably not but here goes anyway.

I haven't got round to updating the journal because 1) I keep forgetting its here and 2) I have been busy.

I shifted away from Managed DirectX for the moment. I know its something I will have to get back to at some point but there are so many books out there for unmanaged learning that at present it makes sense that I learn things from an unmanaged format and then place what I know in a managed environment at a later date.

Anyways, this meant recycling my project system to start with a simple Unmanaged application. And then building on it.

I currently have 3 top level projects running :
Textures, Terrain and GUI

I've currently been working on a GUI system to basically help me runtime to set some things up in my terrain and texture projects so I haven't forgotten them just trying to get the GUI side working. Also, my brother who is working on a game project with me has asked me too so that he can then use them in his Networking App test projects.

We are trying to build up a good if not solid and morphable engine system so that modules can be plugged into any Engine system as required.

Of course, we are learning as we are progressing so we are getting enjoyment out of every success and frustrated at every pitfall. But we will get there .... at some point.

Xrystal

Xrystal

 

Noisy Pictures

Well now that I can draw a pretty terrain I thought I should see about looking into how those rendering programs get those nice landscapes generated and lovely textures.

Whilst trying to get a marbly texture I managed to get the following image to appear using the following code:


bool DXTerrain::GenerateTexture(void)
{
int TexWidth = m_VertsPerRow;
int TexDepth = m_VertsPerCol;

SurfaceDescription sfcd = m_texture->GetLevelDescription(0);
if ( sfcd.Format != Format::X8R8G8B8 ) return false;
int* ImageData = (int*)m_texture->LockRectangle(0,LockFlags::None)->InternalData.ToPointer();
int m_rangeHeight = (int)(m_maxHeight / 5.0f);
Int32 m_Ranges __gc[] = new Int32[5];
for (int i=0; i 5; i++)
{
m_Ranges = m_minHeight + (m_rangeHeight * i);
}
Random* r = new Random();
int rndR = r->Next(0,1000);
float t;
int f;
for (int i = 0; i {
for (int j = 0; j {
int c;
int index = (j * m_VertsPerCol + i);
float height = (m_heights[index]);

// Currugated Iron
t = (float)Math::Cos(i + m_noise->Perlin3D(j+rndR * 0.625f, i+rndR *0.625f, height+rndR * 0.625f));

// Weird Lattice Effect
//t = (float)Math::Cos(i + m_noise->Perlin3D(j+rndR * 0.625f, i+rndR *0.625f, height+rndR * 0.625f));

if(t0) t = -t;
if(t>1) t = 1.0f;
int f = (int)(t * 255.0f);
c = Color::FromArgb(f,f,f).ToArgb();
ImageData[index] = c;
}
}
//m_texture->AutoGenerateFilterType = TextureFilter::Anisotropic;
m_texture->GenerateMipSubLevels();
m_texture->UnlockRectangle(0);
return true;
}



The output looks like this:



Xrystal

Xrystal

 

Ah the fun of generating textures

Well, I've been spending the last few months recoding my base code as I had avoided testing return codes and such things and wanted to make the code as multi useable as possible.

A brief breakdown of what I have so far is as follows:

DXBase - Handles the basic requirements of directx.
DXFont - Handles font operations
DXSprite - Use for the 2D element of the graphical interface
DXCamera - Handles the view of the application
DXPrimitive - Handles the drawing of basic objects
DXRay - Handles ray tracing facilities
DXTerrain - Handles anything to do with a terrain

Obviously they are open towards improvement as I learn more in this area. The idea is at some point this base code will become the backbone of any application I choose to create once I've got these basics down pat.

The latest success is the ability to colorise the terrain texture file based on height of the point in question. Its not perfect but is something to work on. Just needs some fine tuning and the picking of more appropriate colors or a better range of heights to test against.

Well for those that are interested here is the current texture generation code that is used in my sample code.


bool DXTerrain::GenerateTexture(void)
{
int TexWidth = m_VertsPerRow;
int TexDepth = m_VertsPerCol;

m_texture = new Texture(m_device,TexWidth,TexDepth,0,Usage::AutoGenerateMipMap,Format::X8R8G8B8,Pool::Managed);
SurfaceDescription sfcd = m_texture->GetLevelDescription(0);
if ( sfcd.Format != Format::X8R8G8B8 ) return false;
int* ImageData = (int*)m_texture->LockRectangle(0,LockFlags::None)->InternalData.ToPointer();
int m_rangeHeight = (int)(m_maxHeight / 5.0f);
Int32 m_Ranges __gc[] = new Int32[5];
for (int i=0; i 5; i++)
{
m_Ranges = m_minHeight + (m_rangeHeight * i);
}
Random* r = new Random();
for (int i = 0; i {
for (int j = 0; j {
int c;
int index = (j * m_VertsPerCol + i);
float height = (m_heights[index]);

if (height 0) c = Color::Aqua.ToArgb();
else if (height 0]) c = Color::Yellow.ToArgb();
else if (height 1]) c = Color::Green.ToArgb();
else if (height 2]) c = Color::DarkGreen.ToArgb();
else if (height 3]) c = Color::Brown.ToArgb();
else if (height 4]) c = Color::SlateGray.ToArgb();
else c = Color::Snow.ToArgb();

ImageData[index] = c;
}
}
m_texture->AutoGenerateFilterType = TextureFilter::Anisotropic;
m_texture->GenerateMipSubLevels();
m_texture->UnlockRectangle(0);
return true;
}




Here's the current screenshot of a small map. As you can see its not great but it shows promise.


Xrystal

Xrystal

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!