Skip to main content
GameDev.net gamedev.net
🔒 Locked

D3DXCreateEffectFromFile() problem ( new question inside!)

Started by Tutukun Aug 29, 2006 at 2:58 PM 5 replies 2k views
Original Post
Tutukun
Tutukun
Hi! I'm having a problem with D3DXCreateEffectFromFile(). After runnig the program, it gives me this error: Unhandled exception at 0x00411adc in HLSL_DIFFUSE.exe: 0xC0000005: Access violation reading location 0x00000000. Maybe there is something wrong with the input parameters. The following is my code. ALl the bold lines r those has something to do with DX. The rest are just normal Windows stuffs. Thanks in advance :) Please read my next post for my new question

// include the basic windows header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment (lib,"d3d9.lib")
#pragma comment (lib,"d3dx9.lib")
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }
struct CUSTOMVERTEX
{
	FLOAT x,y,z,rhw;
	DWORD color;
};
LPDIRECT3DVERTEXBUFFER9 t_buffer=NULL;
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPD3DXEFFECT m_pEffect=NULL;

HRESULT loadEffect(const char* filename);
void init_graphics(void);
void initD3D(HWND hWnd);
void cleanD3D(void);
void render_frame(void);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    // the handle for the window, filled by a function
    HWND hWnd;
    // this struct holds information for the window class
    WNDCLASSEX wc;

    // clear out the window class for use
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    // fill in the struct with the needed information
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = L"WindowClass1";

    // register the window class
    RegisterClassEx(&wc);

    // create the window and use the result as the handle
    hWnd = CreateWindowEx(NULL,
                          L"WindowClass1",    // name of the window class
                          L"Our First Windowed Program",    // title of the window
                          WS_OVERLAPPEDWINDOW,    // window style
                          300,    // x-position of the window
                          300,    // y-position of the window
                          500,    // width of the window
                          400,    // height of the window
                          NULL,    // we have no parent window, NULL
                          NULL,    // we aren't using menus, NULL
                          hInstance,    // application handle
                          NULL);    // used with multiple windows, NULL

    // display the window on the screen
    ShowWindow(hWnd, nCmdShow);

    // enter the main loop:
	initD3D(hWnd);
    // this struct holds Windows event messages
    MSG msg;

    // Enter the infinite message loop
    while(TRUE)
    {
		DWORD starting_point = GetTickCount();
        // Check to see if any messages are waiting in the queue
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // If the message is WM_QUIT, exit the while loop
            if (msg.message == WM_QUIT)
                break;

            // translate keystroke messages into the right format
            TranslateMessage(&msg);

            // send the message to the WindowProc function
            DispatchMessage(&msg);
        }

        // Run game code here
        // ...
        // ...
		
		render_frame();
		if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);

        while ((GetTickCount() - starting_point) < 25);
    }

    // return this part of the WM_QUIT message to Windows
	cleanD3D();
    return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // sort through and find what code to run for the message given
    switch(message)
    {
        // this message is read when the window is closed
        case WM_DESTROY:
            {
                // close the application entirely
                PostQuitMessage(0);
                return 0;
            } break;
    }

    // Handle any messages the switch statement didn't
    return DefWindowProc (hWnd, message, wParam, lParam);
}
void init_graphics(void){
CUSTOMVERTEX vertices[] =
{
	{320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0,0,255)},
	{520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0,255,0)},
	{120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255,0,0)}
};
d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
						   0,
						   CUSTOMFVF,
						   D3DPOOL_MANAGED,
						   &t_buffer,
						   NULL);
VOID* pVoid;
t_buffer->Lock(0,0,(void**)&pVoid,0);
memcpy(pVoid, vertices, sizeof(vertices));
t_buffer->Unlock();
return;
}

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;

	d3d->CreateDevice(D3DADAPTER_DEFAULT,
						D3DDEVTYPE_HAL,
						hWnd,
						D3DCREATE_HARDWARE_VERTEXPROCESSING,
						&d3dpp,
						&d3ddev);
	loadEffect("diffuse.fx");
	init_graphics();
	return;
}

