• Advertisement
Sign in to follow this  

Main Loop Issues

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

Although this is Direct3d, I put it in this forum because I'm having problems with the simple main loop. I can never get the main loop right in windows programs. I have it lexically and grammatically correct, but at runtime it starts up and becomes blank. I believe I am getting something mixed up here. I am under the assumption that a window is blank window is supposed to show up, but instead the window flashes briefly and then goes away. The problem comes when I try to get my application's main loop to work with the WinMain's loop. I'm quite sure the problems are in the loops; can you help me? Renderer.h
#pragma once
#include <d3d9.h>
#include <windows.h>

class Renderer
{
public:
	//Fields
	IDirect3D9 *D3D;
	D3DFORMAT format;
	D3DPRESENT_PARAMETERS pp;
	IDirect3DDevice9 *p_device;
	HRESULT hr;
	bool isFullscreen;
	bool isRunning;
	//Constructor & Destructor
	Renderer(HWND hwnd);
	~Renderer();
	//Functions
	HRESULT Render();
	HRESULT Run();
};

Renderer.cpp
#include <windows.h>
#include "Renderer.h"
#include <d3d9.h>

Renderer::Renderer(HWND hwnd)
{
	isFullscreen = false;
	D3D = Direct3DCreate9(D3D_SDK_VERSION);
	format=D3DFMT_R5G6B5;
	ZeroMemory(&pp,sizeof(D3DPRESENT_PARAMETERS));
	   pp.BackBufferCount= 1;  //We only need a single back buffer
	pp.MultiSampleType=D3DMULTISAMPLE_NONE; //No multi-sampling
	pp.MultiSampleQuality=0;                //No multi-sampling
	pp.SwapEffect = D3DSWAPEFFECT_DISCARD;  // Throw away previous frames, we don't need them
	pp.hDeviceWindow=hwnd;  //This is our main (and only) window
	pp.Flags=0;            //No flags to set
	pp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; //Default Refresh Rate
	pp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;   //Default Presentation rate
	pp.BackBufferFormat=format;      //Display format
	pp.EnableAutoDepthStencil=FALSE; //No depth/stencil buffer	
	pp.Windowed          = isFullscreen;

	hr=D3D->CreateDevice(D3DADAPTER_DEFAULT, //The default adapter, on a multi-monitor system
                                              //there can be more than one.
                          D3DDEVTYPE_HAL, //Use hardware acceleration rather than the software renderer
                          //Our Window
                          hwnd,
                          //Process vertices in software. This is slower than in hardware,
                          //But will work on all graphics cards.
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          //Our D3DPRESENT_PARAMETERS structure, so it knows what we want to build
                          &pp,
                          //This will be set to point to the new device
                          &p_device);
}
Renderer::~Renderer()
{
	if(D3D){
		D3D->Release();
		D3D=NULL;
	}
}
HRESULT Renderer::Render()
{
	HRESULT hr = NULL;
	//Do nothing, for now.
	return hr;
}
HRESULT Renderer::Run()
{
	HRESULT hr;
	MSG msg;
	while(isRunning)
	{
		while(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		hr=Render();   
	}
	return hr;
}

window.cpp
#include <windows.h>
#include "Renderer.h"
HWND hwnd;
const char g_szClassName[] = "myWindowClass";

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        /*case WM_LBUTTONDOWN:
        {
            char szFileName[MAX_PATH];
            HINSTANCE hInstance = GetModuleHandle(NULL);

            GetModuleFileName(hInstance, szFileName, MAX_PATH);
            MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
        }
		*/
        break;
		case WM_KEYDOWN:
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    MSG Msg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "Direct3d",
        WS_POPUP | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, 
		GetSystemMetrics(SM_CXSCREEN),
		GetSystemMetrics(SM_CYSCREEN),
		//800,
		//600,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
	//Call D3D Stuff here
	Renderer *renderer = new Renderer(hwnd);
	renderer->Run();
	//End call

    return Msg.wParam;
}

Share this post


Link to post
Share on other sites
Advertisement
You know what - I don't see isRunning being initialised anywhere in that code. In which case it will, I believe, default to 0, or false. Hence it immediately exits Renderer::Run().

Jim.

Share this post


Link to post
Share on other sites
In window.cpp, you're missing a 'break;' in your switch statement after the 'WM_KEYDOWN' case. The WM_CLOSE case follows, and as a result, pressing any key will immediately destroy your window.

Share this post


Link to post
Share on other sites
I intended the WM_KEYDOWN being bound to the exit of the program. Thus, I could exit without doing Alt-F4.

Share this post


Link to post
Share on other sites
JimPrice is on the right track, isRunning isn't being initialized, so in debug it'll be probably true due to begin filled with debug value (0xcdcdcdcd?).

In release it'll be random, one time true, another time false.

Set it to true in the constructor of the renderer. Also, since you aren't setting it to false anywhere to leave the app, your Run method will never be left.

ALSO, remove the break that's above WM_KEYDOWN.

If it compiles like this, the switch will probably break at every possibility and return 0, thus cancelling half the messages.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement