A beginner and some shader code.

Started by
5 comments, last by littlekid 16 years, 1 month ago
As lame as this sounds(this is from a thread I made about 1 week ago), this is my friends membership to a direct x site. It has some code on it and one was not working. I am not quite sure why though. The code compiles fine, and the shader looks just like other shader tutorials but it just doesn't load it. I tried the fxc command prompt compile system and it said I was missing a 'main' statement. I wasn't quite sure if this meant a literal typed in main statement or a statement that equates to main. No other tutorial I found used 'main'(yes I know there are no ' in the typing of it) in there code and they compiled fine and worked (Frank luna's book, all xna tutorials I have seen,ect), but also said it was missing a 'main' statement. When i changed one of the statements to main , it worked and loaded the shader but this seemed odd because no other book or tutorial I have looked through did this. This also poses a problem when Pixel and vertex shaders are being used in one file(I replaced vs with main and it worked, the code will be on the bottom). So is it the source code or the shader that is the problem? I know it would be smart to email the guy but he hasn't responded to my newest message in 10 days. In the course of 2 months I got 1 response. I also find it odd that Frank luna's books code compiled and launched fine with shaders while this one doesn't. This is what happens exactly. I debug and its says no errors and then I get a black screen(Where the teapot is suppose to go) and then just the loading icon. What am I doing wrong? Code(shader)

 float4x4 World;
float4x4 View;
float4x4 Projection;

struct VertexOut
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};

VertexOut VertexShader(float4 Pos : POSITION)
{
    VertexOut Vert = (VertexOut)0;
    float4x4 Transform;

    Transform = mul(World, View);
    Transform = mul(Transform, Projection);
    Vert.Pos = mul(Pos, Transform);

    Vert.Color = float4(1, 1, 1, 1);

    return Vert;
}

technique FirstTechnique
{
    pass FirstPass
    {
        Lighting = FALSE;
        ZEnable = TRUE;

        VertexShader = compile vs_2_0 VertexShader();
    }
}
[source/]

c++ 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 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"dxtshader.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;
}
[source/]

Any advice?

thanks

[Edited by - mysockshurt on March 1, 2008 2:33:27 PM]
Advertisement
What debugging have you tried that doesn't seem to work?

Do you get any error returns from your function calls?

D3DX function calls usually return an HRESULT. It doesn't appear that you have any error checking in your code. You should check return values to ensure you've made a valid call and get a valid result.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I copied your shader code and try running fxc with it. It gives the error:
error X3000: syntax error: unexpected token 'VertexShader'.

I think you can't name your VertexShader as VertexShader. Changing it to something like:
VertexOut vs_vertexshader(float4 Pos : POSITION)
seems to allow fxc to compile.

My fxc compile settings are: /T fx_2_0 /Fo

Hopes this helps
I tried what you said and still it compiles in vc++ and still I get the dreaded loading circle. When I put it in fxc I got 'main' entry point not found. This time when I put in main in place I still got the loading circle. This is really bothering me, or do I need to change a setting? When I use frank luna's pond water example it compiles perfectly and fxc also says its lacking a 'main'.
Any other idea?
What settings are you using for fxc? I am able to compile the code in fxc once I change the VertexShader Function name to something else. Here is the following shader code that compiled sucessfully on my fxc.

float4x4 World;float4x4 View;float4x4 Projection;struct VertexOut{    float4 Pos : POSITION;    float4 Color : COLOR;};VertexOut vs_myshader(float4 Pos : POSITION){    VertexOut Vert = (VertexOut)0;    float4x4 Transform;    Transform = mul(World, View);    Transform = mul(Transform, Projection);    Vert.Pos = mul(Pos, Transform);    Vert.Color = float4(1, 1, 1, 1);    return Vert;}technique FirstTechnique{    pass FirstPass    {        Lighting = FALSE;        ZEnable = TRUE;        VertexShader = compile vs_2_0 vs_myshader();    }}


Hope it helps
It still doesn't load the shader. I am using the default settings but I am trying to change it. The msdn instructions are a little cryptic for me. Is this the cause of it not working? Is there a setting in vc++ I should change? Is there another example of dx code like this to compare. How can I change the settings?Its odd because when I try the shader code in xna It works.

Thanks
You may check to see if the DX functions are not failing.

For example:
if (FAILED(effect->Begin())) Output(L"Failed to start effect");

Doing this can help you to check if any DX calls are failing.

A sidenote, you can merge your clear call to a single one:

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

to

d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

This topic is closed to new replies.

Advertisement