Проба пера на C++ и DX11

Добавлен , опубликован
Программирование
Язык:
C++
Добрый вечер.
Как я уже говорил, я разделяю своё свободное время по проектам. Одну неделю в один, другую в другой. И на этой неделе я займусь изучение Cpp и Direct X SDK 11 (June 2010).
Изучением Cpp я уже давно хотел заняться, но не решался. Да и тема рендера 3D графики меня интересует уже давно, еще года 3 назад, я изучал Direct X 9 на Delphi. Я даже далеко зашел, но натолкнулся на одну неисправность в SDK для Delphi, что меня сильнее натолкнуло на изучение Cpp. В общем пару месяцев назад, я все таки решил учить Cpp. Ну и как обычно решил начать изучение не с простого, там "Hello world", а уже с чего то серьёзного.
Вооружившись книгами и документацией по DX 11 решил попробовать что нибудь написать. Результаты меня не радовали первые дни, ну а что еще было ожидать? Но в течении пары недель удалось побороть эти проблемы и я смог разобраться в документации и базовых туториалах от мелкософта. По скольку графикой я уже занимался, то у меня уже была выработана некая архитектура приложений, а перевести на Cpp уже было не так то уж и трудно. В общем еще пару недель и я уже смог нарисовать простой кубик на экране =). Но на этом я не остановился пошел дальше, научился использовать шейдеры и кубмап текстуры.
Решил я всё это протестировать и получил хороший результат. Его вы видите слева, особенно радует FPS. Держится на хорошей планке, но все же думаю что есть к чему расти. Единственно, что криво вышло - это не грамотно обрезанная текстура неба, просто делал на скорую руку, чтобы побыстрее посмотреть результат.
Затем нашел статью по программированию шейдеров на HLSL. Немного помучившись с передачей данных в шейдер мне удалось реализовать точечный источник света с линейным и билинейным затуханием. Результат представлен справа.
Затем я решил задуматься о пост эффектах. Это были адские деньки. Несколько дней я сидел и разбирал различные статьи и документацию, но у меня ничего не выходило. И как всегда исправив всего один символ у меня все заработало. Как же я был тогда зол, но и одновременно и рад, что у меня получилось сделать рендер в текстуру. И я сразу же решил опробовать пост-эффекты. Открыв блокнот, я быстренько написал простенькие пост эффекты.
Из-за рендера в текстуру серьёзно падает FPS, но ничего страшного, думаю, что это возможно исправить.
Дальше я решил проверить возможности своего приложения нарисовав 1000 кубов. Но увы меня ждал провал. Все 1000 FPS превратились в жалкую 1, а иногда и 0. Пришлось искать методы оптимизации рендера. Мой выбор пал на инстансинг. Так же помучившись несколько дней над ним, мне удалось вернуть хороший фпс. Но работы над оптимизацией этой методики еще очень много. На этом я пока что остановился.
Когда я писал на паре инстансинг, проходил наш препод по программированию и заметил чем я занимаюсь. Спросив что это дальше будет я не ответил, а он сказал: "Майнкрафт может запилишь?". В общем дальше получилась очень интересная дискуссия насчет Direct X в общем и еще по мелочам.
С понедельника попробую еще немного оптимизировать рендер, надеюсь удастся выкрасть еще немного памяти и фпс. Дальше попробую заняться мелкими системными примочками.
И напоследок я хочу вам рассказать о простоте конечного приложения.
Создание окна и инициализация рендера для него
GetCoreInterface(&core);
AGEWindowProp prop(800, 600, "Test 3D Application");
core->CreateNewWindow(&prop, &wnd, NULL);
core->CreateRenderManager(&render, NULL);
render->Initialize(wnd, true, 1366, 768);
Загрузка текстур происходит буквально в 3 строчки.
mm->CreateTexture(&pTexture);
pTexture->SetTextureType(AGE_TEXTURE_CUBE);
pTexture->LoadFromFile("skybox.dds");
pTexture->Release();
Установка sky box'а и создание сцены занимает 4 строчки
render->CreateScene(&scene);
scene->SetRenderState(AGE_RENDER_STATE_BACK);	
scene->GetSkyBoxObject()->SetMesh(3);
scene->GetSkyBoxObject()->SetEffect(skyboxFXId);
Установка рендера в текстуру и подключение пост эффекта
render->CreateScene(&scene);
scene->CreateRenderedTexture(800, 600);
scene->GetEffect()->LoadFromFile("scene.fx");
scene->SetRenderState(AGE_RENDER_STATE_BACK);
Единственное, что я пока что не делал, так это загрузку мешей из файла. Поэтому создавать приходиться вручную, но это тоже занятие не из самых долгих.
создание меша куба
mm->CreateMesh(&mesh);
mesh->CreateRegion(&mRegion);

float s = 250.0f;

mRegion->AddVertex(VERTEX(-s,-s,-s));
mRegion->AddVertex(VERTEX(s,-s,-s));
mRegion->AddVertex(VERTEX(s,-s,s));
mRegion->AddVertex(VERTEX(-s,-s,s));
mRegion->AddVertex(VERTEX(-s,s,-s));
mRegion->AddVertex(VERTEX(s,s,-s));
mRegion->AddVertex(VERTEX(s,s,s));
mRegion->AddVertex(VERTEX(-s,s,s));
//Front
mRegion->AddTriangle(0, 1, 5);
mRegion->AddTriangle(5, 4, 0);
//Right
mRegion->AddTriangle(1, 2, 6);
mRegion->AddTriangle(6, 5, 1);
//Left
mRegion->AddTriangle(0, 4, 7);
mRegion->AddTriangle(7, 3, 0);
//Back
mRegion->AddTriangle(6, 2, 3);
mRegion->AddTriangle(3, 7, 6);
//Top
mRegion->AddTriangle(4, 5, 6);
mRegion->AddTriangle(6, 7, 4);
//Bottom
mRegion->AddTriangle(2, 1, 0);
mRegion->AddTriangle(0, 3, 2);

mRegion->SetTexture(3);

mesh->Init();
mesh->Release();
Ну в принципе, это все что я хотел вам сегодня рассказать. Всем удачи и до скорых встреч в новых постах