Jump to content
  • Advertisement
Sign in to follow this  
simotix

Project texturing issue

This topic is 3230 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am reading 3D Game Programming With DirectX 9.0c A Shader Approach and I am trying to learn how to do projective texturing. However, I do understand how the light frustum is made. He details it as
		D3DXMATRIX mLight;

		D3DXMATRIX lightLens;
		float lightFOV = D3DX_PI*0.30f;
		D3DXMatrixPerspectiveFovLH(&lightLens, lightFOV, 1.0f, 1.0f, 200.0f);

		D3DXMATRIX lightView;
		D3DXVECTOR3 lightPosW(60.0f, 90.0f, 0.0f); // Why 60, 90, 0
		D3DXVECTOR3 lightTargetW(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f);
		D3DXMatrixLookAtLH(&lightView, &lightPosW, &lightTargetW, &lightUpW);

		mLight = objectTransform*lightView*lightLens;

But I do not understand why. I tried to write it and I just get a blurred texture. Does anyone know what I am doing wrong? (Also, the bottom half of the plane does not have the texture showing up, that is not because of the shader but because of my render code. I am trying to figure that out). Image of the plane: http://img16.imageshack.us/img16/7299/projectivetexturewrong.jpg Texture (testTexture.dds) http://www.wikiupload.com/download_page.php?id=178644 DirectX Code
#include <windows.h>
#include <iostream>
#include <ctime>	//time() for random seed

#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

//Random Float Macro
#define RAND_FLOAT(min,max) (((rand()/(float)RAND_MAX)*((max)-(min)))+(min))
#define KEYDOWN(key) ((GetAsyncKeyState(key) & 0x8000) ? true : false)
#define SAFE_RELEASE(p) { if(p){ p->Release(); p = NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete [] p; p = NULL; } }

using namespace std;

#define			SCREEN_WIDTH		800
#define			SCREEN_HEIGHT		600

HINSTANCE   app;
HWND        wnd;

struct VERTEX 
{
	D3DXVECTOR3	pos;
	D3DXVECTOR3 normal;
	float u, v;
};


struct Light
{
	D3DXVECTOR3 vAmbient; 
	D3DXVECTOR3 vDiffuse;
	D3DXVECTOR3 vSpecular;

	D3DXVECTOR3 vPosition;
	float fRadius;
};

IDirect3D9			*d3d = NULL;
IDirect3DDevice9	*dev = NULL;
ID3DXFont			*dxFont = NULL;

IDirect3DVertexDeclaration9		*vertexDecl=NULL;

IDirect3DVertexBuffer9			*squareBuff=NULL; // square
IDirect3DIndexBuffer9			*squareIndex=NULL;// square indices
IDirect3DTexture9        *squareTexture=NULL;

ID3DXEffect				*shaderEffect; 
D3DXMATRIX camProjectionMatrix;
D3DXMATRIX camViewMatrix;

Light renderLight;



//--------------------------------------------------------------------------

bool InitWindow();						// initialize window
void InitGame();
void InitDirLight();
void InitSpotLight();
void InitPointLight();
void LoopGame();
void EndGame();

void InitDX();
void Render();
void Update();
void InitDX();
void InitGeometry();
void DrawSquare();

float DegreesToRadians(float Degrees);

int WINAPI WinMain(HINSTANCE hInstance,		// handle to application
				   HINSTANCE hPrevInstance,	// handle to previous app
				   LPTSTR lpCmdLine,		// command line string
				   int nCmdShow );			// show window value

LRESULT CALLBACK WndProc(HWND hWnd,				// handle to window
						 UINT message,			// incoming message
						 WPARAM wparam,			// message info
						 LPARAM lparam );		// message info

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, int )
{
	app = hInstance;				// store application handle
	InitWindow();					// init window
	InitGame();						// initialize game

	MSG msg; ZeroMemory( &msg, sizeof( msg ) );  // use to catch windows messages
	while ( msg.message != WM_QUIT ) 
	{

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

		LoopGame();					// MAIN GAME LOOP!

	}

	EndGame();						// game shutdown and cleanup

	UnregisterClass( "DirectXApplication", app ); // unregister window
	return 0; // done
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	// attempt to handle
	switch ( message )
	{
	case ( WM_DESTROY ): { PostQuitMessage( 0 ); }
						 break;
	}
	// pass to default handler
	return DefWindowProc( hWnd, message, wParam, lParam );
}

bool InitWindow( void )
{   
	WNDCLASSEX  wndClass;

	// register a new type of window
	ZeroMemory( &wndClass, sizeof( wndClass ) );
	wndClass.cbSize         = sizeof( WNDCLASSEX );             // size of window structure
	wndClass.lpfnWndProc    = ( WNDPROC )WndProc;               // message callback
	wndClass.lpszClassName  = "DirectXApplication";             // class name
	wndClass.hInstance      = app;                   // handle to application
	wndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );    // default cursor
	wndClass.hbrBackground  = ( HBRUSH )( COLOR_WINDOWFRAME );  // background brush
	RegisterClassEx( &wndClass );

	// create window of registered type
	wnd = CreateWindow(
		"DirectXApplication", "DirectX Application",                     // class name, window title 
		WS_OVERLAPPEDWINDOW,   // window style
		CW_USEDEFAULT, CW_USEDEFAULT,                           // x & y coordinates
		SCREEN_WIDTH, SCREEN_HEIGHT,                            // width & height of window
		NULL, NULL,                                             // parent window & menu
		app,                                         // handle to application
		NULL );

	// take a guess
	ShowWindow( wnd, SW_SHOW );                           // technically should be nCmdShow

	return true;
}

void InitGame()
{
	srand(unsigned int(time(0)));	//randomize!

	InitDX();
	InitGeometry();

	// InitCamera
	D3DXMatrixIdentity(&camViewMatrix);
	D3DXMatrixIdentity(&camProjectionMatrix);

	camViewMatrix._41 = 0.0f; camViewMatrix._42 = 0.0f; camViewMatrix._43 = -4.0f;
	D3DXMatrixPerspectiveFovLH(&camProjectionMatrix, D3DX_PI/3, float(SCREEN_WIDTH)/SCREEN_HEIGHT, 0.1f, 500.0f);

	// init Font
	D3DXCreateFont(dev, 32, 0, FW_NORMAL, NULL, false, 
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, 
		ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
		"Ariel", &dxFont);

	// Load the floar texture
	D3DXCreateTextureFromFile(dev, "testTexture.dds", &squareTexture);

	// init shader
	LPD3DXBUFFER pBufferErrors = NULL;
	HRESULT hResult = D3DXCreateEffectFromFile(dev, "ProjectiveTexture.fx", 
		NULL, NULL, 0, NULL, &shaderEffect, &pBufferErrors );

	renderLight.vAmbient = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
	renderLight.vDiffuse = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
	renderLight.vSpecular = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
	renderLight.fRadius = 4.0f;
	renderLight.vPosition = D3DXVECTOR3(0.0f, -2.0f, 0.0f);
}

void LoopGame()
{
	Update();
	Render();
}

void EndGame()
{	
	SAFE_RELEASE(squareBuff); squareBuff=0;
	SAFE_RELEASE(vertexDecl); vertexDecl=0;
	SAFE_RELEASE(squareTexture); squareTexture=0;

	//--------------------
	dxFont->Release(); dxFont=0;
	dev->Release();	dev=0;
	d3d->Release();	d3d=0;
}

void InitDX()			//Initialize D3D object
{
	d3d = Direct3DCreate9(D3D_SDK_VERSION);	

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

	d3dpp.hDeviceWindow = wnd;
	d3dpp.Windowed = true;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //no VSync
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

	// add for 3D
	d3dpp.EnableAutoDepthStencil = true;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

	d3d->CreateDevice(0, D3DDEVTYPE_HAL, wnd,
		D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &dev);

	dev->SetRenderState(D3DRS_ZENABLE, true);
	dev->SetRenderState(D3DRS_AMBIENT, false);	
	dev->SetRenderState(D3DRS_LIGHTING, false);
}

void Render()
{
	dev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0,0,100), 1, 0);
	dev->BeginScene();

	// Start the effect
	shaderEffect->SetTechnique("PerPixelPointLight");
	unsigned int unPasses;
	shaderEffect->Begin(&unPasses, 0);

	// Set light varaibles
	shaderEffect->SetFloatArray("light.pos", renderLight.vPosition, 3);
	shaderEffect->SetFloatArray("light.ambient", renderLight.vAmbient, 4);
	shaderEffect->SetFloatArray("light.diffuse", renderLight.vDiffuse, 4);
	shaderEffect->SetFloatArray("light.specular", renderLight.vSpecular, 4);
	shaderEffect->SetFloat("light.radius", renderLight.fRadius);

	// Set Matrial variables
	float ones[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
	shaderEffect->SetFloatArray("material.ambient", ones, 4);
	shaderEffect->SetFloatArray("material.diffuse", ones, 4);
	shaderEffect->SetFloatArray("material.specular", ones, 4);
	shaderEffect->SetFloat("material.shininess", 2.0f);

	// Set the texture
	shaderEffect->SetTexture("tCurrentTexture", squareTexture);

	// Set the matricies
	{
		D3DXMATRIX objectTransform;				// generic transformation matrix
		D3DXMatrixIdentity(&objectTransform);	// world transform for square
		D3DXMatrixRotationX(&objectTransform, DegreesToRadians(90.0f)); // Rotate 90 degrees on X, to make it look like it is laying down
		objectTransform._41 = -2.0f; objectTransform._42 = -1.0f; objectTransform._43 = -2.0f; // Center the plane in the view
		shaderEffect->SetMatrix("worldMatrix", &objectTransform);

		D3DXMATRIX viewMatrixForRender;
		{
			D3DXMATRIX _mRotation(camViewMatrix);
			_mRotation._41 = _mRotation._42 = _mRotation._43 = 0;
			D3DXMatrixTranspose(&_mRotation, &_mRotation);

			D3DXMatrixIdentity(&viewMatrixForRender);
			viewMatrixForRender._41 = -(camViewMatrix._41);
			viewMatrixForRender._42 = -(camViewMatrix._42);
			viewMatrixForRender._43 = -(camViewMatrix._43);
			D3DXMatrixMultiply(&viewMatrixForRender, &viewMatrixForRender, &_mRotation);
		}

		D3DXMATRIX mViewProj = objectTransform * viewMatrixForRender * camProjectionMatrix;
		shaderEffect->SetMatrix("worldViewProjectionMatrix", &mViewProj);

		// BOOK : This is what I do not understand, why these values?
		D3DXMATRIX mLight;

		D3DXMATRIX lightLens;
		float lightFOV = D3DX_PI*0.30f;
		D3DXMatrixPerspectiveFovLH(&lightLens, lightFOV, 1.0f, 1.0f, 200.0f);

		D3DXMATRIX lightView;
		D3DXVECTOR3 lightPosW(60.0f, 90.0f, 0.0f); // Why 60, 90, 0
		D3DXVECTOR3 lightTargetW(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f);
		D3DXMatrixLookAtLH(&lightView, &lightPosW, &lightTargetW, &lightUpW);

		mLight = objectTransform*lightView*lightLens;
		shaderEffect->SetMatrix("gLightWVP", &mLight);
	}

	shaderEffect->CommitChanges();

	shaderEffect->BeginPass(0);
	DrawSquare();
	shaderEffect->EndPass();

	shaderEffect->End();

	dev->EndScene();
	dev->Present(0,0,0,0);
}

void Update()
{

}

