Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Небесная оболочка(SkyBox)  (Прочитано 18052 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Booch
Гость
« : 09-11-2009 15:57 » 

Всем привет, вот решил создать класс небесной оболочки, используя файл эффекта из "Кнут"а.
После нескольких дней мучений, иправления тонны ошибок , просмотра десятков сайтов по этой тематике дошёл до того что эффект рисует этот куб, но кубическая текстура ресуется только с одной стороной, неправильно повёрнута да ещё и занимает 1/4 стороны куба...ППЦ


Вот файл класса куба

sky_model.cpp
Код:
#include "sky_model.h"

struct Vertex
{
Vertex(){}
Vertex(
float x, float y, float z
  )
{
_x  = x;  _y  = y;  _z  = z;
}
float _x, _y, _z;
};
#define FVF_VERTEX (D3DFVF_XYZ)

cSkyModel::cSkyModel(IDirect3DDevice9* device, Camera* TheCamera)
{
Device = device;
D3DXMatrixIdentity(&_world);
_bgtexture = 0;
_SkyBoxEffect = 0;

_WorldViewProjHandle = 0;

_TexHandle = 0;
_SkyBoxTechHandle = 0;
D3DXMatrixIdentity(&_WorldViewProj);

_TheCamera = TheCamera;
}

cSkyModel::~cSkyModel()
{
if(_vb){_vb->Release(); _vb = 0;}
if(_ib){_ib->Release(); _ib = 0;}
if(_bgtexture) _bgtexture->Release();

// Device->Release(); // закомить- иначе ошибка gпри закрытии приложения, уберается один раз
}

bool cSkyModel::CreateCube( void )
{
Device->CreateVertexBuffer(
24 * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
FVF_VERTEX,
D3DPOOL_MANAGED,
&_vb,
0);

Vertex* v;
float W=1.0f, H=1.0f, L=1.0f;
_vb->Lock(0, 0, (void**)&v, 0);

// build box

// fill in the front face vertex data
v[0] = Vertex( -W, -H, -L);
v[1] = Vertex( -W,  H, -L);
v[2] = Vertex(  W,  H, -L);
v[3] = Vertex(  W, -H, -L);

// fill in the back face vertex data
v[4] = Vertex( -W, -H,  L);
v[5] = Vertex(  W, -H,  L);
v[6] = Vertex(  W,  H,  L);
v[7] = Vertex( -W,  H,  L);

// fill in the top face vertex data
v[8]  = Vertex( -W,  H, -L);
v[9]  = Vertex( -W,  H,  L);
v[10] = Vertex(  W,  H,  L);
v[11] = Vertex(  W,  H, -L);

// fill in the bottom face vertex data
v[12] = Vertex( -W, -H, -L);
v[13] = Vertex(  W, -H, -L);
v[14] = Vertex(  W, -H,  L);
v[15] = Vertex( -W, -H,  L);

// fill in the left face vertex data
v[16] = Vertex( -W, -H,  L);
v[17] = Vertex( -W,  H,  L);
v[18] = Vertex( -W,  H, -L);
v[19] = Vertex( -W, -H, -L);

// fill in the right face vertex data
v[20] = Vertex(  W, -H, -L);
v[21] = Vertex(  W,  H, -L);
v[22] = Vertex(  W,  H,  L);
v[23] = Vertex(  W, -H,  L);

_vb->Unlock();

Device->CreateIndexBuffer(
36 * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&_ib,
0);

WORD* i = 0;
_ib->Lock(0, 0, (void**)&i, 0);

// fill in the front face index data
i[0] = 0; i[1] = 1; i[2] = 2;
i[3] = 0; i[4] = 2; i[5] = 3;

// fill in the back face index data
i[6] = 4; i[7]  = 5; i[8]  = 6;
i[9] = 4; i[10] = 6; i[11] = 7;

// fill in the top face index data
i[12] = 8; i[13] =  9; i[14] = 10;
i[15] = 8; i[16] = 10; i[17] = 11;

// fill in the bottom face index data
i[18] = 12; i[19] = 13; i[20] = 14;
i[21] = 12; i[22] = 14; i[23] = 15;

// fill in the left face index data
i[24] = 16; i[25] = 17; i[26] = 18;
i[27] = 16; i[28] = 18; i[29] = 19;

// fill in the right face index data
i[30] = 20; i[31] = 21; i[32] = 22;
i[33] = 20; i[34] = 22; i[35] = 23;

_ib->Unlock();


//////////////////////////////////////////////////////////////////////
//
    // Создание эффекта
    //
    HRESULT hr = 0;
ID3DXBuffer* errorBuffer = 0;
    hr = D3DXCreateEffectFromFile(
           Device,           // связанное устройство
           "simple_skybox.fx",  // имя файла эффекта
           0,                // нет определений препроцессора
           0,                // нет интерфейса ID3DXInclude
           D3DXSHADER_DEBUG, // флаги компиляции
           0,                // нет совместного использования параметров
           &_SkyBoxEffect,   // возвращает указатель на интерфейс эффекта
           &errorBuffer);    // возвращает сообщения об ошибках

    // Выводим любые сообщения об ошибках
    if(errorBuffer)
    {
         ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
errorBuffer->Release();
    }

    if(FAILED(hr))
    {
          ::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0);
          return false;
    }

    //
    // Сохраняем дескрипторы часто используемых параметров
    //
    _SkyBoxTechHandle  = _SkyBoxEffect->GetTechniqueByName("BasicCubeMap");
_WorldViewProjHandle = _SkyBoxEffect->GetParameterByName(0, "mWorldViewProj");
    _TexHandle         = _SkyBoxEffect->GetParameterByName(0, "tex0");

    //
    // Устанавливаем параметры эффекта
    //
    // Матрица
    _SkyBoxEffect->SetMatrix(_WorldViewProjHandle, &_WorldViewProj);
    // Текстура
hr = D3DXCreateTextureFromFile(Device, "models/skybox1.dds", &_bgtexture); //skybox1.dds
if(FAILED(hr) )
{
::MessageBox(0, "SkyBox->D3DXCreateTextureFromFile() - FAILED", 0, 0);
          return false;
}
    _SkyBoxEffect->SetTexture(_TexHandle, _bgtexture);   

return true;
}


bool cSkyModel::render(bool wireframe)
{

Device->SetTransform(D3DTS_WORLD, &_world);

// Устанавливаем используемую технику
_SkyBoxEffect->SetTechnique(_SkyBoxTechHandle);
    UINT numPasses = 0;
   
_SkyBoxEffect->Begin(&numPasses, 0); // техника, пуск

// Устанавливаем переменные эффекта
_TheCamera->getSkyBoxMatrix(&_WorldViewProj, Device);
_SkyBoxEffect->SetMatrix(_WorldViewProjHandle, &_WorldViewProj);
   
for(int i = 0; i < numPasses; i++)
    {

_SkyBoxEffect->BeginPass(i); // техника, проход

Device->SetStreamSource(0, _vb, 0, sizeof(Vertex));
Device->SetIndices(_ib);
Device->SetFVF(FVF_VERTEX);
Device->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,                 
0,                 
24,
0,
12); 

}
    _SkyBoxEffect->End(); // техника остановка


D3DXMATRIX I;
D3DXMatrixIdentity(&I);
Device->SetTransform(D3DTS_WORLD, &I);

return true;
}

sky_model.h
Код:
#ifndef __sky_modelH__
#define __sky_modelH__

#include <string>
#include <vector>
#include "camera.h"

class cSkyModel
{
public:
cSkyModel(IDirect3DDevice9* device, Camera* TheCamera);
~cSkyModel();

bool CreateCube( void );
bool render(bool wireframe);

private:

IDirect3DDevice9* Device;
D3DXMATRIX _world;

IDirect3DVertexBuffer9* _vb;
IDirect3DIndexBuffer9* _ib;
// Effect
IDirect3DTexture9* _bgtexture; //текстура куба
Camera* _TheCamera;
ID3DXEffect* _SkyBoxEffect;
D3DXHANDLE _WorldViewProjHandle;
D3DXHANDLE _TexHandle;
D3DXHANDLE _SkyBoxTechHandle;
D3DXMATRIX _WorldViewProj;

};
#endif //CSKYBOX_H

Класс использует камеру(с огромным количеством ненужного кода), которая уже обсуждалась (где-то здесь я видел её, поэтому её код
приложен но не обсуждается), её задача заключается в создании и передаче матрицы SkyBox эффекту(функция  Camera::getSkyBoxMatrix).

чтобы запустить эту белиберду Да-да в приложении нужно в...
 своём главном файле включить заголовки
Код:
#include "sky_model.h"
#include "camera.h"

определить класс камеры и скайбокса
Код:
Camera   TheCamera(Camera::LANDOBJECT);
cSkyModel* _SkyModel;

далее где-нибудь настроить камеру  и создать скайбокс (один раз Улыбаюсь)
Код:
TheCamera.setProjParam( Device, D3DX_PI * 0.25f, (float)Width/(float)Height, 0, 0);
Width - ширина экрана
Height - высота

// create skymodel
_SkyModel = new cSkyModel(_device, TheCamera);
if ( !_SkyModel->CreateCube() )
{
::MessageBox(0, "_SkyModel->CreatePMesh - FAILED", 0, 0);
::PostQuitMessage(0);
}

Перед рендерингом
Код:
TheCamera.ReadInput(timeDelta);	
// timeDelta - может быть любое число например 0.7f ("чувствительность" камеры)
// Update the view matrix representing the cameras new position/orientation.
TheCamera.useCamera( Device );

теперь в функции рендеринга
Код:
if(_SkyModel)
_SkyModel->render(false);

вот кажется и всё разжевал С ума сойти...... а да ещё надо при завершении приложения реализовать класс _SkyModel, но это уж как-нибудь сами)
файл эффекта во вложениях, а кубическую текстуру(models/skybox1.dds) , к сожалению не могу передать, слишком много весит Жаль

Мне кажется с матрицей, что передается в эффект(Camera::getSkyBoxMatrix) что-то не так А черт его знает...

* Camera.zip (4.2 Кб - загружено 1169 раз.)
* skybox_prscreen.jpg (82.4 Кб - загружено 1315 раз.)
* simple_skybox.fx (1.52 Кб - загружено 1225 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 10-11-2009 04:36 » 

Booch, и ты полагаешь, всем есть время и желание сидеть и собирать твою программу по кусочкам, чтобы понять, в чём причина ? Улыбаюсь
Приложи рабочий проект, удалив из него лишнее (коммерческие секреты, папку release, debug, файл *.ncb)
Записан

Booch
Гость
« Ответ #2 : 10-11-2009 17:02 » 

Хорошо извиняюсь...
Вот чистый проект. Только "нужные" файлы.
Остаётся собрать  и подключить  библиотечки :
d3d9.lib
d3dx9.lib
winmm.lib
Всё, кроме трёхмерной текстуры, которую можно взять из примеров  DirectX SDK (March 2009)\Samples\C++\Direct3D\StateManager\Media\skybox02.dds

Только там не понятно где низ ,а где верх т.к. кроме скайбокса больше ничего не рисуется)

* sky_box.zip (10.76 Кб - загружено 1208 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 11-11-2009 04:22 » 

эхъ... Вот, сделал за тебя работу: создал новый проект, вставил туда файлы, добился положительной компиляции и запуска. Ничего пока не исправлял, немного занят. Покумекай, почему пока что вообще ничего не видно Улыбаюсь

да и запускается только полноэкранный вариант

* test_sky.rar (17.26 Кб - загружено 1207 раз.)
Записан

Booch
Гость
« Ответ #4 : 11-11-2009 14:12 » new

Дык, есть более быстрый и читерский способ собирания проетов в VS. Да-да
У меня VS2008 : Фаыл->Создать проект из существующего кода....
  а потом только указать каталог (где лежат эти .cpp , .h) и название проекта, "далее" "готово" и всё, только либы подключить.
 Поэтому я больше ничего не вложил в архив.

Проект работает как и у меня , после копирования текстуры из
Код:
DirectX SDK (March 2009)\Samples\C++\Direct3D\StateManager\Media\skybox02.dds

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

Я пробовал поменять местами в файле эффекта xyz  в этой строке
simple_skybox.fx
Код:
Out.vTex0 = v.Pos.xzy;
это в вершинном шейдере, но к сожалению эффект не в лучшую сторону, просто меняется положение текстуры на кубе((

* test_sky_printscreen.jpg (83.92 Кб - загружено 1269 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 12-11-2009 04:04 » 

Цитата
Дык, есть более быстрый и читерский способ собирания проетов в VS
У меня VS2008 : Фаыл->Создать проект из существующего кода....
 а потом только указать каталог (где лежат эти .cpp , .h) и название проекта, "далее" "готово" и всё, только либы подключить.

один фиг, руками всё то же самое ) Зато точно знаю, что куда впихнул, а не полагаться на визард Ага



Ну с этим разобрались, запустилось, вертится. Сейчас я занят, вечером попробую поразбираться, если что получится - завтра отпишусь
Заранее предупреждаю - я сам ещё чайник в директе )) Но разобраться интересно
Записан

Booch
Гость
« Ответ #6 : 14-11-2009 11:53 » 

Ок спс, я ещё посмотрю, может где есть хорошее объяснение этой штуки.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 14-11-2009 11:56 » 

я ещё не брался даже, всё некогда ((
Записан

Booch
Гость
« Ответ #8 : 22-11-2009 10:42 » 

Так всё, разобрался. Надо было правильно загружать кубическую текстуру Да-да
Правильный проект приложен(без кубической текстуры skybox02 из Microsoft DirectX SDK (March 2009))


* test_skybox.zip (19.03 Кб - загружено 1274 раз.)
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 22-11-2009 11:43 » 

Offtopic:
Booch, картинки лучше прикладывать к посту, т.к. сервисах, на подобных imageshack, они живут не долго. Чтобы потом картинка не просто висела атачем, а отобразилась в посте, после сохранения поста скопируй ссылку на атач и отредактируй сообщение еще раз, вставив в нужное место тег [img]url твоего атача[/img].
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines