Jump to content
  • Advertisement
Sign in to follow this  
justcallmedrago

Issues with closing app window with Escape

This topic is 4082 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

For some reason, when I press escape, the window never closes, but the teapot on the screen freezes like the app tried to quit. Escape used to close it when showing single triangles. When I finally get the window closed, VC++ shows the error message:
Quote:
Unhandled exception at 0x00411d2f in Game Engine.exe: 0xC0000005: Access violation reading location 0x00000000.
There aren't any warnings or errors when the project is built. Code:
// Game Engine.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
//#include "Game Engine.h"

// 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
//LPDIRECT3DVERTEXBUFFER9 t_buffer = NULL;    // the pointer to the vertex buffer
//LPDIRECT3DVERTEXBUFFER9 t2_buffer = NULL;    // the pointer to the vertex buffer
//LPDIRECT3DVERTEXBUFFER9 t3_buffer = NULL;    // the pointer to the vertex buffer
LPDIRECT3DSURFACE9 z_buffer = NULL;    // the pointer to the z-buffer


// global variables
LPD3DXMESH meshSpaceship;
DWORD numMaterials;

D3DMATERIAL9* material;    // define the material object

// 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
void init_light(void);

struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)

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

    // 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);
			break;
		}

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

    // clean up DirectX and COM
    cleanD3D();

    return (INT)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 Hypercraft
	init_light();

    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn off the 3D lighting
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

    return;
}


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

    d3ddev->BeginScene();

    // select which vertex format we are using
    d3ddev->SetFVF(CUSTOMFVF);

	static float index = 0.0f; index+=0.03f; // an ever-increasing float value
    
	// 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
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to 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
                               1000.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection

    // set the world transform
    D3DXMATRIX mat;    // a matrix to store the rotation for each triangle
    D3DXMatrixRotationX(&mat, index);    // the rotation matrix
    d3ddev->SetTransform(D3DTS_WORLD, &(mat));    // set the world transform

	meshSpaceship->DrawSubset(0);

    d3ddev->EndScene(); 

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

    return;
}


// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
	meshSpaceship->Release();    // close and release the spaceship mesh
    t_buffer->Release();    // close and release the vertex buffer
    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, &meshSpaceship, NULL);    // create the teapot
	// local variable (in the init_graphics() function)

    return;
}

// this is the function that sets up the lights and materials
void init_light(void)
{
    D3DLIGHT9 light;    // create the light struct
    D3DMATERIAL9 material;    // create the material struct

    ZeroMemory(&light, sizeof(light));    // clear out the struct for use
    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    light.Diffuse.r = 0.5f;    // .5 red
    light.Diffuse.g = 0.5f;    // .5 green
    light.Diffuse.b = 0.5f;    // .5 blue
    light.Diffuse.a = 1.0f;    // full alpha (we'll get to that soon)

    D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f};    // the direction of the light
    light.Direction = vecDirection;    // set the direction

    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0
    d3ddev->LightEnable(0, TRUE);    // turn on light #0

    ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
    material.Diffuse.r = material.Ambient.r = 1.0f;    // set the material to full red
    material.Diffuse.g = material.Ambient.g = 1.0f;    // set the material to full green
    material.Diffuse.b = material.Ambient.b = 1.0f;    // set the material to full blue
    material.Diffuse.a = material.Ambient.a = 1.0f;    // set the material to full alpha

    d3ddev->SetMaterial(&material);    // set the globably-used material to &material

    return;
}

Share this post


Link to post
Share on other sites
Advertisement
Your observed results suggest you're not handling your windows messages correctly.

Something look a bit odd about how you're translating messages, catching and then posting messages again - and you're not tidying up Win32 properly at the end, only D3D.

DXUT can be a bit intimidating, but it's the textbook for how to handle your application's interaction with Windows and other apps. See how it structures its loops.

Also, for a simpler answer trying looking at the tutorials in the D3D9 sample folder - they work on pressing escape and function as expected...

hth
Jack

Share this post


Link to post
Share on other sites
Hey there, may be its still rendering when you press escape
try this


// check the 'escape' key
if(KEY_DOWN(VK_ESCAPE))
{
PostMessage(hWnd, WM_DESTROY, 0, 0);
break;
}
else
render_frame();

Share this post


Link to post
Share on other sites
I can't see where "t_buffer" is defined and initialised... Plus, on cleanD3D() you should be checking for != NULL before trying to release any of those objects - that'll easily cause an access violation if you try and Release() an empty object.

You seem to be missing a few other bits - the code you've commented out looks like it probably has useful information, including the "t_buffer" initialisation, and the Teapot init code! Is there a reason for this?

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!