Уроки Коммент.

Создание игр » DirectX 9, Featured » Создание игры. Графический движок.

Создание игры. Графический движок.

Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D Вообще, тема создания собственного графического движка для игры достаточно больная и давно заезженная. Я решил включить её в уроки на моём блоге, т.к. многие всё равно, так или иначе, возьмутся делать собственный графический движок. Кроме того, это блог в том числе по программированию графики, потому лишним не будет. Ну и, конечно, создание игры, особенно достаточно простой, нередко подразумевает и создание граф. движка, т.к. простой движок создать достаточно не сложно, а времени сэкономить он может кучу.

Со своей стороны обещаю, что наш графический движок не будет многоруким шивой и мы создадим его максимально компактным и простым. А так же, что на создание этого графического движка для игры у нас не уйдёт слишком много времени – нам же надо в первую очередь сделать игру, а не графический движок.

Итак, какой же минимум работы мы сможем поручить созданному нами графическому движку для игры? Давайте прикинем, что бы нам хотелось:

  • Что бы весь код инициализации графики был скрыт в самом движке.
  • Что бы движок загружал для нас текстуры и шейдеры
  • Если вдруг произошёл LostDevice (например, такое бывает при запуске скринсейвера или блогкировке компа), что бы движок сам восстанавливал все нужные данные (например, текстуры).
  • Мы хотим одной функцией завершать всю работу с графикой и выгружать все ресурсы

Пока этого хватит.

Итого получается, текстура:

class CTexture
{
	// класс Graphics будет иметь доступ к protected-членам
	friend class Graphics;
 
private:
	//! файл текстуры
	std::wstring m_strTexSrc;
	//! это сама текстура
	LPDIRECT3DTEXTURE9 m_pTex;
 
protected:
	// доступ только для класса Graphics
	CTexture(void);
	~CTexture(void);
	void SetTexture(LPDIRECT3DTEXTURE9 pTex);
	void SetSrc(const std::wstring& src);
	LPDIRECT3DTEXTURE9 GetTexture() const;
public:
	std::wstring GetSrc() const;
};
 
typedef CTexture* CTexturePtr; // тип указателей на текстуру

Шейдеры:

class CShader
{
	friend class Graphics;
 
private:
	//! Это пиксельный шейдер?
	bool m_bIsPS;
	//! Здесь ошибки омпиляции
	LPD3DXBUFFER m_pErrors;
	//! Здесь скопилированый шейдер
	LPD3DXBUFFER m_pShaderBuff;
	//! Таблица констант шейдера
	LPD3DXCONSTANTTABLE m_pConstTable;
	//! вертексный и писельный шейдер. экономим память
	union
	{
		LPDIRECT3DPIXELSHADER9 m_pPixelShader;
		LPDIRECT3DVERTEXSHADER9 m_pVertexShader;
 
	} m_pShader;
 
	//! Девайс, в котором создан шейдер
	LPDIRECT3DDEVICE9 m_pShaderDevice;
 
protected:
	//! Функция загрузки и компиляции шейдера
	HRESULT Load( const std::string& strFileName,
		const std::string& strFuncName, const std::string& profile);
	HRESULT Release();
	//! Получение пиксельного шейдера
	LPDIRECT3DPIXELSHADER9 GetPixelShader();
	//! Поулчение вертексного шейдера
	LPDIRECT3DVERTEXSHADER9 GetVertexShader();
	//! Получение буфера скомпилированого шейдера 
	//! нужно для создания HW-шейдера
	LPD3DXBUFFER GetCompileBuffer();
	//! Установка HW-шейдера (пиксельного)
	void SetHardwareShader(LPDIRECT3DDEVICE9 pDev, 
		LPDIRECT3DPIXELSHADER9 pHWShader);
	//! Установка HW-шейдера (вертексного)
	void SetHardwareShader(LPDIRECT3DDEVICE9 pDev, 
		LPDIRECT3DVERTEXSHADER9 pHWShader);
	CShader(void);
	~CShader(void);
 
public:
	bool IsPS(); // это пиксельный шейдер?
	bool IsVS(); // или это вертексный шейдер?
	//! Функция задания матрицы
	HRESULT SetFloat(D3DXHANDLE hConstant, CONST FLOAT Value);
	HRESULT SetVector(D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVec4);
	HRESULT SetMatrix(D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix);
};
 
typedef CShader* CShaderPtr; // тип указателей на текстуру

Кода, вроде, немало, но, мне кажется, всё должно быть понятно из комментариев. Мы вынесли текстуры и шейдеры в отдельные классы, что бы полностью скрыть их реализацию от пользователя движка – так в дальнейшем будет проще программировать. Кроме того, мы сможем не думать о таких вещах, как загружена ли уже нужная нам текстура, что делать при LostDevice и так далее. В общем, просто удобство и, следовательно, скорость программига в будущем.

Теперь сам графический движок:

class Graphics : public singleton<Graphics>
{
	friend class singleton<Graphics>;
private:
	LPDIRECT3D9 m_pD3D;
	LPDIRECT3DDEVICE9 m_pd3dDevice;
 
	// структкура с параметрами девайса
	D3DPRESENT_PARAMETERS m_d3dpp;
 
	typedef std::vector<CTexturePtr> vecTextures;
	vecTextures m_vecTextures;
 
	typedef std::vector<CShaderPtr> vecShaders;
	vecShaders m_vecShaders;
 
protected:
	Graphics(void);
	~Graphics(void);
	LPDIRECT3DDEVICE9 GetDevice();
 
public:
	bool Init(HWND hRenderWnd, int width, int height);
	void Cleanup();
	HRESULT Reset();
	bool StartRender();
 
	HRESULT SetFVF(DWORD FVF);
	HRESULT SetPixelShader(CShaderPtr shader);
	HRESULT SetVertexShader(CShaderPtr shader);
	HRESULT SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
	HRESULT SetSamplerState(DWORD Sampler, 
		D3DSAMPLERSTATETYPE Type, DWORD Value);
	HRESULT SetTexture(DWORD stage, CTexturePtr pTex);
	HRESULT DPUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, 
		CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
	//! Функция отрисовки спрайта в заданных координатах\
	и с заданными размерами
	HRESULT DrawSprite(CTexturePtr pTex, D3DXVECTOR2 pos, D3DXVECTOR2 size);
 
	bool EndRender();
	CTexturePtr LoadTexture(const std::wstring& szFileName);
	CShaderPtr LoadShader( const std::string& strFileName, 
		const std::string& strFuncName, const std::string& profile);
};

Для начала нам этого хватит. Конечно, этот получился очень примитивный движок – в нём нет умных указателей, счётчиков ссылок, нет приоритетов ресурсов, нет многопоточности, нет даже элементарной возможности выгрузить уже не нужную текстуру. Но нам это сейчас и не нужно. В следующих уроках мы будем постепенно наращивать возможности и, со временем, получим достаточно универсальный и удобный движок. Текущих же возможностей нам вполне хватит для создания несложных игр. А это, согласитесь, уже немало, учитывая, что на всё про всё мы потратили всего полчаса работы…

P/S Исходики к статье будут в следующем уроке, где мы сделаем летающий корабль игрока.

Поддержите нас! Расскажите о этом сайте друзьям:
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
  • Создание игры. Графический движок. Создание игр Создание движка Vertex shader Pixel shader Direct3D
Ещё по этой теме:




Раздел: DirectX 9, Featured · Теги: Direct3D, Pixel shader, Vertex shader, Создание движка, Создание игр

6 комментариев на "Создание игры. Графический движок."
  1. Scripter пишет:

    супер :)

  2. Antony пишет:

    Вопрос по коду, в цикле, где обрабатываются windows message и код игры, мы каждый кадр заново устанавливаем все матрицы, рендер стейты и прочее.
    А почему нельзя это выставить один раз перед тем, как войти в цикл?

    1. Вячеслав пишет:

      Antony, вынести это всё можно и вызывать однократно тоже можно. Но:
      1) в реальной боле-мене сложной игре это скорее всего не получится, т.к. там куча изменений стейтов и матриц во время рендера каждого кадра
      2) если таким образом вы надеетесь “прооптимизировать” программу – не стоит, толку (буста) от этого не будет

  3. Даниил пишет:

    А можно написать в какой очереди их читать а то как то непонятно где 1 урок, а где 2

    1. Вячеслав пишет:

      Читать просто от старых уроков к новым. Справа в меню есть так же “Уроки DirectX” и “Уроки создания игр” – там последовательность чтения указана.

  4. Даниил пишет:

    спасибо ещё 1 вопросик wstring это какой файл подключать?

Оставить комментарий

*

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">