ПрограммированиеФорумОбщее

Вопросы новичка по постройке движка

Страницы: 1 2 3 Следующая »
#0
21:16, 3 мая 2010

Уважаемые корифеи игростроя!
Я пытаюсь учиться в построении своего игрового движка. При этом использую книги.
На данный момент -- это "Искусство программирования игр на С++" (Михаил Фленов)[2006]

Но по ходу возникают проблемы, которые я решить не в состоянии.

Я думаю, что не одинок в таком положении. Поэтому тема может быть интересна и другим новичкам игростроя.

По ходу буду задавать вопросы.

Заранее ОЧЕНЬ ПРИЗНАТЕЛЕН тем, кто даст ясные и понятные комменты и разъяснения.

Вопрос №1.

При инициализации Direct3D не работает режим fullscreen. программа вылетает с ошибкой.

Вот исходники:

1_Step

Что там нужно изменить или добавить?

ЗЫ. Да, забыл сказать, что у меня Виста(SP2)  стоит на рабочей машине.

#1
22:57, 3 мая 2010

vkd
выкладывай сорсы сюда, влом что-то качать

#2
23:35, 3 мая 2010

Mimon
> выкладывай сорсы сюда, влом что-то качать
вот первая часть


#pragma once

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3dxof.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "winmm.lib")


#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <mmsystem.h>  //    подключаем системную библиотеку
#include <d3dx9core.h>  //    подключаем заголовочный файл для работы со шрифтом
#include <d3dx9Mesh.h>  //   

// Global Variables:
char szWindowClass[] = "Direct3DTemplateProj";
char szTitle[] = "Direct3D";

// Direct3D objects
IDirect3D9 *pD3D = NULL;
IDirect3DDevice9 *pD3DDevice = NULL;

int iWidth=800;
int iHeight=600;

// Функция инициализации Direct3D
HRESULT DX3DInit(IDirect3D9 **ppiD3D9,
                IDirect3DDevice9 **ppiD3DDevice9,
                HWND hWnd,
        DWORD iWidth,
        DWORD iHeight,
        BOOL bFullScreen)
{
  // Инициализация
  if((*ppiD3D9 = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    return E_FAIL;

  // Заполняем основные параметры представления
  D3DPRESENT_PARAMETERS d3dpp;
  ZeroMemory(&d3dpp, sizeof(d3dpp));

  d3dpp.BackBufferWidth = iWidth;
  d3dpp.BackBufferHeight = iHeight;

  // Запрос на отображение в полноэкранном режиме
  int  iRes;
  if (!bFullScreen)
      iRes=MessageBox(hWnd, "Use fullscreen mode?", "Screen", MB_YESNO | MB_ICONQUESTION);
  else
    iRes = IDYES;


  if(iRes == IDYES)
  {

    // Полноэкранный режим

    // Установка параметров полноэкранного режима
      d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
    d3dpp.SwapEffect      = D3DSWAPEFFECT_FLIP;
    d3dpp.Windowed        = FALSE;
      d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
      d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  }
  else
  {

    // Оконный режим

    RECT wndRect;
      RECT clientRect;
    GetWindowRect(hWnd, &wndRect);
      GetClientRect(hWnd, &clientRect);   

    iWidth  = iWidth + (wndRect.right-wndRect.left)  - (clientRect.right-clientRect.left);
    iHeight = iHeight + (wndRect.bottom-wndRect.top) - (clientRect.bottom-clientRect.top);

    MoveWindow(hWnd, wndRect.left, wndRect.top, iWidth, iHeight, TRUE);

    // Получить формат пикселя
    D3DDISPLAYMODE d3ddm;
    (*ppiD3D9)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

    // Установка параметров
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.SwapEffect      = D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed        = TRUE;
  }
 
  DWORD Flags= D3DCREATE_MIXED_VERTEXPROCESSING;

  // Создать 3D устройство
  HRESULT hRes;
  if(FAILED(hRes = (*ppiD3D9)->CreateDevice(
    D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL, hWnd, Flags,
    &d3dpp, ppiD3DDevice9)))
    return hRes;

  // Установить перспективу
  float Aspect = (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight;
  D3DXMATRIX matProjection;
  D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4.0f, Aspect, 0.001f, 1000.0f);
  (*ppiD3DDevice9)->SetTransform(D3DTS_PROJECTION, &matProjection);

  (*ppiD3DDevice9)->SetRenderState(D3DRS_LIGHTING, FALSE);

  return S_OK;
}

HRESULT DX3DInitZ(IDirect3D9 **ppiD3D9,
                IDirect3DDevice9 **ppiD3DDevice9,
                HWND hWnd,
        DWORD iWidth,
        DWORD iHeight,
        BOOL bFullScreen)
{
  // Инициализация
  if((*ppiD3D9 = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    return E_FAIL;

  // Заполняем основные параметры представления
  D3DPRESENT_PARAMETERS d3dpp;
  ZeroMemory(&d3dpp, sizeof(d3dpp));

  d3dpp.BackBufferWidth = iWidth;
  d3dpp.BackBufferHeight = iHeight;
  d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
  d3dpp.EnableAutoDepthStencil = TRUE;

  // Запрос на отображение в полноэкранном режиме
  int  iRes;
  if (!bFullScreen)
      iRes=MessageBox(hWnd, "Use fullscreen mode?", "Screen", MB_YESNO | MB_ICONQUESTION);
  else
    iRes = IDYES;

  if(iRes == IDYES)
  {

    // Полноэкранный режим

    // Установка параметров полноэкранного режима
      d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
    d3dpp.SwapEffect      = D3DSWAPEFFECT_FLIP;
    d3dpp.Windowed        = FALSE;
      d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
      d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  }
  else
  {

    // Оконный режим

    RECT wndRect;
      RECT clientRect;
    GetWindowRect(hWnd, &wndRect);
      GetClientRect(hWnd, &clientRect);   

    iWidth  = iWidth + (wndRect.right-wndRect.left)  - (clientRect.right-clientRect.left);
    iHeight = iHeight + (wndRect.bottom-wndRect.top) - (clientRect.bottom-clientRect.top);

    MoveWindow(hWnd, wndRect.left, wndRect.top, iWidth, iHeight, TRUE);

    // Получить формат пикселя
    D3DDISPLAYMODE d3ddm;
    (*ppiD3D9)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

    // Установка параметров
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.SwapEffect      = D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed        = TRUE;
  }
 
  DWORD Flags= D3DCREATE_MIXED_VERTEXPROCESSING;

  // Создать 3D устройство
  HRESULT hRes;
  if(FAILED(hRes = (*ppiD3D9)->CreateDevice(
    D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL, hWnd, Flags,
    &d3dpp, ppiD3DDevice9)))
    return hRes;

#3
23:36, 3 мая 2010

Mimon
> выкладывай сорсы сюда, влом что-то качать

вот вторая (продолжение) (я все в один файл слил)

// Установить перспективу
  float Aspect = (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight;
  D3DXMATRIX matProjection;
  D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4.0f, Aspect, 1.0f, 5000.0f);
  (*ppiD3DDevice9)->SetTransform(D3DTS_PROJECTION, &matProjection);

  (*ppiD3DDevice9)->SetRenderState(D3DRS_LIGHTING, TRUE);

  return S_OK;
}

DWORD LoadMesh(char *filename, IDirect3DDevice9 *ppiD3DDevice9,
        ID3DXMesh **ppMesh,
        LPDIRECT3DTEXTURE9 **pMeshTextures,
        char *texturefilename,
        D3DMATERIAL9 **pMeshMaterials
        )
{
  LPD3DXBUFFER pD3DXMtrlBuffer;
  DWORD dwNumMaterials;

  D3DXLoadMeshFromX(filename, D3DXMESH_SYSTEMMEM,
    ppiD3DDevice9, NULL, &pD3DXMtrlBuffer, NULL, &dwNumMaterials, ppMesh);

  D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();

  (*pMeshTextures) = new LPDIRECT3DTEXTURE9[dwNumMaterials];
  (*pMeshMaterials) = new D3DMATERIAL9[dwNumMaterials];

  for( DWORD i=0; i<dwNumMaterials; i++ )
  {
    // Копируем материал
    (*pMeshMaterials) = d3dxMaterials.MatD3D;

    // Создаем текстуру
    if( FAILED(D3DXCreateTextureFromFile(ppiD3DDevice9,
      d3dxMaterials.pTextureFilename, &(*pMeshTextures))))
      if( FAILED(D3DXCreateTextureFromFile(ppiD3DDevice9,
        texturefilename, &(*pMeshTextures)
)))
        (*pMeshTextures)
= NULL;
  }

//  (ID3DXMesh *)(*ppMesh)->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
  return dwNumMaterials;
}

bool LoadTexture(DWORD* text_buf, int iWidth, int iHeight, char* filename)
{
    HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);       
  if(hFile == INVALID_HANDLE_VALUE)
    return FALSE;

  BITMAPFILEHEADER bmpfilehdr; 
  DWORD dwRead;
  if(!ReadFile(hFile, &bmpfilehdr, sizeof(bmpfilehdr), &dwRead, NULL))
    return FALSE;
   
  char* ptr=(char*)&bmpfilehdr.bfType;
  if (*ptr!='B' || *++ptr!='M')
    return FALSE;

  BITMAPINFOHEADER bmpinfohdr;
  if(!ReadFile(hFile, &bmpinfohdr, sizeof(bmpinfohdr), &dwRead, NULL))
    return FALSE;

  if (bmpinfohdr.biCompression!=BI_RGB)
    return 0;

  int iImageSize=bmpinfohdr.biSizeImage;
  if (iImageSize==0)
    iImageSize=((iWidth*4+3) & ~3)*iHeight;

  BYTE* buf=new BYTE[iImageSize];
  if(!ReadFile(hFile, buf, iImageSize, &dwRead, NULL))
    return FALSE;

    if (bmpinfohdr.biBitCount!=24)
    return FALSE;

  int bytesgiven=(iWidth*3+3) & ~3;
  DWORD* btSurf = text_buf;
  BYTE* imagebits = (BYTE*)(&buf[(iHeight-1)*bytesgiven]);

  for (int i=0; i<iHeight; i++)
  {
    RGBTRIPLE* tlImage=(RGBTRIPLE*)imagebits;
    for (int p=0; p<iWidth; p++)
    {
      *btSurf = (DWORD)((tlImage->rgbtBlue) | (tlImage->rgbtGreen << 8) |
                  (tlImage->rgbtRed << 16) | (0xFF << 24));
      tlImage++;
      btSurf++;
    }
    imagebits -= bytesgiven;
  }

  delete [] buf;
  return TRUE;
}


// имя: DeleteDirect3D()
// назначение: освобождение захваченных ресурсов


VOID DeleteDirect3D()

{
    if (pD3DDevice)
    pD3DDevice -> Release();

    if  (pD3D)
    pD3D -> Release();
}

// Объявление фукций, включенных в этот модуль:

// Функция инициализации Direct3D
HRESULT DX3DInit(IDirect3D9 **ppiD3D9,
                IDirect3DDevice9 **ppiD3DDevice9,
                HWND hWnd,
        DWORD iWidth,
        DWORD iHeight,
        BOOL bFullScreen
        );

HRESULT DX3DInitZ(IDirect3D9 **ppiD3D9,
                IDirect3DDevice9 **ppiD3DDevice9,
                HWND hWnd,
        DWORD iWidth,
        DWORD iHeight,
        BOOL bFullScreen
        );

DWORD LoadMesh(char *filename, IDirect3DDevice9 *ppiD3DDevice9,
        ID3DXMesh **ppMesh,
        LPDIRECT3DTEXTURE9 **pMeshTextures,
        char *texturefilename,
        D3DMATERIAL9 **pMeshMaterials
        );

bool LoadTexture(DWORD* text_buf, int iWidth, int iHeight,
        char* filename);

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

bool Init(HWND hWnd);
void GraphEngine();

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
{
  WNDCLASSEX wcex;
  MSG        msg;
  HWND      hWnd;

  CoInitialize(NULL);

  // Register window class
  wcex.cbSize        = sizeof(wcex);
  wcex.style        = CS_CLASSDC;
  wcex.lpfnWndProc  = (WNDPROC)WndProc;
  wcex.cbClsExtra    = 0;
  wcex.cbWndExtra    = 0;
  wcex.hInstance    = hInst;
  wcex.hIcon        = LoadIcon(NULL, IDI_APPLICATION);
  wcex.hCursor      = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground = NULL;
  wcex.lpszMenuName  = NULL;
  wcex.lpszClassName = szWindowClass;
  wcex.hIconSm      = LoadIcon(NULL, IDI_APPLICATION);
  if(!RegisterClassEx(&wcex))
    return FALSE;

  // Create the main window
  hWnd = CreateWindow(szWindowClass, szTitle, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
              CW_USEDEFAULT, CW_USEDEFAULT, iWidth, iHeight, NULL, NULL, hInst, NULL);
  if(!hWnd)
    return FALSE;
  ShowWindow(hWnd, SW_NORMAL);
  UpdateWindow(hWnd);

  if(Init(hWnd) == TRUE)
  {
    while (true)
    {
      // если есть сообщение в очереди
      if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
      {
        // обработать сообщение
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        if (msg.message == WM_QUIT) break;
      }
      // Вызвать функцию движка игры
      GraphEngine();
    }
  }
// Освобождаем захваченные ресурсы:
  DeleteDirect3D();


  CoUninitialize();

  return 0;
}

// Реализации ф-ций:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message) {
    case WM_DESTROY:
            PostQuitMessage(0);         
            break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
  }

  return 0;
}

bool Init(HWND hWnd)
{
  if (DX3DInitZ(&pD3D, &pD3DDevice, hWnd, iWidth, iHeight, FALSE)!=S_OK)
  {
    MessageBox(hWnd, "DirectX Initialize Error", "Error", MB_OK);
    return FALSE;
  }

  return TRUE;
}

void GraphEngine()
{
  pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
  if (SUCCEEDED(pD3DDevice->BeginScene()))
  {
    pD3DDevice->EndScene();
  }


  pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

может все и не стоило приводить, да я так, на всякий случай...
код полностью рабочий за исключением вышеописанной проблемы.

#4
8:14, 4 мая 2010

vkd
> При инициализации Direct3D не работает режим fullscreen. программа вылетает с
> ошибкой.
А она у тебя вообще компилируется? Прежде, чем собрал модуль, исправил с десяток синтаксических ошибок.

После сборки и оконный, и фулскирин работают(!). Собственно, не понял: в чем проблема :) У тебя карточка сочетание D3DFMT_R5G6B5+D3DFMT_D24S8 поддерживает (проверь через IDirect3D9::CheckDepthStencilMatch())?

#5
19:33, 4 мая 2010

destrator
> А она у тебя вообще компилируется?

Компилится и работает нормально кроме режима fullscreen.
Видюха у меня GF 7000M. Что, может не поддерживать D3DFMT_R5G6B5+D3DFMT_D24S8 ?

Какие параметры вставлять в ф-цию IDirect3D9::CheckDepthStencilMatch()?

#6
19:46, 4 мая 2010

Это ж надо "для изучения" сразу прыгнуть в дебри Direct3D.
Скачай какой нибудь простой движок вроде HGE, разберись на нём сначала, он от тебя все тонкости интимных отношений с D3D спрячет.

#7
20:19, 4 мая 2010


kvakvs
> он от тебя все тонкости интимных отношений с D3D спрячет
вот этого как раз и не хочется! Я хочу научиться в ПРОЦЕССЕ!

#8
20:34, 4 мая 2010

vkd
> На данный момент -- это "Искусство программирования игр на С++" (Михаил
> Фленов)[2006]
Хорош прикалываться.
З.Ы.
Задай себе правильный вопрос - какой движок написал Михаил Фленов от 2006 года.
Вот такой же напишешь и ты.

#9
20:42, 4 мая 2010

vkd
Лучше Джим Адамса почитай, это реально лучше. (Джим Адамс Программирование ролевых игр с DirectX). Вроде на netlib онлайн библиотека есть
http://www.netlib.narod.ru/library/book0051/index.htm
сорцы качнул с инета.
В свое время я долго и мучительно  искал ошибки, когда у меня была такая же проблема.

#10
20:45, 4 мая 2010

vkd
> "Искусство программирования игр на С++" (Михаил Фленов)[2006]
Плохая книга. Точнее я ее не читал, но автор не крутой.

Тебе нужно учиться по вот таким примерно урокам.
http://www.codesampler.com/dx9src.htm
Просто и понятно.
Раньше еще был сайт ultimategameprogramming.com но сейчас он мертв. Поищи может найдешь уроки с него.
Еще есть gametutorials платный, но CD можно найти на торрентах.

#11
20:48, 4 мая 2010

graveman
Pokimon
Спасибо! Сейчас буду смотреть.

#12
22:13, 4 мая 2010

Pokimon
> Плохая книга. Точнее я ее не читал, но автор не крутой.
Ты прям стереотип ходячий xD

#13
22:30, 4 мая 2010

d.m.k
> Ты прям стереотип ходячий xD
Что Вы имеете ввиду?

#14
22:57, 4 мая 2010

graveman
> Лучше Джим Адамса почитай, это реально лучше. (Джим Адамс Программирование
> ролевых игр с DirectX). Вроде на netlib онлайн библиотека есть
> http://www.netlib.narod.ru/library/book0051/index.htm

Она реально лучше?

> сорцы качнул с инета.

Где?

> В свое время я долго и мучительно искал ошибки, когда у меня была такая же
> проблема.

Решились благодаря этой книге?

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.