void InitGeometry()
{
	D3DVERTEXELEMENT9 decl[] = 
	{ 
		{0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
		{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
		{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
		D3DDECL_END()
	};
	dev->CreateVertexDeclaration(decl, &vertexDecl);

	//--------------------------------------------------
	//  square
	VERTEX sqverts[4];
	sqverts[0].pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);	// top left
	sqverts[1].pos = D3DXVECTOR3(0.0f, 5.0f, 0.0f);	// top left
	sqverts[2].pos = D3DXVECTOR3(5.0f, 5.0f, 0.0f);	// top right
	sqverts[3].pos = D3DXVECTOR3(5.0f, 0.0f, 0.0f);	// bottom right

	sqverts[0].u = 0;
	sqverts[0].v = 1;
	sqverts[1].u = 0;
	sqverts[1].v = 0;
	sqverts[2].u = 1;
	sqverts[2].v = 0;
	sqverts[3].u = 1;
	sqverts[3].v = 1;

	sqverts[0].normal = D3DXVECTOR3(0,1,0);
	sqverts[1].normal = D3DXVECTOR3(0,1,0);
	sqverts[2].normal = D3DXVECTOR3(0,1,0);
	sqverts[3].normal = D3DXVECTOR3(0,1,0);

	void* pBuffer;	

	dev->CreateVertexBuffer(4*sizeof(VERTEX),0,0,	D3DPOOL_DEFAULT, &squareBuff,0);

	squareBuff->Lock(0,0, &pBuffer, 0);
	memcpy(pBuffer, sqverts, 4*sizeof(VERTEX));
	squareBuff->Unlock();

	//////////// inidicies
	WORD indicies[6];
	indicies[0] = 0; indicies[1] = 1; indicies[2] = 2;
	indicies[3] = 0; indicies[4] = 2; indicies[5] = 3;

	dev->CreateIndexBuffer(6*sizeof(WORD),0, D3DFMT_INDEX16,  D3DPOOL_DEFAULT, &squareIndex, 0);

	squareIndex->Lock(0,0, &pBuffer, 0);
	memcpy(pBuffer, indicies, 6*sizeof(WORD));
	squareIndex->Unlock();
}

void DrawSquare()					// draw square
{	
	dev->SetStreamSource(0, squareBuff, 0, sizeof(VERTEX));
	dev->SetIndices(squareIndex);	
	dev->SetVertexDeclaration(vertexDecl);

	dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
}

float DegreesToRadians(float Degrees) 
{
	float DegreesToRadians = (float)(Degrees * (3.14159265f / 180));
	return DegreesToRadians;
}

ProjectiveTexture.fx
struct Light
{
	float3 dir;                    
	float3 pos;                    
	float4 ambient;			
	float4 diffuse;			
	float4 specular;		
	float radius;			
};

// Material structure to orginize material variables.
struct Material
{
	float4 ambient;			
	float4 diffuse;			
	float4 emissive;		
	float4 specular;		
	float shininess;
};

// World position of the object being passed in.
float4x4 worldMatrix;

// World * View * Projection Matrix
float4x4 worldViewProjectionMatrix;	

// Position of the camera
float3 cameraPos;

// The light structure to be used.
Light light;

// The incoming material structure
Material material;

// The texture to use.
texture tCurrentTexture;

uniform extern float4x4  gLightWVP;

sampler2D sTexture = sampler_state
{
	Texture = <tCurrentTexture>;
	MagFilter = NONE;
	MinFilter = NONE;
	MipFilter = NONE;
};

struct VS_INPUT
{
	float3 position : POSITION;
	float2 texCoord : TEXCOORD0;
	float3 normal : NORMAL;
};

struct VS_OUTPUT
{
	float2 texCoord : TEXCOORD0;
	float3 viewDir : TEXCOORD1;
	float3 lightDir : TEXCOORD2;
	float3 normal : TEXCOORD3;
	float4 diffuse : COLOR0;
	float4 specular : COLOR1;
	float4 position : TEXCOORD4;
   	float4 projTex  : TEXCOORD5;
};

VS_OUTPUT VS(VS_INPUT IN, out float4 outPos : POSITION)
{
	VS_OUTPUT OUT;

	float3 worldPos = mul(float4(IN.position, 1.0f), worldMatrix).xyz;
	OUT.viewDir = cameraPos - worldPos;

	outPos = mul(float4(IN.position, 1.0f), worldViewProjectionMatrix);
	OUT.position = float4(worldPos, 1.0f);
	OUT.texCoord = IN.texCoord;

	OUT.lightDir = (light.pos - worldPos);

	OUT.normal = mul(-IN.normal, (float3x3)worldMatrix);

	OUT.diffuse = material.diffuse * light.diffuse;
	OUT.specular = material.specular * light.specular;

	// BOOK : Render from light source to generate projective texture coordinates.
	OUT.projTex = mul(float4(IN.position, 1.0f), gLightWVP);

	return OUT;
}

float4 PS(VS_OUTPUT IN) : COLOR
{
	float3 n = normalize(IN.normal);
	float3 l = normalize(IN.lightDir);
	float3 v = normalize(IN.viewDir);
	float d = length(light.pos-IN.position);

	float3 h = normalize(l + v); 

	float nDotL = dot(n, l);
	float nDotH = saturate(dot(n, h));

	float specularPower = pow(nDotH, material.shininess); 

	float atten = 1.0f-d/light.radius;


	float4 finalColor = float4(0.0f, 0.0f, 0.0f, 1.0f);

	if(nDotL >= 0)
	{
		finalColor = (material.ambient * (atten * light.ambient)) +
			(IN.diffuse * nDotL * atten) + (IN.specular * specularPower * atten);

		float4 projecTexCoord = IN.projTex;

		// Project the texture coords and scale/offset to [0, 1].
		projecTexCoord.xy /= projecTexCoord.w;            
		projecTexCoord.x =  0.5f*projecTexCoord.x + 0.5f; 
		projecTexCoord.y = -0.5f*projecTexCoord.y + 0.5f;

		finalColor *= tex2D(sTexture, projecTexCoord.xy);
	}

	return finalColor;
}

technique PerPixelPointLight
{
	pass
	{
		VertexShader = compile vs_2_0 VS();
		PixelShader = compile ps_2_0 PS();
	}
}

Share this post


Link to post
Share on other sites
Advertisement
I don't see exactly what you are trying to accomplish. Perhaps if you make a new post with an explanation of what you want to achieve, then people will be able to help you with the method. You have posted a bit too much code to look through.

Are you trying to create a light shining through a textured blended polygon, where a surface on the other side of the polygon gets illuminated depending on the colors and translucency of the texture?
Kinda like the shadows of the leaves here: http://developer.amd.com/gpu/radeon/RadeonSampleCode/ProjectiveTextureMapping/Pages/default.aspx.

Share this post


Link to post
Share on other sites
What I want to do is have a source in which I can then project and image from that source down to an object. That is exactly what Frank Luna is describing in this book, however, I just do not understand that one snippet of code. What he does in his book and what I am trying to do is use a spot light to project an image down on a surface.

Such as this http://img26.imageshack.us/img26/3189/lightsourcesurface.jpg

Which should then give something like this http://img115.imageshack.us/img115/261/wantede.jpg (the skull texture skewed onto the plane).

I have a lot of code posted because that is literally all of my code. The rendering code is in the function "render" but the part I do not understand is that first code snippet.

Share this post


Link to post
Share on other sites
Quote:
Original post by simotix
What I want to do is have a source in which I can then project and image from that source down to an object. That is exactly what Frank Luna is describing in this book, however, I just do not understand that one snippet of code. What he does in his book and what I am trying to do is use a spot light to project an image down on a surface.

Such as this http://img26.imageshack.us/img26/3189/lightsourcesurface.jpg

Which should then give something like this http://img115.imageshack.us/img115/261/wantede.jpg (the skull texture skewed onto the plane).

I have a lot of code posted because that is literally all of my code. The rendering code is in the function "render" but the part I do not understand is that first code snippet.


Well if you do not want to just project a transparent picture on the screen in some pass, do the texture projection in meshes pixel shaders. You get camera world space postion, move it to object space, subtitute vector object position from the obj camera position vector, normalize new vector. you know have a direction vector with which x and y components you can sample projected texture and use the sampled value for final color multiplication. It is not axectly accurate, but it is fast and nice still. you will have to draw accurate texure for this (put 1 into not shading parts of texture, and put lesser values on shadow casting spots). Concentrate casting spots in the middle and leave a lot of space white to scale down the casting part.

Share this post


Link to post
Share on other sites
Maybe I am not explaining it correctly, but I do not understand what is going on here


D3DXMATRIX mLight;

D3DXMATRIX lightLens;
float lightFOV = D3DX_PI*0.30f;
D3DXMatrixPerspectiveFovLH(&lightLens, lightFOV, 1.0f, 1.0f, 200.0f);

D3DXMATRIX lightView;
D3DXVECTOR3 lightPosW(60.0f, 90.0f, 0.0f); // Why 60, 90, 0
D3DXVECTOR3 lightTargetW(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&lightView, &lightPosW, &lightTargetW, &lightUpW);

mLight = objectTransform*lightView*lightLens;




That is my main concern, understanding that code. I do not understand why those values were chosen, what they are doing there and how they can be defined. That is what I am looking to be answered.

Share this post


Link to post
Share on other sites
lightPosW is simply the light's position, you can set it to whatever you want. lightTargetW is the point where the light is centered on, that is the center point that the spotlight is shining at. lightUpW is a vector that is regarded as 'up' from the light's point of view. That is, if you put your camera at the light position, it can rotate around its z-axis, while still looking at the same point, and an 'up' vector is required to completely define the view matrix.

Share this post


Link to post
Share on other sites
With the above posted shader I am still getting the wrong thing and I have no clue why, does anyone know why?

Here is that it looks like now
http://img49.imageshack.us/img49/641/projectwrong.jpg

I am building my light matrix like this now


D3DXMATRIX lightLens;
float lightFOV = D3DX_PI*renderLight.fRadius;
D3DXMatrixPerspectiveFovLH(&lightLens, lightFOV, 1.0f, 1.0f, 200.0f);

D3DXMATRIX lightView;
D3DXVECTOR3 lightPosW = renderLight.vPosition;
D3DXVECTOR3 lightTargetW(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&lightView, &lightPosW, &lightTargetW, &lightUpW);

mLight = objectTransform*lightView*lightLens;
shaderEffect->SetMatrix("gLightWVP", &mLight);




All code:

#include <windows.h>
#include <iostream>
#include <ctime> //time() for random seed

#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

//Random Float Macro
#define RAND_FLOAT(min,max) (((rand()/(float)RAND_MAX)*((max)-(min)))+(min))
#define KEYDOWN(key) ((GetAsyncKeyState(key) & 0x8000) ? true : false)
#define SAFE_RELEASE(p) { if(p){ p->Release(); p = NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete [] p; p = NULL; } }

using namespace std;

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

HINSTANCE app;
HWND wnd;

struct VERTEX
{
D3DXVECTOR3 pos;
D3DXVECTOR3 normal;
float u, v;
};


struct Light
{
D3DXVECTOR3 vAmbient;
D3DXVECTOR3 vDiffuse;
D3DXVECTOR3 vSpecular;

D3DXVECTOR3 vPosition;
D3DXVECTOR3 vDirection;

float fRadius;
};

IDirect3D9 *d3d = NULL;
IDirect3DDevice9 *dev = NULL;
ID3DXFont *dxFont = NULL;

IDirect3DVertexDeclaration9 *vertexDecl=NULL;

IDirect3DVertexBuffer9 *squareBuff=NULL; // square
IDirect3DIndexBuffer9 *squareIndex=NULL;// square indices
IDirect3DTexture9 *squareTexture=NULL;

ID3DXEffect *shaderEffect;
D3DXMATRIX camProjectionMatrix;
D3DXMATRIX camViewMatrix;

Light renderLight;



//--------------------------------------------------------------------------

bool InitWindow(); // initialize window
void InitGame();
void InitDirLight();
void InitSpotLight();
void InitPointLight();
void LoopGame();
void EndGame();

void InitDX();
void Render();
void Update();
void InitDX();
void InitGeometry();
void DrawSquare();

float DegreesToRadians(float Degrees);

int WINAPI WinMain(HINSTANCE hInstance, // handle to application
HINSTANCE hPrevInstance, // handle to previous app
LPTSTR lpCmdLine, // command line string
int nCmdShow ); // show window value

LRESULT CALLBACK WndProc(HWND hWnd, // handle to window
UINT message, // incoming message
WPARAM wparam, // message info
LPARAM lparam ); // message info

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, int )
{
app = hInstance; // store application handle
InitWindow(); // init window
InitGame(); // initialize game

MSG msg; ZeroMemory( &msg, sizeof( msg ) ); // use to catch windows messages
while ( msg.message != WM_QUIT )
{

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

LoopGame(); // MAIN GAME LOOP!

}

EndGame(); // game shutdown and cleanup

UnregisterClass( "DirectXApplication", app ); // unregister window
return 0; // done
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
// attempt to handle
switch ( message )
{
case ( WM_DESTROY ): { PostQuitMessage( 0 ); }
break;
}
// pass to default handler
return DefWindowProc( hWnd, message, wParam, lParam );
}

bool InitWindow( void )
{
WNDCLASSEX wndClass;

// register a new type of window
ZeroMemory( &wndClass, sizeof( wndClass ) );
wndClass.cbSize = sizeof( WNDCLASSEX ); // size of window structure
wndClass.lpfnWndProc = ( WNDPROC )WndProc; // message callback
wndClass.lpszClassName = "DirectXApplication"; // class name
wndClass.hInstance = app; // handle to application
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); // default cursor
wndClass.hbrBackground = ( HBRUSH )( COLOR_WINDOWFRAME ); // background brush
RegisterClassEx( &wndClass );

// create window of registered type
wnd = CreateWindow(
"DirectXApplication", "DirectX Application", // class name, window title
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, CW_USEDEFAULT, // x & y coordinates
SCREEN_WIDTH, SCREEN_HEIGHT, // width & height of window
NULL, NULL, // parent window & menu
app, // handle to application
NULL );

// take a guess
ShowWindow( wnd, SW_SHOW ); // technically should be nCmdShow

return true;
}

void InitGame()
{
srand(unsigned int(time(0))); //randomize!

InitDX();
InitGeometry();

// InitCamera
D3DXMatrixIdentity(&camViewMatrix);
D3DXMatrixIdentity(&camProjectionMatrix);

camViewMatrix._41 = 0.0f; camViewMatrix._42 = 0.0f; camViewMatrix._43 = -4.0f;
D3DXMatrixPerspectiveFovLH(&camProjectionMatrix, D3DX_PI/3, float(SCREEN_WIDTH)/SCREEN_HEIGHT, 0.1f, 500.0f);

// init Font
D3DXCreateFont(dev, 32, 0, FW_NORMAL, NULL, false,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
"Ariel", &dxFont);

// Load the floar texture
D3DXCreateTextureFromFile(dev, "testTexture.dds", &squareTexture);

// init shader
LPD3DXBUFFER pBufferErrors = NULL;
HRESULT hResult = D3DXCreateEffectFromFile(dev, "ProjectiveTexture.fx",
NULL, NULL, 0, NULL, &shaderEffect, &pBufferErrors );

renderLight.vAmbient = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
renderLight.vDiffuse = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
renderLight.vSpecular = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
renderLight.fRadius = 4.0f;
renderLight.vPosition = D3DXVECTOR3(0.0f, 2.0f, 0.0f);
}

