« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга



ПнВтСрЧтПтСбВс
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
    Популярное
Функция AccessResource

Функция GetWindowExt

Версия Oracle 10g: специалисты по настройке запросов больше не нужны

Глава 8. Правила программирования на С++

Глава 18. ОГРАНИЧЕНИЕ ЗНАЧЕНИЙ ВАШИХ ДАННЫХ

Chapter 5. Работа с картинками

Функция ReleaseDC

Структура CGI программы

Зависимость способа реализации средства защиты от предъявляемых к нему требований

Компонент программиста




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 179
Пользователей: 0

Статьи:: Графика и игроделание DirectX, OpenGL etc.) :: Direct3D :: Что может наша видеокарта, что можем сделать мы и как это узнать?



отправить ссылку другу версия для печати  Обсудить на форуме

Что может наша видеокарта, что можем сделать мы и как это узнать?



По прошествии некоторого времени после празднования Нового Года и всего, что с ним связано, предлагаю вашему вниманию новый урок. Посвящен он будет извлечению информации о возможностях вашей видео карты (или видео карт, если у вас их несколько), таких как поддерживаемые разрешения экрана, возможные форматы поверхностей, различные форматы глубинных буферов. Также сюда отнесем тему получения и использования возможностей видео карты, или, точнее, чип сета на котором она построена (например GeForce1-2-3, TNT1-2, Radeon, 3dfx Voodoo и так далее), это такие возможности как возможность рендерить в оконном режиме, аппаратной реализации TnL, максимальные размеры текстур и т.д.

Данная тема появилась тогда, когда мне потребовалось сделать, что бы можно было запускать мою программу о всех возможных режимах, на всех устройствах, при любом разрешении. Мое прежнее решение (в виде диалога прямо при загрузке программы) мне не понравилось еще и потому, что мне пришлось слишком часто запускать программу в одном и том же разрешении, при это изменяя саму программу, а вот каждый раз при этом устанавливать это самое разрешение оказалось достаточно утомительным занятием.

Отсюда появилось вполне ожидаемое решение - хранить эти настройки в файле. Казалось в чем тогда проблема - вопрос же вроде решен. Но что мне оказалось не правильным, так это то, что при этом пользователь может написать такие параметры, которые не будут работать на данной конкретной видео карте. Отсюда еще один вывод - нужно позволить пользователь самому выбрать настройки из заранее приготовленных. Н при этом брать эту информацию не с потолка, а выяснить эти возможности у видео карты.

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

Данная программка предназначена исключительно для создания конфигурационного файла, на основе предпочтений пользователя - он сам может выбрать какую именно видео карту использовать (если их несколько), какое устройство рендеринга, задать требуемый вариант работы (оконный или полноэкранный, с учетом разных форматов поверхностей - 16 бит, 24 бита или 32 бита), выбрать разрешение экрана, а также и частоту регенерации для монитора, установить требуемый формат буфера глубины и даже выбрать число вторичных поверхностей (2 или 3, соответственно Double или Triple Buffers). После того, как пользователь все выбрал и нажал кнопку 'Save and Exit' вся конфигурация сохраняется в файл config.txt, который затем используется непосредственно главной программой. Она из него загружает эти сохраненные параметры, и использует их по назначению - установке их, когда происходит инициализация Direct3D8.

Внешне все это понятно. Теперь давайте возьмемся за внутренности, за то, как все это устроено внутри, как происходит процесс в программе. Но для начала нужно объяснить, как это вообще все организовано, и что как и в какой последовательности нужно делать (я достаточно долго до этого добирался, и много на этом потратил времени).

1 - получаем количество доступных нам видео карт;
2 - для каждой видео карты выясняем, какие устройства рендеринга на ней доступны;
3 - для каждого устройства рендеринга получаем допустимые форматы поверхностей для рендеринга;
4 - далее для каждого формата поверхностей получаем список всех возможных форматов для буферов глубины;
5 - для каждой видео карты получаем список всех доступных видео разрешений, частоты обновления и глубины пикселя поверхности (16, 24, 32 бита);

Теперь возьмемся за рассмотрение практической части, покрывающей вышеозначенные пункты.

