posted by REDFORCE 2017. 4. 7. 14:59

#1. Engine System

 + WinMain - EngineSystem

 + EngineCore

 + EngineError

 + MainNode


#2. FrameWork

 + Grahpics  (현재 글)

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이번 글 부터는 #2 FrameWork에 대해서 설명하도록 하겠습니다.


실질적으로 FrameWork를 통해 게임을 만들 때 어떤식으로 만들지


그리고 어떤식으로 Framework를 활용할지에 대해서 주로 거론하며

각 클래스들의 역할과 개념을 설명드릴 예정입니다.



Graphics Class 는 DirectX Device를 생성하고

Game 에서 이용하기 위해 어떤 정보들을 담고있는지 보도록 하겠습니다.


1. struct VertexC


첫 번째로 볼 사항은 Vertex 구조체 입니다.


모든 이미지의 텍스쳐는 vertex 좌표가 필요합니다.

따라서 그 좌표에서 사용 될 vertex 구조체가 다음과 같이 정의되어있습니다.

struct VertexC // Vertex with Color
{
float x, y, z; // vertex location
float rhw; // reciprocal homogeneous W (set to 1)
unsigned long color; // vertex color
};
view raw graphics.h hosted with ❤ by GitHub



2. struct SpriteData


두 번째로 볼 사항은 앞으로 사용할

모든 2D 이미지(스프라이트 이미지)를 담고있을 구조체 입니다.

// SpriteData: The properties required by Graphics::drawSprite to draw a sprite
struct SpriteData
{
int width; // width of sprite in pixels
int height; // height of sprite in pixels
float x; // screen location (top left corner of sprite)
float y;
float scale; // <1 smaller, >1 bigger
float angle; // rotation angle in radians
RECT rect; // used to select an image from a larger texture
LP_TEXTURE texture; // pointer to texture
bool flipHorizontal; // true to flip sprite horizontally (mirror)
bool flipVertical; // true to flip sprite vertically
};
view raw graphics.h hosted with ❤ by GitHub


스프라이트 구조체 안에는

 + width / height (이미지 크기)

 + x ,y (스크린 좌표)

 + scale (이미지 스케일)

 + angle (이미지 회전 각도)

 + rect (스프라이트 출력할 이미지 RECT)

 + texture (이미지 텍스쳐)

 + flipHorizontal / flipVertical (이미지 상하좌우 반전 여부)


값들이 있습니다. 각각 int / float / rect / LP_Texture / bool 값들로 이루어져있습니다.


3. Graphics Class Member


세 번째로 Graphics 클래스의 private: 접근한정자 안에 선언 된 변수들입니다.

// DirectX pointer types
#define LP_TEXTURE LPDIRECT3DTEXTURE9
#define LP_SPRITE LPD3DXSPRITE
#define LP_3DDEVICE LPDIRECT3DDEVICE9
#define LP_3D LPDIRECT3D9
#define VECTOR2 D3DXVECTOR2
#define LP_VERTEXBUFFER LPDIRECT3DVERTEXBUFFER9
#define LP_DXFONT LPD3DXFONT
#define LP_VERTEXBUFFER LPDIRECT3DVERTEXBUFFER9
#define LP_DXLINE LPD3DXLINE
class Graphics
{
private:
// DirectX pointers and stuff
LP_3D direct3d;
LP_3DDEVICE device3d;
LP_SPRITE sprite;
LP_DXLINE line; // line pointer
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE pMode;
IDirect3DQuery9* pOcclusionQuery; // for pixel perfect collision detection
DWORD numberOfPixelsColliding; // for pixel perfect collision detection
// other variables
HRESULT result; // standard Windows return codes
HWND hwnd;
bool fullscreen;
bool stencilSupport; // true if device supports stencil buffer
int width;
int height;
COLOR_ARGB backColor; // background color
// (For internal engine use only. No user serviceable parts inside.)
// Initialize D3D presentation parameters
void initD3Dpp();
}
view raw Graphics.h hosted with ❤ by GitHub



위부터 차례대로 Graphics에서 사용하는 내용들을 위한 변수들이 있습니다.


 + LPDIRECT3D9            (directX)

 + LPDIRECT3DDEVICE9   (directX device)

 + LPD3DXSPRITE           (directX Sprite)

 + LPD3DXLINE              (dxLine)


d3dpp / pMode (DirectX를 설정하기 위한 변수)

pOcclusionQuery / numberOfPixel(pixel collision에서 사용하는 변수)


그 외에 hwnd / 전체화면 여부 / directX에서 설정할 해상도 width / height 값 / 배경 값


등등..설정할 변수들이 있습니다.



그 아래로 수 많은 함수들이 선언되어있습니다만

현재 헤더에서 일일히 설명하기엔 분량이 많아지므로 


cpp 파일에서 함께 다루면서 설명하도록 하겠습니다.



아래에는 헤더 파일의 코드 전체가 담겨져 있습니다.

#ifndef _GRAPHICS_H // Prevent multiple definitions if this
#define _GRAPHICS_H // file is included in more than one place
#define WIN32_LEAN_AND_MEAN
#ifdef _DEBUG
#define D3D_DEBUG_INFO
#endif
class Graphics;
#include <d3d9.h>
#include <d3dx9.h>
#include <D3dx9core.h>
#include "constants.h"
#include "gameError.h"
// DirectX pointer types
#define LP_TEXTURE LPDIRECT3DTEXTURE9
#define LP_SPRITE LPD3DXSPRITE
#define LP_3DDEVICE LPDIRECT3DDEVICE9
#define LP_3D LPDIRECT3D9
#define VECTOR2 D3DXVECTOR2
#define LP_VERTEXBUFFER LPDIRECT3DVERTEXBUFFER9
#define LP_DXFONT LPD3DXFONT
#define LP_VERTEXBUFFER LPDIRECT3DVERTEXBUFFER9
#define LP_DXLINE LPD3DXLINE
// Color defines
// ARGB numbers range from 0 through 255
// a = Alpha channel (transparency where 255 is opaque)
// r = Red, g = Green, b = Blue
#define COLOR_ARGB DWORD
#define SETCOLOR_ARGB(a,r,g,b) \
((COLOR_ARGB)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
namespace graphicsNS
{
// Some common colors
// ARGB numbers range from 0 through 255
// A = Alpha channel (transparency where 255 is opaque)
// R = Red, G = Green, B = Blue
const COLOR_ARGB ORANGE = D3DCOLOR_ARGB(255,255,165, 0);
const COLOR_ARGB BROWN = D3DCOLOR_ARGB(255,139, 69, 19);
const COLOR_ARGB LTGRAY = D3DCOLOR_ARGB(255,192,192,192);
const COLOR_ARGB GRAY = D3DCOLOR_ARGB(255,128,128,128);
const COLOR_ARGB OLIVE = D3DCOLOR_ARGB(255,128,128, 0);
const COLOR_ARGB PURPLE = D3DCOLOR_ARGB(255,128, 0,128);
const COLOR_ARGB MAROON = D3DCOLOR_ARGB(255,128, 0, 0);
const COLOR_ARGB TEAL = D3DCOLOR_ARGB(255, 0,128,128);
const COLOR_ARGB GREEN = D3DCOLOR_ARGB(255, 0,128, 0);
const COLOR_ARGB NAVY = D3DCOLOR_ARGB(255, 0, 0,128);
const COLOR_ARGB WHITE = D3DCOLOR_ARGB(255,255,255,255);
const COLOR_ARGB YELLOW = D3DCOLOR_ARGB(255,255,255, 0);
const COLOR_ARGB MAGENTA = D3DCOLOR_ARGB(255,255, 0,255);
const COLOR_ARGB RED = D3DCOLOR_ARGB(255,255, 0, 0);
const COLOR_ARGB CYAN = D3DCOLOR_ARGB(255, 0,255,255);
const COLOR_ARGB LIME = D3DCOLOR_ARGB(255, 0,255, 0);
const COLOR_ARGB BLUE = D3DCOLOR_ARGB(255, 0, 0,255);
const COLOR_ARGB BLACK = D3DCOLOR_ARGB(255, 0, 0, 0);
const COLOR_ARGB FILTER = D3DCOLOR_ARGB(255,255,255,255); // use to specify drawing with colorFilter
const COLOR_ARGB ALPHA25 = D3DCOLOR_ARGB( 64,255,255,255); // AND with color to get 25% alpha
const COLOR_ARGB ALPHA50 = D3DCOLOR_ARGB(128,255,255,255); // AND with color to get 50% alpha
const COLOR_ARGB BACK_COLOR = NAVY; // background color of game
const COLOR_ARGB TRANSCOLOR = BLACK; // transparent color
enum DISPLAY_MODE{TOGGLE, FULLSCREEN, WINDOW};
}
struct VertexC // Vertex with Color
{
float x, y, z; // vertex location
float rhw; // reciprocal homogeneous W (set to 1)
unsigned long color; // vertex color
};
// Flexible Vertex Format Codes
// D3DFVF_XYZRHW = The verticies are transformed
// D3DFVF_DIFFUSE = The verticies contain diffuse color data
#define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
// SpriteData: The properties required by Graphics::drawSprite to draw a sprite
struct SpriteData
{
int width; // width of sprite in pixels
int height; // height of sprite in pixels
float x; // screen location (top left corner of sprite)
float y;
float scale; // <1 smaller, >1 bigger
float angle; // rotation angle in radians
RECT rect; // used to select an image from a larger texture
LP_TEXTURE texture; // pointer to texture
bool flipHorizontal; // true to flip sprite horizontally (mirror)
bool flipVertical; // true to flip sprite vertically
};
class Graphics
{
private:
// DirectX pointers and stuff
LP_3D direct3d;
LP_3DDEVICE device3d;
LP_SPRITE sprite;
LP_DXLINE line; // line pointer
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE pMode;
IDirect3DQuery9* pOcclusionQuery; // for pixel perfect collision detection
DWORD numberOfPixelsColliding; // for pixel perfect collision detection
// other variables
HRESULT result; // standard Windows return codes
HWND hwnd;
bool fullscreen;
bool stencilSupport; // true if device supports stencil buffer
int width;
int height;
COLOR_ARGB backColor; // background color
// (For internal engine use only. No user serviceable parts inside.)
// Initialize D3D presentation parameters
void initD3Dpp();
public:
// Constructor
Graphics();
// Destructor
virtual ~Graphics();
// Releases direct3d and device3d.
void releaseAll();
// Initialize DirectX graphics
// Throws GameError on error
// Pre: hw = handle to window
// width = width in pixels
// height = height in pixels
// fullscreen = true for full screen, false for window
void initialize(HWND hw, int width, int height, bool fullscreen);
// Create a vertex buffer.
// Pre: verts[] contains vertex data.
// size = size of verts[]
// Post: &vertexBuffer points to buffer if successful.
HRESULT createVertexBuffer(VertexC verts[], UINT size, LP_VERTEXBUFFER &vertexBuffer);
// Display a quad (rectangle) with alpha transparency.
// Pre: createVertexBuffer was used to create vertexBuffer containing four
// vertices defining the quad in clockwise order.
// g3ddev->BeginScene was called
bool drawQuad(LP_VERTEXBUFFER vertexBuffer);
// Load the texture into default D3D memory (normal texture use)
// For internal engine use only. Use the TextureManager class to load game textures.
// Pre: filename = name of texture file.
// transcolor = transparent color
// Post: width and height = size of texture
// texture points to texture
HRESULT loadTexture(const char * filename, COLOR_ARGB transcolor, UINT &width, UINT &height, LP_TEXTURE &texture);
// Load the texture into system memory (system memory is lockable)
// Provides direct access to pixel data. Use the TextureManager class to load textures for display.
// Pre: filename = name of texture file.
// transcolor = transparent color
// Post: width and height = size of texture
// texture points to texture
HRESULT loadTextureSystemMem(const char *filename, COLOR_ARGB transcolor, UINT &width, UINT &height, LP_TEXTURE &texture);
// Display the offscreen backbuffer to the screen.
HRESULT showBackbuffer();
// Checks the adapter to see if it is compatible with the BackBuffer height,
// width and refresh rate specified in d3dpp. Fills in the pMode structure with
// the format of the compatible mode, if found.
// Pre: d3dpp is initialized.
// Post: Returns true if compatible mode found and pMode structure is filled.
// Returns false if no compatible mode found.
bool isAdapterCompatible();
// Draw the sprite described in SpriteData structure.
// color is optional, it is applied as a filter, WHITE is default (no change).
// Creates a sprite Begin/End pair.
// Pre: spriteData.rect defines the portion of spriteData.texture to draw
// spriteData.rect.right must be right edge + 1
// spriteData.rect.bottom must be bottom edge + 1
void drawSprite(const SpriteData &spriteData, // sprite to draw
COLOR_ARGB color = graphicsNS::WHITE); // default to white color filter (no change)
// Reset the graphics device.
HRESULT reset();
// Toggle, fullscreen or window display mode
// Pre: All user created D3DPOOL_DEFAULT surfaces are freed.
// Post: All user surfaces are recreated.
void changeDisplayMode(graphicsNS::DISPLAY_MODE mode = graphicsNS::TOGGLE);
// Return length of vector v.
static float Vector2Length(const VECTOR2 *v) {return D3DXVec2Length(v);}
// Return Dot product of vectors v1 and v2.
static float Vector2Dot(const VECTOR2 *v1, const VECTOR2 *v2) {return D3DXVec2Dot(v1, v2);}
// Normalize vector v.
static void Vector2Normalize(VECTOR2 *v) {D3DXVec2Normalize(v, v);}
// Transform vector v with matrix m.
static VECTOR2* Vector2Transform(VECTOR2 *v, D3DXMATRIX *m) {return D3DXVec2TransformCoord(v,v,m);}
// Return the number of pixels colliding between the two sprites.
// Pre: The device supports a stencil buffer and pOcclusionQuery points to
// a valid occlusionQuery object.
// Post: Returns the number of pixels of overlap
// This function waits for the graphics card to render the last frame and return
// the collision query pixel count. To avoid slowing down your game, use a
// simple collison test first to eliminate entities that are not colliding.
DWORD pixelCollision(const SpriteData &sprite1, const SpriteData &sprite2);
// get functions
// Return direct3d.
LP_3D get3D() { return direct3d; }
// Return device3d.
LP_3DDEVICE get3Ddevice() { return device3d; }
// Return sprite
LP_SPRITE getSprite() { return sprite; }
// Return handle to device context (window).
HDC getDC() { return GetDC(hwnd); }
// Test for lost device
HRESULT getDeviceState();
// Return fullscreen
bool getFullscreen() { return fullscreen; }
// Return pOcclusionQuery
IDirect3DQuery9* getPOcclusionQuery() { return pOcclusionQuery; }
// Returns true if the graphics card supports a stencil buffer
bool getStencilSupport() { return stencilSupport; }
// Set color used to clear screen
void setBackColor(COLOR_ARGB c) {backColor = c;}
//=============================================================================
// Create DX line, description from D3dx9core.h
// This object intends to provide an easy way to draw lines using D3D.
//
// Begin -
// Prepares device for drawing lines
// Draw -
// Draws a line strip in screen-space.
// Input is in the form of a array defining points on the line strip. of D3DXVECTOR2
// DrawTransform -
// Draws a line in screen-space with a specified input transformation matrix.
// End -
// Restores device state to how it was when Begin was called.
// SetPattern -
// Applies a stipple pattern to the line. Input is one 32-bit
// DWORD which describes the stipple pattern. 1 is opaque, 0 is
// transparent.
// SetPatternScale -
// Stretches the stipple pattern in the u direction. Input is one
// floating-point value. 0.0f is no scaling, whereas 1.0f doubles
// the length of the stipple pattern.
// SetWidth -
// Specifies the thickness of the line in the v direction. Input is
// one floating-point value.
// SetAntialias -
// Toggles line antialiasing. Input is a BOOL.
// TRUE = Antialiasing on.
// FALSE = Antialiasing off.
// SetGLLines -
// Toggles non-antialiased OpenGL line emulation. Input is a BOOL.
// TRUE = OpenGL line emulation on.
// FALSE = OpenGL line emulation off.
// OpenGL line: Regular line:
// *\ *\
// | \ / \
// | \ *\ \
// *\ \ \ \
// \ \ \ \
// \ * \ *
// \ | \ /
// \| *
// *
// OnLostDevice, OnResetDevice -
// Call OnLostDevice() on this object before calling Reset() on the
// device, so that this object can release any stateblocks and video
// memory resources. After Reset(), the call OnResetDevice().
//=============================================================================
void createLine(LP_DXLINE *line)
{
D3DXCreateLine(device3d, line);
}
//=============================================================================
// Draw DirectX line from X1,Y1 to X2,Y2.
// width defauts to 1.
// color defaults to graphicsNS::WHITE.
//=============================================================================
void drawLine(float x1, float y1, float x2, float y2, float width = 1.0f, COLOR_ARGB color = graphicsNS::WHITE);
//=============================================================================
// Clear backbuffer and BeginScene()
//=============================================================================
HRESULT beginScene()
{
result = E_FAIL;
if(device3d == NULL)
return result;
// Clear back buffer, stencil buffer and depth buffer
device3d->Clear(0, 0,
D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
backColor, 1.0f, 0);
result = device3d->BeginScene(); // begin scene for drawing
return result;
}
//=============================================================================
// EndScene()
//=============================================================================
HRESULT endScene()
{
result = E_FAIL;
if(device3d)
result = device3d->EndScene();
return result;
}
//=============================================================================
// Sprite Begin
//=============================================================================
void spriteBegin()
{
sprite->Begin(D3DXSPRITE_ALPHABLEND);
}
//=============================================================================
// Sprite End
//=============================================================================
void spriteEnd()
{
sprite->End();
}
};
#endif
view raw Graphics.h hosted with ❤ by GitHub


'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #2_Graphics.cpp (2)  (0) 2017.04.17
June_Engine #2_Graphics.cpp (1)  (0) 2017.04.15
June_Engine #1_MainNode  (0) 2017.04.07
June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
posted by REDFORCE 2017. 4. 7. 13:27

#1. Engine System

 + WinMain - EngineSystem

 + EngineCore

 + EngineError

 + MainNode (현재 글)


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이번 글에서는 각 매니저나 게임 구동에 필요한 것들이 동작 될, 루트라 볼 수 있는

MainNode에 대해서 설명하겠습니다.


MainNode Class는 EngineSystem Class와 Game Class 에서의 중간다리 역할이라 할 수 있습니다.


헤더를 먼저 살펴보겠습니다.

#ifndef _MAINNODE_H // Prevent multiple definitions if this
#define _MAINNODE_H // file is included in more than one place
class MainNode;
namespace mainNodeNS
{
//const float maxFrameLimit = 60.0f; //Not Using This Code
}
class MainNode
{
private:
bool initializedMgr = false;
public:
MainNode();
~MainNode();
HRESULT initialize();
void release();
void update();
void render();
LRESULT messageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
#endif
view raw mainNode.h hosted with ❤ by GitHub



헤더에서는 주요하게 볼 부분은 MainNode의 함수 구성이


initialize()

release()

update()

render()


로 나뉘어져 있다는 사실 입니다.


그리고 Engine의 프로시져로 받아오는 내용을 처리할 핸들러가 있습니다.



이어서 .cpp 를 보겠습니다.


cpp 는 헤더에 선언해두었던 각각의 함수 수행부가 구현되어 있습니다.

#include "stdafx.h"
#include "mainNode.h"
#include "scene_Main.h"
#include "scene_Test.h"
#include "scene_Maptool.h"
MainNode::MainNode() : initializedMgr(FALSE)
{
}
MainNode::~MainNode()
{
}
HRESULT MainNode::initialize()
{
//Need Not Hwnd Managers initialize
//FILEMANAGER->initialize();
//TIMEMANAGER->initialize();
LAYERMANAGER->initialize();
//Need Hwnd Managers initialize
IMAGEMANAGER->initialize(g_Graphics);
// Create the game, sets up message handler
//game = new scene_Main;
SCENEMANAGER->addScene("Main", new Scene_Main);
SCENEMANAGER->addScene("Test", new Scene_Test);
SCENEMANAGER->addScene("Maptool", new Scene_Maptool);
SCENEMANAGER->initialize();
return S_OK;
}
void MainNode::release()
{
SCENEMANAGER->release();
//TIMEMANAGER->release();
IMAGEMANAGER->release();
FILEMANAGER->release();
LAYERMANAGER->release();
}
void MainNode::update()
{
//TIMEMANAGER->UpdateTime(mainNodeNS::maxFrameLimit);
SCENEMANAGER->update();
}
void MainNode::render()
{
SCENEMANAGER->render();
}
LRESULT MainNode::messageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (SCENEMANAGER->getCurrentScene() == NULL)
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return SCENEMANAGER->getCurrentScene()->messageHandler(hwnd, msg, wParam, lParam); //SceneManager Proc
}
view raw mainNode.cpp hosted with ❤ by GitHub



먼저 intiailize()에서는 게임에서 사용 하는 각각의 Manager들을 초기화 합니다.


코드상에 TIMEMANAGER와 FILEMANAGER가 주석처리 된 이유는


현재 사용하지 않기 때문이고, FILEMANAGER의 경우 EngineStart( ) 구역으로 빠져있습니다.



release() 는 매니저들에 대한 내용을 해지하는 것을 수행합니다. 



두 번째로 update() 에서 SceneManager를 업데이트하여 현재 게임의 내용을 업데이트합니다.


이것이 수행되고 나면 SceneManager -> render()를 수행하여

그리기 작업을 수행하게 됩니다.



마지막에 있는 MessageHandler는 EngineRun()에서 전달되는 프로시져에서의 메세지 처리 핸들러 입니다.


키 입력에 대한 처리를 여기서 위와 같이 하게 됩니다.




'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #2_Graphics.cpp (1)  (0) 2017.04.15
June_Engine #2_Graphics.h  (0) 2017.04.07
June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
posted by REDFORCE 2017. 4. 7. 10:13

#1. Engine System

 + WinMain - EngineSystem

 + EngineCore

 + EngineError (현재 글)

 + MainNode


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이번 글에서는 EngineError.h 에 대해서 설명하도록 하겠습니다.


흔히 어떤 에러에 대한 처리를 위해서 try - catch 문을 이용하여


exception 처리를 하는데요.



저는 그 처리 중에 내가 알수 있을 법한 처리로 에러를 보고자


EngineError.h 를 만들어두었습니다.


먼저 코드를 보는게 이해가 빠른 분들이 계실 수도 있으니 전체 코드부터 올려드리겠습니다.

#ifndef _ENGINERROR_H
#define _ENGINERROR_H
#define WIN32_LEAN_AND_MEAN
#include <string>
#include <exception>
namespace engineErrorNS
{
const int ENGINE_FATAL_ERROR = 400;
const int ENGINE_INTERFACE_ERROR = 401;
const int ENGINE_CORE_ERROR = 403;
const int ENGINE_SYSTEM_MENU_ERROR = 404;
}
class EngineError : public std::exception
{
private:
int errorCode;
std::string message;
public:
// default constructor
EngineError() throw() :errorCode(engineErrorNS::ENGINE_FATAL_ERROR), message("Undefined Error in EngineSystem.") {}
// copy constructor
EngineError(const EngineError& e) throw() : std::exception(e), errorCode(e.errorCode), message(e.message) {}
// constructor with args
EngineError(int code, const std::string &s) throw() :errorCode(code), message(s) {}
// assignment operator
EngineError& operator= (const EngineError& rhs) throw()
{
std::exception::operator=(rhs);
this->errorCode = rhs.errorCode;
this->message = rhs.message;
}
// destructor
virtual ~EngineError() throw() {};
// override what from base class
virtual const char* what() const throw() { return this->getMessage(); }
const char* getMessage() const throw() { return message.c_str(); }
int getErrorCode() const throw() { return errorCode; }
};
#endif // !_ENGINEERROR_H
view raw engineError.h hosted with ❤ by GitHub



위와 같이 먼저 


1. #include <exception>을 이용합니다.

2. 그리고 간단히 내가 정의할 에러 코드를 namespace로 묶어두었습니다.

3. EngineError Class는 std::exception을 부모로 받습니다.

4. 생성자에 throw( ) 를 이용하여 에러 코드와 메세지를 던지도록 하게합니다.

5. 간단히 operator= 에도 메세지를 받을 수 있도록 재정의 해줍니다.



이게 다 입니다.


사용 법은??


이미 우리는 engineSystem.cpp 에서 EngineError를 사용하는 것을 보셨을 겁니다.


그곳(engineError.cpp)을 참조하시는게 빠르니 


직접 해보시거나 이런식으로 만들어보면서 쓰시면 좋을 것 같습니다.

'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #2_Graphics.h  (0) 2017.04.07
June_Engine #1_MainNode  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
June_Engine #1_EngineSystem  (0) 2017.04.06
posted by REDFORCE 2017. 4. 7. 09:34

#1. Engine System

 + WinMain - EngineSystem

 + EngineCore (현재 글)

 + EngineError

 + MainNode


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이어서 EngineCore의 cpp 입니다.


.h 에서 선언해두었던 std::thread를 이용하는 내용만 있습니다만.


실질적으로 어떤 것을 수행하게끔 구현은 시켜두지 않았습니다.



본래 계획은 Component Based 형식의 엔진 구조를 만들어서 


이 코어쓰레드들을 여러개 만들어서 일을 시킬려고 했습니다만


아직 개발중인지라 틀만 잡아두고 냅둔 상태입니다.

그래도 아무 설명도 안하고 넘어가면 찝찝하니 initialize( )에 적어둔 내용을 보겠습니다.

#include "stdafx.h"
#include "engineCore.h"
EngineCore::EngineCore()
{
}
EngineCore::~EngineCore()
{
for (auto iter : vecWorkers)
{
if (iter->joinable())
iter->join();
}
}
bool EngineCore::initialize()
{
bool success = false;
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo); //Get SystemInfo
DWORD cpu_count = systemInfo.dwNumberOfProcessors; //CPU CORE COUNT
int coreSize = (int)cpu_count;
//vecWorker Push_Back(Emplace_Back) Worker Thread for CPU Count
for (int i = 0; i < coreSize; i++)
{
std::thread worker = std::thread([&]{ CoreSupport(); });
vecWorkers.emplace_back(&worker);
}
success = true;
return success;
}
void EngineCore::CoreSupport()
{
//To do Something
}
view raw engineCore.cpp hosted with ❤ by GitHub


SYSTEM_INFO systemInfo;

GetSystemInfo(&systemInfo); //Get SystemInfo

DWORD cpu_count = systemInfo.dwNumberOfProcessors;    //CPU CORE COUNT


는 윈도우 함수를 이용해서 cpu 코어 갯수를 알아내는 방법입니다.


DWORD 형태로 값이 반환되어 지기 때문에 (int)로 형변환하여 

받아온 코어 갯수 만큼 쓰레드를 생성하여 컨테이너에 담아둡니다.


그리고 그 쓰레드가 일할 내용은 선언해두었던 가상 함수 CoreSupport( ) 를 넣어주었습니다.


만약 어떤 쓰레드를 이용하여 일을 시킬 내용이 생긴다면



EngineCore를 부모로 상속받아서 어떤 작업 내용을 CoreSupport에 담아두면 될 것 같습니다.


그러나 아직은 확실히 동작시켜본 적이 없기 때문에 확신은 없습니다.



그냥 이렇게 한번 돌려보자 라는 생각으로 만들어두었을 뿐..


아무튼 현재 사용하지 않는 코어 부분들입니다!

'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #1_MainNode  (0) 2017.04.07
June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
June_Engine #1_EngineSystem  (0) 2017.04.06
June_Engine #1_WinMain  (0) 2017.04.06
posted by REDFORCE 2017. 4. 6. 19:18

#1. Engine System

 + WinMain - EngineSystem

 + EngineCore (현재 글)

 + EngineError

 + MainNode


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이번 글에서는 이전에 적어둔 EngineSystem Class에서 불렀던 EngineCore Class가 어떻게 돌아가는지 살펴보도록 하겠습니다.


먼저 헤더부터 살펴보도록 하겠습니다.


헤더에는 단순히 아래와 같이 std::vector 로 std::Thread 컨테이너만 있습니다.

#ifndef _ENGINECORE_H
#define _ENGINECORE_H
class EngineCore;
#include <thread>
#include <vector>
class EngineCore
{
private:
std::vector<std::thread*> vecWorkers;
public:
EngineCore();
~EngineCore();
bool initialize();
virtual void CoreSupport();
};
#endif // !_ENGINECORE_H
view raw engineCore.h hosted with ❤ by GitHub


보시는 것과 같이 engineCore Class 에서는 std::Thread 를 이용하여 


멀티쓰레드를 사용하기 위해 준비하고 있습니다.



그리고 멀티쓰레드에서 일할 내용이 들어갈 가상함수 CoreSupport ( ) 함수가 있습니다.

'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineSystem  (0) 2017.04.06
June_Engine #1_WinMain  (0) 2017.04.06
June_Engine #1_메뉴얼(Manual)  (0) 2017.04.05
posted by REDFORCE 2017. 4. 6. 17:18

#1. Engine System

 + WinMain - EngineSystem (현재 글)

 + EngineCore

 + EngineError

 + MainNode


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이어서 WinMain - EngineSystem 두번째 글 입니다.


EngineSystem.h 부터 살펴보도록 하겠습니다.

#ifndef _ENGINESYSTEM_H
#define _ENGINESYSTEM_H
class EngineSystem;
class EngineSystem
{
private:
public:
EngineSystem();
~EngineSystem();
bool engineStart(HINSTANCE hInstance, int nCmdShow);
int run();
bool CreateMainWindow(HWND &, HINSTANCE, int);
LRESULT EngineProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
};
#endif // !_ENGINESYSTEM_H
view raw engineSystem.h hosted with ❤ by GitHub



헤더 구성은 주요 함수 내용은 


 + 생성자 / 소멸자

 + bool engineStart ( )           // 엔진 시작 전 초기화 지점

 + int Run ( )                       // 엔진 런

 + bool CreateWindowMain    // 메인 Window 화면 생성 함수

 + LRESULT EngineProc( )       // 메인 프로시져


이 있습니다. 

(위의 내용에는 파라미터가 생략되어있습니다. 정확한건 Gist로 올려둔 코드를 보시기 바랍니다)



생성자와 소멸자에선 딱히 하는 일이 없기 때문에 생략합니다.




첫 번째 함수인 bool engineStart( ) 함수부터 살펴보겠습니다.

//=============================================================================
// Engine Start
// This Function Will Load When WinMain.cpp Start
//=============================================================================
bool EngineSystem::engineStart(HINSTANCE hInstance, int nCmdShow)
{
FILEMANAGER->initialize();
bool success = false;
// pEngine->Set This Point.
// For Static Engine & Game Proc
::pEngine = this;
EngineCore engineCore;
if (engineCore.initialize()) //This is Not Meaning Anything Until Develop Component Based System
{
try
{
// Create Engine-Main Window
if (CreateMainWindow(g_hWndEngine, hInstance, nCmdShow) == false)
throw(EngineError(engineErrorNS::ENGINE_CORE_ERROR, "Engine Main Window Create Failed"));
success = true;
}
catch (const EngineError &err)
{
MessageBox(g_hWndEngine, err.getMessage(), "Error", MB_OK);
}
}
return success;
}


engineStart 함수에서는 먼저 FILEMANAGER->initialize( ) 가 수행됩니다.


FILEMANAGER는 본 편에서 다룰 내용은 아니지만 간단히 설명하자면


프로젝트가 구동 될 때 읽어 들일 Resource 폴더내의 내용을 긁어오는 녀석이라 보시면 됩니다.

Singleton 패턴으로 선언되어있으며 추후 엔진에서 어떤 리소스에 대한 내용을 다시 불러올 때 사용 됩니다.



그리고 ::pEngine = this; 는 앞으로 사용 될 엔진의 static 함수인 메인 프로시져를 수행하기 위한 용도 입니다.


그리고 핵심 부분인 


EngineCore engineCore;

if (engineCore.initialize()) //This is Not Meaning Anything Until Develop Component Based System

{

try

{

// Create Engine-Main Window

if (CreateMainWindow(g_hWndEngine, hInstance, nCmdShow) == false)

throw(EngineError(engineErrorNS::ENGINE_CORE_ERROR, "Engine Main Window Create Failed"));


success = true;

}

catch (const EngineError &err)

{

MessageBox(g_hWndEngine, err.getMessage(), "Error", MB_OK);

}

}


에서 EngineCore를 선언 및 수행하게 되며 engineCore.initializer() 에서 return 받은 값이 true 면

엔진 루프를 실행 할 준비가 되었다는 뜻 입니다.


따라서 Main Window를 이때 생성하게 되는데요.

CreateMainWindow 함수를 통해 메인 HWND를 통해 WinMain에서 받아온 hInstance값을 통해 화면을 만들게 됩니다.


여기까지 작업이 잘 끝났다면 return success를 돌려주게 되겠지요.


아래는 위에 engineStart 과정에서 사용 한 CreateMainWindow 함수와 EngineProc ( 프로시져 ) 입니다.

//=============================================================================
// Create the window
// Returns: false on error
//=============================================================================
bool EngineSystem::CreateMainWindow(HWND &hWnd, HINSTANCE hInstance, int nCmdShow)
{
// Fill in the window class structure with parameters
// that describe the main window.
g_wcx.cbSize = sizeof(g_wcx); // size of structure
g_wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes
g_wcx.lpfnWndProc = ::EngineProc; // points to window procedure
g_wcx.cbClsExtra = 0; // no extra class memory
g_wcx.cbWndExtra = 0; // no extra window memory
g_wcx.hInstance = hInstance; // handle to instance
g_wcx.hIcon = LoadIcon(NULL, IDI_WINLOGO);
g_wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow
g_wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // black background
g_wcx.lpszMenuName = NULL; // name of menu resource
g_wcx.lpszClassName = CLASS_NAME; // name of window class
g_wcx.hIconSm = NULL; // small class icon
// Register the window class.
// RegisterClassEx returns 0 on error.
if (RegisterClassEx(&g_wcx) == 0) // if error
return false;
//set up the screen in windowed or fullscreen mode?
DWORD style;
if (FULLSCREEN)
style = WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP;
else
style = WS_OVERLAPPEDWINDOW;
// Create window
hWnd = CreateWindow(
CLASS_NAME, // name of the window class
GAME_TITLE, // title bar text
style, // window style
CW_USEDEFAULT, // default horizontal position of window
CW_USEDEFAULT, // default vertical position of window
WINSIZEX, // width of window
WINSIZEY, // height of the window
(HWND)NULL, // no parent window
(HMENU)NULL, // no menu
hInstance, // handle to application instance
(LPVOID)NULL); // no window parameters
// if there was an error creating the window
if (!hWnd)
return false;
if (!FULLSCREEN) // if window
{
// Adjust window size so client area is GAME_WIDTH x GAME_HEIGHT
RECT clientRect;
GetClientRect(hWnd, &clientRect); // get size of client area of window
MoveWindow(hWnd,
0, // Left
0, // Top
WINSIZEX + (WINSIZEX - clientRect.right), // Right
WINSIZEY + (WINSIZEY - clientRect.bottom), // Bottom
TRUE); // Repaint the window
}
// Show the window
ShowWindow(hWnd, nCmdShow);
return true;
}
//=============================================================================
// Window Event Callback Function
// This Proc Function is Static
// It will be converted For Engine messageHandler
//=============================================================================
LRESULT EngineSystem::EngineProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
//return (engineInput->messageHandler(hWnd, Msg, wParam, lParam));
return (g_MainNode->messageHandler(hWnd, Msg, wParam, lParam));
}




그리고 두 번째 핵심 부분인 engineRun ( )을 살펴보겠습니다.

//=============================================================================
// Engine Run
// Global Graphics Pointer initialize
// MainNode initialize
// Window Message Loop -> MainNode.Update()
// if has found something problem, It would be catched GameError
//=============================================================================
int EngineSystem::run()
{
//Graphics Initialize
g_Graphics = new Graphics;
g_Graphics->initialize(g_hWndEngine, 0, 0, false);
//Main Node Initialize
g_MainNode = new MainNode;
g_MainNode->initialize();
MSG msg;
try {
// main message loop
int done = 0;
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// look for quit message
if (msg.message == WM_QUIT)
done = 1;
// decode and pass messages on to WinProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_MainNode->update(); // Main Node Update() Message Loop -> Update()
}
}
//SAFE_DELETE (game); // free memory before exit
return msg.wParam;
}
catch (const EngineError &err)
{
g_MainNode->release(); // MainNode release
DestroyWindow(g_hWndEngine); // Destory Engine Window
MessageBox(NULL, err.getMessage(), "Error", MB_OK);
}
catch (...)
{
g_MainNode->release(); // MainNode release
DestroyWindow(g_hWndEngine); // Destory Engine Window
MessageBox(NULL, "Unknown error occured in game.", "Error", MB_OK);
}
return 0;
}



engineRun( ) 에서는 게임의 


Game의 DirectX 를 얹기 위해 Graphics 클래스와

Scene의 루트 노드라 부를 수 있는 MainNode를 생성합니다.


각각 initialize( ) 함수를 통해 초기화를 진행하고 메인 노드의 초기화가 끝나면


이제 메세지 루프를 돌게 됩니다.


메세지 루프는 window가 생성되면서 연결시켜주었던 프로시져를 통해 


메세지 루프를 돌게 되며 PeekMessage가 없으면

메인노드의 Update 함수를 수행합니다.


try - Catch 구문으로 감싸져 있는 스코프 부분이 루프 영역입니다.



그리고 혹여나 어떤 에러가 발생하면 Catch 구문으로 가서 에러를 띄워주고 메인 Window를 다시 파괴하고 모든 것들을 릴리즈 시킵니다.



아마 여기까지는 일반적인 WinAPI 게임 구조의 형태와 비슷하기 때문에


Initialize -> Update -> Render 로직을 따라 가시면 쉽게 이해하실 수 있을거라 생각드네요.




여기까지가 EngineSystem Class에 대한 내용이었습니다.


혹여나 잘 이해가 안가시는 부분이 있다면 질문주시면 성의껏 답변해드리겠습니다.



전체 cpp 코드는 아래에 적어두었습니다.

#include "stdafx.h"
#include "engineSystem.h"
#include "engineCore.h"
#include "engineError.h"
#include "mainNode.h"
// EngineSystem Pointer For CALLBACK EngineProc
EngineSystem* pEngine;
//=============================================================================
// Main Engine Proc
//=============================================================================
static LRESULT CALLBACK EngineProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return pEngine->EngineProc(hWnd, Msg, wParam, lParam);
}
EngineSystem::EngineSystem()
{
}
EngineSystem::~EngineSystem()
{
}
//=============================================================================
// Engine Start
// This Function Will Load When WinMain.cpp Start
//=============================================================================
bool EngineSystem::engineStart(HINSTANCE hInstance, int nCmdShow)
{
FILEMANAGER->initialize();
bool success = false;
// pEngine->Set This Point.
// For Static Engine & Game Proc
::pEngine = this;
EngineCore engineCore;
if (engineCore.initialize()) //This is Not Meaning Anything Until Develop Component Based System
{
try
{
// Create Engine-Main Window
if (CreateMainWindow(g_hWndEngine, hInstance, nCmdShow) == false)
throw(EngineError(engineErrorNS::ENGINE_CORE_ERROR, "Engine Main Window Create Failed"));
success = true;
}
catch (const EngineError &err)
{
MessageBox(g_hWndEngine, err.getMessage(), "Error", MB_OK);
}
}
return success;
}
//=============================================================================
// Engine Run
// Global Graphics Pointer initialize
// MainNode initialize
// Window Message Loop -> MainNode.Update()
// if has found something problem, It would be catched GameError
//=============================================================================
int EngineSystem::run()
{
//Graphics Initialize
g_Graphics = new Graphics;
g_Graphics->initialize(g_hWndEngine, 0, 0, false);
//Main Node Initialize
g_MainNode = new MainNode;
g_MainNode->initialize();
MSG msg;
try {
// main message loop
int done = 0;
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// look for quit message
if (msg.message == WM_QUIT)
done = 1;
// decode and pass messages on to WinProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_MainNode->update(); // Main Node Update() Message Loop -> Update()
}
}
//SAFE_DELETE (game); // free memory before exit
return msg.wParam;
}
catch (const EngineError &err)
{
g_MainNode->release(); // MainNode release
DestroyWindow(g_hWndEngine); // Destory Engine Window
MessageBox(NULL, err.getMessage(), "Error", MB_OK);
}
catch (...)
{
g_MainNode->release(); // MainNode release
DestroyWindow(g_hWndEngine); // Destory Engine Window
MessageBox(NULL, "Unknown error occured in game.", "Error", MB_OK);
}
return 0;
}
//=============================================================================
// Create the window
// Returns: false on error
//=============================================================================
bool EngineSystem::CreateMainWindow(HWND &hWnd, HINSTANCE hInstance, int nCmdShow)
{
// Fill in the window class structure with parameters
// that describe the main window.
g_wcx.cbSize = sizeof(g_wcx); // size of structure
g_wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes
g_wcx.lpfnWndProc = ::EngineProc; // points to window procedure
g_wcx.cbClsExtra = 0; // no extra class memory
g_wcx.cbWndExtra = 0; // no extra window memory
g_wcx.hInstance = hInstance; // handle to instance
g_wcx.hIcon = LoadIcon(NULL, IDI_WINLOGO);
g_wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow
g_wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // black background
g_wcx.lpszMenuName = NULL; // name of menu resource
g_wcx.lpszClassName = CLASS_NAME; // name of window class
g_wcx.hIconSm = NULL; // small class icon
// Register the window class.
// RegisterClassEx returns 0 on error.
if (RegisterClassEx(&g_wcx) == 0) // if error
return false;
//set up the screen in windowed or fullscreen mode?
DWORD style;
if (FULLSCREEN)
style = WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP;
else
style = WS_OVERLAPPEDWINDOW;
// Create window
hWnd = CreateWindow(
CLASS_NAME, // name of the window class
GAME_TITLE, // title bar text
style, // window style
CW_USEDEFAULT, // default horizontal position of window
CW_USEDEFAULT, // default vertical position of window
WINSIZEX, // width of window
WINSIZEY, // height of the window
(HWND)NULL, // no parent window
(HMENU)NULL, // no menu
hInstance, // handle to application instance
(LPVOID)NULL); // no window parameters
// if there was an error creating the window
if (!hWnd)
return false;
if (!FULLSCREEN) // if window
{
// Adjust window size so client area is GAME_WIDTH x GAME_HEIGHT
RECT clientRect;
GetClientRect(hWnd, &clientRect); // get size of client area of window
MoveWindow(hWnd,
0, // Left
0, // Top
WINSIZEX + (WINSIZEX - clientRect.right), // Right
WINSIZEY + (WINSIZEY - clientRect.bottom), // Bottom
TRUE); // Repaint the window
}
// Show the window
ShowWindow(hWnd, nCmdShow);
return true;
}
//=============================================================================
// Window Event Callback Function
// This Proc Function is Static
// It will be converted For Engine messageHandler
//=============================================================================
LRESULT EngineSystem::EngineProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
//return (engineInput->messageHandler(hWnd, Msg, wParam, lParam));
return (g_MainNode->messageHandler(hWnd, Msg, wParam, lParam));
}


'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
June_Engine #1_WinMain  (0) 2017.04.06
June_Engine #1_메뉴얼(Manual)  (0) 2017.04.05
posted by REDFORCE 2017. 4. 6. 16:50

#1. Engine System

 + WinMain - EngineSystem (현재 글)

 + EngineCore

 + EngineError

 + MainNode


#2. FrameWork

 + Grahpics

 + Image - SpriteData

 + Layer

 + Input

 + Game

 + Manager

 + Game Interface

 + Utility


#3. Testing Module

 + 2D Image Test

 + 2D Animation Test

 + Game UI Test


-----------------------------------------------------------------------


이번 글에서는 엔진이 시작하기 까지의 Main 함수의 구성과 Engine System Class에 대해서 살펴보도록 하겠습니다.



아래의 winMain을 살펴보시면 간단하게 다음과 같습니다.

#include "stdafx.h"
// winmain.cpp : 응용 프로그램에 대한 진입점을 정의합니다.
#define _CRTDBG_MAP_ALLOC // for detecting memory leaks
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h> // for detecting memory leaks
#include <crtdbg.h> // for detecting memory leaks
#include "engineSystem.h"
// Function prototypes
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
EngineSystem engine;
//global
HWND g_hWndEngine = nullptr;
Graphics* g_Graphics = nullptr;
MainNode* g_MainNode = nullptr;
WNDCLASSEX g_wcx;
bool g_EngineShutDown = false;
//=============================================================================
// Starting point for a Windows application
//=============================================================================
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// Check for memory leak if debug build
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
if (!engine.engineStart(hInstance, nCmdShow))
return 1;
return engine.run();
}
view raw winmain.cpp hosted with ❤ by GitHub


메인의 구성은 간단하게 EngineSystem Class 하나를 갖고 있고


WINAPI WinMain( ) 함수가 실행되면서 프로그램의 진입점이 정의되어 있습니다.



그리고 그 외 갖가지 글로벌 변수들에 대한 초기화가 이루어져 있습니다.


글로벌 변수들에 대한 설명은 추후 stdafx.h (미리 컴파일 된 헤더) 를 설명 할때 같이 설명하도록 하겠습니다.



    // Check for memory leak if debug build

    #if defined(DEBUG) | defined(_DEBUG)

        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    #endif


는 메무리 누수가 발생했을 시 디버그 모드 환경에서 결과를 출력하기 위해 사용하는 함수 입니다.


프로그램이 종료 시 프로젝트에서 누수 된 메모리 주소영역들이 우르르 나오게 됩니다.


해당 누수 된 메모리를 체이스 하는 방법에 대해서는 별도의 글로 적어놓도록 하겠습니다.


if (!engine.engineStart(hInstance, nCmdShow))

return 1;

위와 같이 EngineStart 함수를 호출하고 return 받은 값이 true 이면


아래의 return engine.run();


함수를 호출하여 엔진을 Run 시킵니다.


이번 글에서는 간단히 메인만 남겨두고 계속해서 다음 글로 적어나가도록 하겠습니다.

(왠만하면 클래스 별로 글을 나눠서 올릴 예정입니다)

'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
June_Engine #1_EngineSystem  (0) 2017.04.06
June_Engine #1_메뉴얼(Manual)  (0) 2017.04.05
posted by REDFORCE 2017. 4. 5. 17:13

본 글은 2D Game Engine(이하 June_Engine)에 대한 설명 글 입니다.


June Engine의 메뉴얼은 여러 번의 포스팅으로 나눠서 정리 될 예정이며

소스 코드 재작성 / 자유로운 사용 여부 / 상업적인 목적 등

어떠한 저작권 문제도 삼지 않으니 자유로이 이용하셔도 됩니다.

다만 본 엔진을 사용 또는 참조 시 출처에 대해서 본 블로그에서 참조 하였음을 꼭 기재하여 주셨으면 합니다.


(저자 : 은고 / redforce01@naver.com)



※ 엔진에 대한 각 항목별 설명은 다음 포스트부터 이어집니다.
이하 아래 내용은 June Engine에 대해서 간략히 설명합니다.


1. Introduced

 - 본 엔진은 WinAPI 기반 DirectX를 활용하여 제작한 2D Game Engine 입니다.
교재 2D Game Programming(저자 : 찰스 캘리. 에이콘)을 참고하여 직접 여러 항목들을 개발해가며 제작하였습니다.


 - 프로젝트 코드는 Github에서 다운로드 할 수 있습니다. (링크 : DirectX_Engine)


현재 제공하는 기능에 대한 내용을 간단히 정리하면 다음과 같습니다.


 + Rendering (2D Image / 2D Animation 지원)

 + 자동 리소스 입력(프로젝트 시작 시 Resource 폴더 검사)

 + 2D UI Framework 제공(Button / Tab / ProgressBar / Frame / Text 등)

 + 멀티 쓰레드 환경 제작 지원(Core Thread / Worker Thread 분리)

 + Key 입력 처리

 + Game Scene 관리

 + Graphics Class를 통한 DirectX 생성(설명은 메뉴얼 참조바랍니다)

 


※ 주의 사항들


 + Sound 입출력은 지원하지 않습니다(추후 FMOD를 탑재할 예정)

 + Auto Resource Check 코드는 1단계 폴더까지만 검색합니다(다단계 폴더 지원은 예정 없음)

 + 일부 프레임워크의 코드 또는 엔진이 동작함에 있어 버그가 있을 수 있습니다.
    버그 발견 시 문의 주시면 해당 버그를 개선 및 고치는데 노력하도록 하겠습니다.



2. Content

 - 프로젝트 폴더 별, 주요 항목들은 다음과 같이 분류 됩니다.


 - Framework

  + Console (InGame Console 창)

  + Game (Game Scene)

  + GameInterface (Game User Interface)

  + Grahpics (DirectX Graphics)

  + Image (2D Image)

  + Input (Key Input)

  + Manager (Framework Managers)

  + Text (InGame Text)

  + Util (Framework Utilities)


 - Engine Managers (현재 미 포함)

  + Component Based 방식을 지원할 예정이었으나 아직 개발중..


 - System Code

  + Engine Main

  + Engine Core

  + Engine Worker Thread

  + Engine GameNode


 - Testing Module

  + Scene Test

  + Interface Test

  + Tab Test

  + 2D Image Test

  + 2D Animation Test



3. 추후 업데이트 예정 항목

 - 아래 항목은 시간 나는대로 개발 할 의사가 있는 내용들 입니다.


 - Framework

  + SoundManager(FMOD)

  + Excel File Loader


 - InGame Code

  + Zoom In/Out Control Function

  + Camera Function

  + InGame ScreenShot Function


 - MapTool

  + Isometric / Rectangle Tile 지원

  + Win32 API Interface Framework 지원

'MyProject > SephyEngine' 카테고리의 다른 글

June_Engine #1_EngineError.h  (0) 2017.04.07
June_Engine #1_EngineCore.cpp (2)  (0) 2017.04.07
June_Engine #1_EngineCore.h (1)  (0) 2017.04.06
June_Engine #1_EngineSystem  (0) 2017.04.06
June_Engine #1_WinMain  (0) 2017.04.06