void render_frame(void){
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
	m_pEffect->SetTechnique("simple"); //<<<--- error?
	d3ddev->BeginScene();
		m_pEffect->Begin(0,0);
		m_pEffect->BeginPass(0);
		d3ddev->SetFVF(CUSTOMFVF);
		d3ddev->SetStreamSource(0,t_buffer,0,sizeof(CUSTOMVERTEX));
		d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
		m_pEffect->EndPass();
		m_pEffect->End();
	d3ddev->EndScene();
	d3ddev->Present(NULL,NULL,NULL,NULL);	
	return;
}

void cleanD3D(void){
	d3ddev->Release();
	d3d->Release();
	t_buffer->Release();
	return;
}

HRESULT loadEffect(const char* filename){
	LPD3DXBUFFER pBufferErrors = NULL;
	HRESULT result = D3DXCreateEffectFromFile(d3ddev,(LPCWSTR)filename,NULL,NULL,0,NULL, &m_pEffect,&pBufferErrors);  //<<<---error?
	if(FAILED(result)){
		SAFE_RELEASE(pBufferErrors);
		return result;
	}
	return D3D_OK;
}
[Edited by - Tutukun on August 30, 2006 12:41:34 AM]
Enselic
Enselic
Are you sure that it is D3DXCreateEffectFromFile() that is the problem? If so, do you pass values fitting with the docs? The error you get is because you the code is trying to dereference a NULL pointer. Use a debugger to find out exactly where.

As a note, [source][/source] is generally preferred when you have this quite large mass of code.
Demirug
Demirug
You are compiling this as Unicode application but use single byte character names for loading the effect. Casting a const char* to LPCWSTR will not convert it to Unicode.
Tutukun
Tutukun
Quote:
Original post by Demirug
You are compiling this as Unicode application but use single byte character names for loading the effect. Casting a const char* to LPCWSTR will not convert it to Unicode.

thanks, I change char* to LPCTSTR and it works :).

New Questions: I cant apply the effect file to me triangle. The HLSL script works since i checked it with FXcomposer, so it must be my loading/ rendering code. Please tell me what i did wrong. Thanks

HRESULT loadEffect(const LPCTSTR filename){	LPD3DXBUFFER pBufferErrors = NULL;	HRESULT result = D3DXCreateEffectFromFile(d3ddev,(LPCTSTR)filename,NULL,NULL,0,NULL, &m_pEffect,&pBufferErrors);	if(FAILED(result)){		SAFE_RELEASE(pBufferErrors);		return result;	}	return D3D_OK;}void render_frame(void){	UINT passes,ipasses;	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);	m_pEffect->SetTechnique("simple");	d3ddev->BeginScene();		d3ddev->SetFVF(CUSTOMFVF);		m_pEffect->Begin(&passes,0);		d3ddev->SetStreamSource(0,t_buffer,0,sizeof(CUSTOMVERTEX));		for(ipasses=0; ipasses < passes; ipasses++)		{			m_pEffect->BeginPass(ipasses);									d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);			m_pEffect->EndPass();		}		m_pEffect->End();	d3ddev->EndScene();	d3ddev->Present(NULL,NULL,NULL,NULL);		return;}


[Edited by - Tutukun on August 30, 2006 12:35:24 AM]
circlesoft
circlesoft
A thing that jumps out at me is that there are many calls that could fail in your render_frame() function, but yet you aren't checking their return values. It's quite possible that a function could be failing in there, but you don't know about it.
shiftybits
shiftybits
A couple other things that may help:

I see that you are using a DWORD to store your vert colors. Try using a regular D3DCOLOR macro, instead of D3DCOLOR_XRGB. I have experienced problems when using D3DCOLOR_XRGB wih effect files in the past. Also, try calling m_pEffect->CommitChanges() after you set the technique to use for your effect.
adelamro
adelamro
If, by HLSL script, you mean a script used in a "script" annotation to some technique or pass, they are not directly supported by DirectX. These scripts are used extensively in the shaders that come with FX Composer, but they are not part of the DirectX effect framework. You will need to interpret such scripts by yourself.
I live in Palestine, but it's not in the country list, so I picked Zimbabwe.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.