Замечу, что данный код я использую не только в этом конфигураторе, но и в основной программе. В основной программе я обернул все это в специальный класс, который будет отвечать за получение всей информации о возможностях вашей видео карты, а так же за загрузку ранее созданного конфигурационного файла. Также замечу, что данный код я приведу в конце (отдельно для конфигуратора и отдельно для основной программы, для конфигуратора это будут исходники единственного в проекте файла с программой, а для основной программы это будет код созданного при этом класса). Собственно теперь все мои проекты будут нуждаться в получаемом конфигурационном файле, конфигуратор при этом также будет включаться во все проекты (это увеличит каждый архив на 30 кб), за исключением исходников. Все исходники конфигуратора и исполнимый файл, а также его возможные обновления будут доступны отдельно.

Для работы с темой данного урока я создал класс :


//-----------------------------------------------
// some classes for video datas determining process
//-----------------------------------------------

#define iDevType 2
#define iFormatType 5
#define iDepthType 7
	
class cAdapter
{
public:
	cAdapter ();
	~cAdapter ();

	static int iCount;
	char desc[MAX_DEVICE_IDENTIFIER_STRING];

	bool bDevice[iDevType];
	bool bDeviceW[iDevType];

	bool bFormat[iDevType][iFormatType];
	bool bDepthFormat[iDevType][iFormatType][iDepthType];

	class cMode
	{
	public:
		cMode ();
		~cMode ();

		static int iCount;

		int Width;
		int Height;
		int Refresh;
		D3DFORMAT Format;
		int BitDepth;
	} *mode;

private:
};

int cAdapter::iCount=0;
int cAdapter::cMode::iCount = 0;

cAdapter::cAdapter (void)
{
	for(int i=0; i<iDevType; i++) 
	{
		bDevice[i] = bDeviceW[i] = false;
		for(int j=0; j>iFormatType; j++) 
		{
			bFormat[i][j] = false;
			for(int k=0; k<iDepthType; k++) bDepthFormat[i][j][k] = false;
	};	};
};

cAdapter::~cAdapter (void)
{
};

cAdapter::cMode::cMode (void)
{
	Width = 0;
	Height = 0;
	Refresh = 0;
	Format = D3DFMT_UNKNOWN;
	BitDepth = 0;
};

cAdapter::cMode::~cMode (void)
{
};

cAdapter *Adapter;

//-----------------------------------------------
// -- some classes for video datas determining process
//----------------------------------------------->/pre>

 

Как тут все рассматривается?
Во первых идет объявление трех констант:

--- количество устройств рендеринга (на данный момент их всего два - D3DDEVTYPE_HAL - аппаратный режим, D3DDEVTYPE_REF - программный режим)
--- количество форматов поверхностей (всего пять - D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, D3DFMT_R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8)
--- количество форматов буфера глубины и буфера шаблонов (depth and stencil buffers - всего семь форматов - D3DFMT_D16_LOCKABLE, D3DFMT_D16, D3DFMT_D15S1, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D32)

Данный класс cAdapter представляет собой один видеоадаптер, если их несколько, то создастся несколько объектов данного класса. В каждом объекте представляющем видеоадаптер (т.е. для каждого видеоадаптера это все выясняется) мы производим поиск сперва всех доступных устройств рендеринга (которых всего два). Далее для каждого из устройств рендеринга мы выясняем какие возможны форматы поверхности для работы. Третий шаг - для каждого из возможных форматов поверхности мы выясняем, какие форматы буфера глубины с ним совместимы. В одномерных массивах bDevice (предназначен для хранения информации о том, какое устройство рендеринга для данного видеоадаптера присутствует) и bDeviceW (те же самые цели только для оконного режима), в двухмерном массиве bFormat (форматы поверхностей, для каждого устройства из bDevice), и в трехмерном массиве bDepthFormat (форматы буфера глубины для каждого формата поверхности для каждого устройства рендеринга) хранится информация о том, доступна ли данная 'штука' или нет. Как вы видите все они типа bool;

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

Далее рассмотрим сам процесс заполнения данных. Весь процесс происходит в следующей части кода:


if(cAdapter::iCount==0)
{
	cAdapter::iCount = p_d3d->GetAdapterCount ();
	Adapter = new cAdapter [cAdapter::iCount];
	for (i=0; i<cAdapter::iCount; i++)
	{
		D3DADAPTER_IDENTIFIER8 info;
		p_d3d->GetAdapterIdentifier (i, D3DENUM_NO_WHQL_LEVEL, &info);
		sprintf (Adapter[i].desc, "%s", info.Description);

		D3DCAPS8 pCaps;
			
		for (j=0; j<iDevType; j++)
		{
			if(SUCCEEDED(p_d3d->GetDeviceCaps (i, DeviceTypes[j], &pCaps)))
			{
				Adapter[i].bDevice[j] = true;
				if(pCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED)
					Adapter[i].bDeviceW[j] = true;
			};

			for (k=0; k<iFormatType; k++)
			{
				if(SUCCEEDED(p_d3d->CheckDeviceType (i, DeviceTypes[j],
 						FormatTypes[k], FormatTypes[k], true)))
				{
					Adapter[i].bFormat[j][k] = true;

					for (l=0; l<iDepthType; l++)
					{
					if(SUCCEEDED(p_d3d->CheckDeviceFormat (i, DeviceTypes[j],
 						FormatTypes[k], D3DUSAGE_DEPTHSTENCIL,
 						D3DRTYPE_SURFACE, DepthTypes[l])))
					if(SUCCEEDED(p_d3d->CheckDepthStencilMatch (i,
 							DeviceTypes[j], FormatTypes[k],
 							FormatTypes[k], DepthTypes[l])))
						Adapter[i].bDepthFormat[j][k][l] = true;
		};	};	};	};



		Adapter[i].cMode::iCount = p_d3d->GetAdapterModeCount (i);
		Adapter[i].cMode::iCount++; // 0 - current desktop format
		Adapter[i].mode = new cAdapter::cMode [Adapter[i].cMode::iCount];

		D3DDISPLAYMODE td3dm;
		p_d3d->GetAdapterDisplayMode (i, &td3dm);
		Adapter[i].mode[0].Width = td3dm.Width;
		Adapter[i].mode[0].Height = td3dm.Height;
		Adapter[i].mode[0].Refresh = td3dm.RefreshRate;
		Adapter[i].mode[0].Format = td3dm.Format;

		for (j=1; j<Adapter[i].cMode::iCount; j++)
		{
			p_d3d->EnumAdapterModes (i, j, &td3dm);
			Adapter[i].mode[j].Width = td3dm.Width;
			Adapter[i].mode[j].Height = td3dm.Height;
			Adapter[i].mode[j].Refresh = td3dm.RefreshRate;
			Adapter[i].mode[j].Format = td3dm.Format;
		};

		for (j=0; j<Adapter[i].cMode::iCount; j++)
		{
			int bpp=0;
			D3DFORMAT tFormat = Adapter[i].mode[j].Format;

			if(tFormat == D3DFMT_X1R5G5B5) bpp=16;
			else if(tFormat == D3DFMT_R5G6B5) bpp=16;
			else if(tFormat == D3DFMT_R8G8B8) bpp=24;
			else if(tFormat == D3DFMT_X8R8G8B8) bpp=32;
			else if(tFormat == D3DFMT_A8R8G8B8) bpp=32;

			Adapter[i].mode[j].BitDepth = bpp;
};	};	};>/pre>

Вы видите, как происходит весь процесс. Надеюсь вам в коде все понятно, но постараюсь все же объяснить по порядку, что и как делается.

Во первых весь процесс происходит только один раз, при загрузке программы, а также включена проверка на количество обнаруженных видеоадаптеров, если их ноль - т.е. ни одного еще нет, то производим их поиск.

Следующими строками мы узнаем, сколько видеоадаптеров у нас есть, и соответственно выделяем необходимый объем памяти. Весь последующий процесс происходит одинаково для всех найденных карт.

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

Затем, для каждого из устройств рендеринга (которых два) мы находим, какие форматы поверхностей и глубинных буферов оно поддерживает.

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

Далее мы проверяем, какие форматы поверхностей рендеринга данное устройство поддерживает. Если мы узнаем, что какой либо формат поддерживается, то следующим шагом у нас будет обнаружение всех доступных форматов буфера глубины, поддерживающихся данным устройством рендеринга для данного формата поверхности.

Собственно на этом работа по обнаружению устройств и форматов всех мастей для текущей видео карты закончена. Далее весь процесс сосредотачивается на обнаружении доступных видеорежимов.

Делается это достаточно просто.

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

Затем мы получаем информацию о текущем разрешении и заносим эту информацию под нулевым номером. Далее мы подобным образом получаем информацию о всех остальных доступных нам видеорежимах, и сохраняем всю эту информацию.

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

Как вы еще должны были заметить, в коде использовались несколько массивов, в которых содержадась информация о форматах. Вот их объявление и инициализация:


const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
const D3DFORMAT FormatTypes[] = { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, D3DFMT_R8G8B8,
 				D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8 };
const D3DFORMAT DepthTypes[] = { D3DFMT_D16_LOCKABLE, D3DFMT_D16,
 				D3DFMT_D15S1, D3DFMT_D24X8, D3DFMT_D24S8,
 				D3DFMT_D24X4S4, D3DFMT_D32 };
const char* sDeviceTypes[] = { "HAL", "REF" };
const char* sFormatTypes[] = { "16 bit Full Screen Mode",
 				"16 bit Full Screen Mode",
 				"24 bit Full Screen Mode",
 				"32 bit Full Screen Mode",
 				"32 bit Full Screen Mode" };
const char* sDepthTypes[] = { "D3DFMT_D16_LOCKABLE", "D3DFMT_D16",
 				"D3DFMT_D15S1", "D3DFMT_D24X8",
 				"D3DFMT_D24S8", "D3DFMT_D24X4S4", "D3DFMT_D32" };

В них просто хранится информация о возможных форматах, а также их текстовое написание для использования, например, на диалоге.

>> Посмотреть полный исходный код конфигуратора (http://www.vvsu.ru/dkcsc/dxgp/rgd_articles_r.asp?s=columns&art=mrsdx8_0021)

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

>> Посмотреть протокол класса (http://www.vvsu.ru/dkcsc/dxgp/rgd_articles_r.asp?s=columns&art=mrsdx8_0021)
>> Посмотреть реализаию методов (http://www.vvsu.ru/dkcsc/dxgp/rgd_articles_r.asp?s=columns&art=mrsdx8_0021)

Как вы видите, все практически тоже самое, единственное это появление "оберточного" класса, и методов работы с ним. И конечно же метод для загрузки конфигурации из файла, он конечно не идеальный, даже я бы сказал страшный, но он работает и работает хорошо.

Собственно немного изменился и код внутри проекта. Это коснулось только обработки диалога (он исчез и его обработка тоже), а также работы с настройками, теперь это все содержится внутри вышеописанного класса. Теперь данные этого класса используются при инициализации, все же остальное осталось прежним.




Рубрика: Direct3D




Подгрузка через AJAX HTML-кода, содержащег....

AJAX

При разработке CMS S.Builder наша команда активно использовала AJAX. Теперь вот решили поделиться накопленным опытом. Начнем с этого хабратопика. Не буду здесь затрагивать различные фреймворки и библиотеки. Свой код всегда роднее. Для работы с AJAX-ом в S.Builder написана библиотека sbAJAX. Можете качать и пользоваться :). В этом файле есть функция sbEvalJS. Для тех, кто не знает, объясню. При подгрузке через AJAX и вставке на страницу HTML-кода, содержащего JavaScript, JavaScript выполняться не будет или полезут баги. Эта функция как раз решает поставленную задачу.


Подробнее... | Рубрика: AJAX | Добавлено: 19.11.2008

Обзор нового релиза самой мощной Ajax библ....

AJAX

Хотя наш обзор немного запоздал, оригинальный Dojo 1.2 вышел в релизной версии ещё 6-го октября, но сейчас мы наверстаем упущенное. И так, Dojo Toolkit — это самая мощная и гибкая ajax-библиотека из всех, что есть на рынке, она активно развивается и имеет большое комьюнити. Кстати, это самое комьюнити, совместно с компанией Sitepen, имеет ещё несколько проектов, среди которых и Cometd и некоторые другие, не менее интересные, о которых мы скоро вам расскажем. Сегодня же все внимание на флагманский продукт — Dojo 1.2.


Подробнее... | Рубрика: AJAX | Добавлено: 19.11.2008

Firebug 1.3 и 1.4 alpha — что нового и инт....

Вебмастеру

Если вы профессиональный веб-разработчик и постоянно имеете дело с разработкой и отладкой сложных AJAX приложений, то наверняка знаете и используете Firebug — плагин для браузера Firefox, предназначенный для отладки и исследования веб-приложений. Текущая его версия, 1.2х достаточно стабильная и функциональна, чтобы помочь в 99% проблем, которые могут возникнуть при разработке. Но и этот инструмент не лишён если не недостатков, то некоторых фич, которые могли бы облегчить работу. И даже идеальный инструмент можно сделать ещё более идеальным, как бы это не звучало.


Подробнее... | Рубрика: Вебмастеру | Добавлено: 19.11.2008

Остальные статьи:

Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...
День программиста — набор стерeотипов
Индусские програмисты
Вышел Django 1.0
Портативная версия Google Chrome Portable
Исходные коды .Net Frameword 3.5 SP1 для о...
Пишем правильный online WYSIWYG-редактор


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия