Long time admirer, first time poster.
Im currently in the process of making my own 2D DirectX9 / Direct3D Game Engine based off the one in Beginning Game Programming book. So far so good, but I have hit a bit of a brick wall with this one. Despite my googling, I cant seem to find much on these topics despite the fact that an awful lot of games allow the player the option to A) Toggle full screen mode (Alt+Enter) and B) Change the screen resolution.
A)
I understand how to easily set up my game to initially run in full screen mode or windowed mode by changing the D3DPRESENT PARAMS and changing a few settings in the CreateWindow function... But what I cant seem to do is give the user the option to press Alt+Enter in game to change to full screen.
I have read that I need to change the D3DPRESENT PARAMS and call Reset() via the Direct3D Device object... But this blew up my game and im not sure why.
To be honest, I may just force the player to use full screen mode for my game anyway... but it would be nice to have this option implemented within the game engine for future projects.
B)
This is the feature I really think I need to implement - and yet, I cant seem to find anything out there to help.
Currently I have a global const int that represents my Screen Height and Width. This is then used when creating the window and also in the D3DPRESENT PARAMS when creating the back buffer.
One other thing that has bugged me regarding resolution changes - How do you guys handle rendering? For example, say my window is of size 1024 by 768. Lets say I render my Texture (with the transformation matrix) at point 1024, 768 (centred) - This obviously renders right at the bottom right of the screen... but lets say the user changes the resolution settings to 1920 by 1080. That image is no longer rendered at the bottom right of the screen.
How would you guys suggest solving this problem? Do you change your rendering code so that you render at a percentage along X and down Y? EG: You render the same Texture at (100,100) and this would happily render the image at the bottom right of the screen no matter how the user has set his/her settings. Of course, this brings about another issue - the texture would still remain the same size in pixels as before the resolution change so you would end up with blank spaces in between textures (I plan to use tile maps)...
Or should I draw to a back buffer that is 1920 by 1080 and scale the surface down when rendering on screen??
Anyway... thanks for any help
EDIT1: Im also looking for some good open source DX9 Direct3D Game engines to have a look at - Afterall, this is the best way to learn a new tecnology. Ive been looking arround the forum and have seen some references to engine developed and available on the forum - but I cant seem to find any
EDIT2:This is GameMain - Handles directX init and the game loop.
[source lang="cpp"]#include "GameMain.h"#include <iostream>//Direct3D variablesLPDIRECT3D9 d3d = NULL;LPDIRECT3DDEVICE9 d3ddev = NULL;LPDIRECT3DSURFACE9 backbuffer = NULL;LPD3DXSPRITE spriteHandler = NULL;const string APPTITLE = "Game Engine - Windowed";const int SCREENW = 1024;const int SCREENH = 768;//Game Loop#define MAXIMUM_FRAME_RATE 60#define MINIMUM_FRAME_RATE 15#define UPDATE_INTERVAL (1.0 / MAXIMUM_FRAME_RATE)#define MAX_CYCLES_PER_FRAME (MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE)//DX9 rendering engine set upbool DirectXRenderingEngineInit(HWND window){ //initialize Direct3D d3d = Direct3DCreate9(D3D_SDK_VERSION); if (!d3d) return false; //set Direct3D presentation parameters D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.BackBufferWidth = SCREENW; d3dpp.BackBufferHeight = SCREENH; d3dpp.hDeviceWindow = window; //create Direct3D device d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); if (!d3ddev) return false; //get a pointer to the back buffer surface d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); //Clear to black d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); //Init the sprite handler D3DXCreateSprite(d3ddev, &spriteHandler); return true;}void GameRun(HWND window){ //Game Loop will be handled here //It is a Time based, fixed interval system //Based off the system located here: //sacredsoftware.net/tutorials/Animation/TimeBasedAnimation.xhtml static double lastFrameTime = 0.0; static double cyclesLeftOver = 0.0; double currentTime; double updateIterations; //Get instance of the sharedInputManager - Basically init it here static InputManager* sharedInputManager = InputManager::GetInstance(window); //Get instance of the sharedGameController static GameController* sharedGameController = GameController::GetInstance(); //Set initial scene if this is the first run through. static bool hasInitialSceneBeenSet = false; if (!hasInitialSceneBeenSet) { sharedGameController->SetInitialScene(); hasInitialSceneBeenSet = true; } //GAME LOOP LARGE_INTEGER queryLargeInt; QueryPerformanceCounter(&queryLargeInt); currentTime = (double)queryLargeInt.QuadPart; updateIterations = ((currentTime - lastFrameTime) + cyclesLeftOver); if (updateIterations > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL)) updateIterations = (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL); while (updateIterations > UPDATE_INTERVAL) { updateIterations -= UPDATE_INTERVAL; //Ask current scene to update logic sharedGameController->UpdateCurrentSceneWithDelta(UPDATE_INTERVAL/MAX_CYCLES_PER_FRAME); } cyclesLeftOver = updateIterations; lastFrameTime = currentTime; //Render current scene sharedGameController->RenderCurrentScene();}void GameEnd(){ //Clean up DX if (spriteHandler) spriteHandler->Release(); if (d3ddev) d3ddev->Release(); if (d3d) d3d->Release();}[/source]