Sign in to follow this  
battle_bright

Touble with an effect file...

Recommended Posts

I'm trying to run a DirectX program with an effect file in Visual C++ Express 2008, but when I run the program all I get is a black screen, and I have to use the Windows Task Manager to exit Visual C++ because the program has stopped responding. The program works fine without the effect file. That is to say if I use DirectX for lighting and transformation effects I have no problems at all. Does anyone know what might be causing this?

Share this post


Link to post
Share on other sites
Ok, here's the code for the effect file. It's called simple.fx

//
// Simple Lighting Model
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: This effect file works with EffectEdit.
//

string XFile = "tiger.x"; // model
int BCLR = 0xff202080; // background

// light direction (view space)
float3 lightDir < string UIDirectional = "Light Direction"; > = {0.577, -0.577, 0.577};

// light intensity
float4 I_a = { 0.1f, 0.1f, 0.1f, 1.0f }; // ambient
float4 I_d = { 1.0f, 1.0f, 1.0f, 1.0f }; // diffuse
float4 I_s = { 1.0f, 1.0f, 1.0f, 1.0f }; // specular

// material reflectivity
float4 k_a : MATERIALAMBIENT = { 1.0f, 1.0f, 1.0f, 1.0f }; // ambient
float4 k_d : MATERIALDIFFUSE = { 1.0f, 1.0f, 1.0f, 1.0f }; // diffuse
float4 k_s : MATERIALSPECULAR= { 1.0f, 1.0f, 1.0f, 1.0f }; // specular
int n : MATERIALPOWER = 32; // power

// texture
texture Tex0 < string name = "tiger.bmp"; >;

// transformations
float4x4 World : WORLD;
float4x4 View : VIEW;
float4x4 Projection : PROJECTION;

struct VS_OUTPUT
{
float4 Pos : POSITION;
float4 Diff : COLOR0;
float4 Spec : COLOR1;
float2 Tex : TEXCOORD0;
};

VS_OUTPUT VS(
float3 Pos : POSITION,
float3 Norm : NORMAL,
float2 Tex : TEXCOORD0)
{
VS_OUTPUT Out = (VS_OUTPUT)0;

float3 L = -lightDir;

float4x4 WorldView = mul(World, View);

float3 P = mul(float4(Pos, 1), (float4x3)WorldView); // position (view space)
float3 N = normalize(mul(Norm, (float3x3)WorldView)); // normal (view space)

float3 R = normalize(2 * dot(N, L) * N - L); // reflection vector (view space)
float3 V = -normalize(P); // view direction (view space)

Out.Pos = mul(float4(P, 1), Projection); // position (projected)
Out.Diff = I_a * k_a + I_d * k_d * max(0, dot(N, L)); // diffuse + ambient
Out.Spec = I_s * k_s * pow(max(0, dot(R, V)), n/4); // specular
Out.Tex = Tex;

return Out;
}

sampler Sampler = sampler_state
{
Texture = (Tex0);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};

float4 PS(
float4 Diff : COLOR0,
float4 Spec : COLOR1,
float2 Tex : TEXCOORD0) : COLOR
{
return tex2D(Sampler, Tex) * Diff + Spec;
}

technique TNoShader
{
pass P0
{
// transforms
WorldTransform[0] = (World);
ViewTransform = (View);
ProjectionTransform = (Projection);

// material
MaterialAmbient = (k_a);
MaterialDiffuse = (k_d);
MaterialSpecular = (k_s);
MaterialPower = (n);

// lighting
LightType[0] = DIRECTIONAL;
LightAmbient[0] = (I_a);
LightDiffuse[0] = (I_d);
LightSpecular[0] = (I_s);
LightDirection[0] = (lightDir);
LightRange[0] = 100000.0f;

LightEnable[0] = TRUE;
Lighting = TRUE;
SpecularEnable = TRUE;

// samplers
Sampler[0] = (Sampler);

// texture stages
ColorOp[0] = MODULATE;
ColorArg1[0] = TEXTURE;
ColorArg2[0] = DIFFUSE;
AlphaOp[0] = MODULATE;
AlphaArg1[0] = TEXTURE;
AlphaArg2[0] = DIFFUSE;

ColorOp[1] = DISABLE;
AlphaOp[1] = DISABLE;

// shaders
VertexShader = NULL;
PixelShader = NULL;
}
}

technique TVertexShaderOnly
{
pass P0
{
// lighting
Lighting = FALSE;
SpecularEnable = TRUE;

// samplers
Sampler[0] = (Sampler);

// texture stages
ColorOp[0] = MODULATE;
ColorArg1[0] = TEXTURE;
ColorArg2[0] = DIFFUSE;
AlphaOp[0] = MODULATE;
AlphaArg1[0] = TEXTURE;
AlphaArg2[0] = DIFFUSE;

ColorOp[1] = DISABLE;
AlphaOp[1] = DISABLE;

// shaders
VertexShader = compile vs_1_1 VS();
PixelShader = NULL;
}
}

technique TVertexAndPixelShader
{
pass P0
{
// shaders
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_1_1 PS();
}
}


//========================================================================
//
//
//========================================================================

Here is the C++ code for the program:

// 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 and keyboard macros
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#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 files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

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

// mesh declarations
LPD3DXMESH meshTeapot; // define the mesh pointer

// effect declarations
LPD3DXEFFECT effect; // define the effect pointer
D3DXHANDLE technique; // define the handle for the best technique

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

// 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 = (WNDPROC)WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program",
WS_EX_TOPMOST | WS_POPUP, 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)
{
DWORD starting_point = GetTickCount();

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}

render_frame();

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

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)
{
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 = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

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

LPD3DXBUFFER errorlog; // for storing errors

// load the effect file
D3DXCreateEffectFromFile(d3ddev, L"simple.fx", 0, 0, 0, 0, &effect, &errorlog);

// find the best technique
effect->FindNextValidTechnique(NULL, &technique);

return;
}


// this is the function used to render a single frame
void render_frame(void)
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3ddev->BeginScene();

// set the view transform
D3DXMATRIX matView; // the view transform matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 3.0f, 6.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
effect->SetMatrix("View", &matView);

// set the projection transform
D3DXMATRIX matProjection; // the projection transform matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
effect->SetMatrix("Projection", &matProjection);

// set the world transform
static float index = 0.0f; index+=0.03f; // an ever-increasing float value
D3DXMATRIX matRotateY; // a matrix to store the rotation for each triangle
D3DXMatrixRotationY(&matRotateY, index); // the rotation matrix
effect->SetMatrix("World", &matRotateY);


effect->Begin(NULL, NULL); // begin using the effect
effect->BeginPass(0); // begin the pass

// render whatever
meshTeapot->DrawSubset(0);

effect->EndPass(); // end the pass
effect->End(); // end the effect

d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);

return;
}


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

return;
}


// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
D3DXCreateTeapot(d3ddev, &meshTeapot, NULL); // create the teapot

return;
}



[Edited by - battle_bright on August 12, 2008 1:54:07 PM]

Share this post


Link to post
Share on other sites
First, please edit your post and place the code between [ source] and [ /source] (but without the spaces after the [).

Second, I'm not sure what the problem is, but the first thing that jumps out is that you don't do any error checking. Specifically, you're not checking the return values of the D3D functions, you're not looking at the errorlog for the effect, etc.

Third, turn on the debug runtimes and see if you get any errors or warnings.

Fourth, step through your program with the debugger and look for errors or "suspicious" behavior.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
First, please edit your post and place the code between [ source] and [ /source] (but without the spaces after the [).

Second, I'm not sure what the problem is, but the first thing that jumps out is that you don't do any error checking. Specifically, you're not checking the return values of the D3D functions, you're not looking at the errorlog for the effect, etc.

Third, turn on the debug runtimes and see if you get any errors or warnings.

Fourth, step through your program with the debugger and look for errors or "suspicious" behavior.


Thanks for all your help by the way. I appreciate your patience.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this