void LoopGame()
{
Update();
Render();
}

void EndGame()
{
SAFE_RELEASE(squareBuff); squareBuff=0;
SAFE_RELEASE(vertexDecl); vertexDecl=0;
SAFE_RELEASE(squareTexture); squareTexture=0;

//--------------------
dxFont->Release(); dxFont=0;
dev->Release(); dev=0;
d3d->Release(); d3d=0;
}

void InitDX() //Initialize D3D object
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

d3dpp.hDeviceWindow = wnd;
d3dpp.Windowed = true;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //no VSync
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

// add for 3D
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

d3d->CreateDevice(0, D3DDEVTYPE_HAL, wnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &dev);

dev->SetRenderState(D3DRS_ZENABLE, true);
dev->SetRenderState(D3DRS_AMBIENT, false);
dev->SetRenderState(D3DRS_LIGHTING, false);
}

void Render()
{
dev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0,0,100), 1, 0);
dev->BeginScene();

// Start the effect
shaderEffect->SetTechnique("PerPixelPointLight");
unsigned int unPasses;
shaderEffect->Begin(&unPasses, 0);

// Set light varaibles
shaderEffect->SetFloatArray("light.pos", renderLight.vPosition, 3);
shaderEffect->SetFloatArray("light.ambient", renderLight.vAmbient, 4);
shaderEffect->SetFloatArray("light.diffuse", renderLight.vDiffuse, 4);
shaderEffect->SetFloatArray("light.specular", renderLight.vSpecular, 4);
shaderEffect->SetFloat("light.radius", renderLight.fRadius);

// Set Matrial variables
float ones[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
shaderEffect->SetFloatArray("material.ambient", ones, 4);
shaderEffect->SetFloatArray("material.diffuse", ones, 4);
shaderEffect->SetFloatArray("material.specular", ones, 4);
shaderEffect->SetFloat("material.shininess", 2.0f);

// Set the texture
shaderEffect->SetTexture("tCurrentTexture", squareTexture);

// Set the matricies
{
D3DXMATRIX objectTransform; // generic transformation matrix
D3DXMatrixIdentity(&objectTransform); // world transform for square
D3DXMatrixRotationX(&objectTransform, DegreesToRadians(90.0f)); // Rotate 90 degrees on X, to make it look like it is laying down
objectTransform._41 = -2.0f; objectTransform._42 = -1.0f; objectTransform._43 = -2.0f; // Center the plane in the view
shaderEffect->SetMatrix("worldMatrix", &objectTransform);

D3DXMATRIX viewMatrixForRender;
{
D3DXMATRIX _mRotation(camViewMatrix);
_mRotation._41 = _mRotation._42 = _mRotation._43 = 0;
D3DXMatrixTranspose(&_mRotation, &_mRotation);

D3DXMatrixIdentity(&viewMatrixForRender);
viewMatrixForRender._41 = -(camViewMatrix._41);
viewMatrixForRender._42 = -(camViewMatrix._42);
viewMatrixForRender._43 = -(camViewMatrix._43);
D3DXMatrixMultiply(&viewMatrixForRender, &viewMatrixForRender, &_mRotation);
}

D3DXMATRIX mViewProj = objectTransform * viewMatrixForRender * camProjectionMatrix;
shaderEffect->SetMatrix("worldViewProjectionMatrix", &mViewProj);

D3DXMATRIX mLight;

D3DXMATRIX lightLens;
float lightFOV = D3DX_PI*renderLight.fRadius;
D3DXMatrixPerspectiveFovLH(&lightLens, lightFOV, 1.0f, 1.0f, 200.0f);

D3DXMATRIX lightView;
D3DXVECTOR3 lightPosW = renderLight.vPosition;
D3DXVECTOR3 lightTargetW(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 lightUpW(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&lightView, &lightPosW, &lightTargetW, &lightUpW);

mLight = objectTransform*lightView*lightLens;
shaderEffect->SetMatrix("gLightWVP", &mLight);
}

shaderEffect->CommitChanges();

shaderEffect->BeginPass(0);
DrawSquare();
shaderEffect->EndPass();

shaderEffect->End();

dev->EndScene();
dev->Present(0,0,0,0);
}

void Update()
{

}

void InitGeometry()
{
D3DVERTEXELEMENT9 decl[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
dev->CreateVertexDeclaration(decl, &vertexDecl);

//--------------------------------------------------
// square
VERTEX sqverts[4];
sqverts[0].pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // top left
sqverts[1].pos = D3DXVECTOR3(0.0f, 5.0f, 0.0f); // top left
sqverts[2].pos = D3DXVECTOR3(5.0f, 5.0f, 0.0f); // top right
sqverts[3].pos = D3DXVECTOR3(5.0f, 0.0f, 0.0f); // bottom right

sqverts[0].u = 0;
sqverts[0].v = 1;
sqverts[1].u = 0;
sqverts[1].v = 0;
sqverts[2].u = 1;
sqverts[2].v = 0;
sqverts[3].u = 1;
sqverts[3].v = 1;

sqverts[0].normal = D3DXVECTOR3(0,1,0);
sqverts[1].normal = D3DXVECTOR3(0,1,0);
sqverts[2].normal = D3DXVECTOR3(0,1,0);
sqverts[3].normal = D3DXVECTOR3(0,1,0);

void* pBuffer;

dev->CreateVertexBuffer(4*sizeof(VERTEX),0,0, D3DPOOL_DEFAULT, &squareBuff,0);

squareBuff->Lock(0,0, &pBuffer, 0);
memcpy(pBuffer, sqverts, 4*sizeof(VERTEX));
squareBuff->Unlock();

//////////// inidicies
WORD indicies[6];
indicies[0] = 0; indicies[1] = 1; indicies[2] = 2;
indicies[3] = 0; indicies[4] = 2; indicies[5] = 3;

dev->CreateIndexBuffer(6*sizeof(WORD),0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &squareIndex, 0);

squareIndex->Lock(0,0, &pBuffer, 0);
memcpy(pBuffer, indicies, 6*sizeof(WORD));
squareIndex->Unlock();
}

void DrawSquare() // draw square
{
dev->SetStreamSource(0, squareBuff, 0, sizeof(VERTEX));
dev->SetIndices(squareIndex);
dev->SetVertexDeclaration(vertexDecl);

dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
}

float DegreesToRadians(float Degrees)
{
float DegreesToRadians = (float)(Degrees * (3.14159265f / 180));
return DegreesToRadians;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by simotix
Maybe I am not explaining it correctly, but I do not understand what is going on here

*** Source Snippet Removed ***

That is my main concern, understanding that code. I do not understand why those values were chosen, what they are doing there and how they can be defined. That is what I am looking to be answered.


Those values are simply the position of the "light" that is projecting the texture. Try to think of projective texturing as if it were a film projector projecting a film onto a canvas. You need to specify the position of this projector, the direction it will project images, and its field of view.

Theres no reason why you can't change those values (60,90,0), they simply define the projector to be 60 units to the right and 90 units up from the origin, and the origin is the position the projector is facing to place the projected image.

One thing to note, make sure "objectTransform" is the identity matrix.

Share this post


Link to post
Share on other sites
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!