Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Вывод картинки на передний план


Автор: Div 14.7.2005, 13:41
Как можно вывести небольшую картинку на экран в DirectX. Чтобы она имела один розрачный цвет и выводилась поверх объектов. Типа менюшек во время игры.

Автор: empter 16.7.2005, 15:18
Попробуй спрайтом

Автор: Div 20.7.2005, 19:10
Всмысле отрисовать полигон с текстурой прямо перед экраном?

Автор: empter 21.7.2005, 17:52
Вобщем да, хотя я этим еще не занимался посмотри пример http://www.gamedev.ru/coding/20603.shtml, кое что дельное там должно быть.

Автор: Guest 24.7.2005, 21:18
вывод картинки это текстурирование можно до восьми текстур
на один объект в том числе и на буфер.


if( FAILED( D3DXCreateTextureFromFileEx( pDirect3DDevice, "Directx.jpg", D3DX_DEFAULT, D3DX_DEFAULT, 100000, 131072, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER,D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER,0x000000ff,NULL,NULL,&pTextura001 ) ) )
return E_FAIL;
// Загружаем вторую текстру
if( FAILED( D3DXCreateTextureFromFileEx( pDirect3DDevice, "Directx.bmp", D3DX_DEFAULT, D3DX_DEFAULT, 10000, 131072, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER,D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER,0x0000000f,NULL,NULL,&pTextura002 ) ) )
return E_FAIL;
// Создаем буфер вершин
if( FAILED( pDirect3DDevice->CreateVertexBuffer( 36 * sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &pBufferVershin, NULL ) ) )
return E_FAIL;
//Блокируем
VOID* pBV;
if( FAILED( pBufferVershin->Lock( 0, sizeof(Vershin), (void**)&pBV, 0 ) ) )
return E_FAIL;
//Копируем
memcpy( pBV, Vershin, sizeof(Vershin) );
// Разблокируем
pBufferVershin->Unlock();
// Создаем индексный буфер
pDirect3DDevice->CreateIndexBuffer( 36 * sizeof(Index),
0, D3DFMT_INDEX16, D3DPOOL_DEFAULT,&pBufferIndex, NULL);
//Блокируем
VOID* pBI;
pBufferIndex->Lock( 0, sizeof(Index) , (void**)&pBI, 0 );
//Копируем
memcpy( pBI, Index, sizeof(Index) );
// Разблокируем
pBufferIndex->Unlock();


Автор: Helicopter 24.7.2005, 21:24
это я скинул. только не зубудь всё в начале объявить

LPDIRECT3DTEXTURE9 pTextura001 = NULL; // Текстyра 1
LPDIRECT3DTEXTURE9 pTextura002 = NULL; // Текстyра 2

если чё пиши

Автор: JoyEx 3.8.2005, 20:58
Можно это сделать еще с помощью оверлея, причем чем проще цвет, тем больше вероятность его сделать прозрачным, т.е. если не RGB(255,215,0), а типа RGB(0,255,0). Например,
Код

    over.dckSrcColorkey.dwColorSpaceLowValue  = RGB(0,255,0);
    over.dckSrcColorkey.dwColorSpaceHighValue = RGB(0,255,0);

    lpSurf2->UpdateOverlay(&rcSrcRect, lpPrimarySurface2, &rcDestRect, 
            DDOVER_SHOW | DDOVER_KEYSRCOVERRIDE, &over);


В SrcColorkey (источник) указывается цвет, который будет прозрачным у источника, т.е. у адресата (lpPrimarySurface2) RGB(0,255,0) с lpSurf2 не увидишь. Можно еще задать color key адресата, чтобы только этот цвет (или диапазон) изменялся.

Помните! Поверхности могут иметь разный цветовой формат.

Автор: Div 6.8.2005, 12:33
Всё понял! Спасибо

Автор: p0s0l 6.8.2005, 13:12
Имхо, оверлей для таких целей - слишком жирно будет smile и не очень надежно. К тому же, вроде как тут речь о Direct3D...

Просто выставь ортогональную проекцию, единичную матрицу вида, отключи Z-тест, включи и настрой альфаблендинг, и выводи прямоугольник с текстурой, имеющей альфа-канал...

Автор: Div 6.8.2005, 13:37
Как отключить Z-тест?

Автор: p0s0l 6.8.2005, 13:44
d3ddev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE)
Аналогично и блендинг делается: D3DRS_ALPHABLENDENABLE, D3DRS_SRCBLEND, D3DRS_DESTBLEND...

Автор: Div 10.8.2005, 06:47
А можно вопрос? Как подогнать прямоугольник под текстуру (по размерам)? У меня всё расплывается. Получается что-то увидеть только тогда, когда изменяю координаты текстуры, но получается так, что квадратиков (тектура - белый квадрат обведенный красным по кроям) много. Наверное в Microsoft должны были предусматреть вывод таких картинок. Может есть другой способ?

Автор: p0s0l 10.8.2005, 12:36
Не понял, что у тебя там такое расплывается и куда, наверное, ты что-то неправильно делаешь.
Вот как должно примерно быть:
Код

d3ddev->BeginScene();

// ... рисуется твоя сцена

// теперь рисуем поверх этого спрайтик...

int ClientWidth = 1024; // ширина поверхности
int ClientHeight = 768; // высота поверхности

// ортогональная проекция
D3DXMATRIX OrthoMatrix;
D3DXMatrixOrthoOffCenterRH( &OrthoMatrix, 0, ClientWidth, 0, ClientHeight, 0, 1);
d3ddev->SetTransform( D3DTS_PROJECTION, &OrthoMatrix );
// ПРИ ТАКОЙ ПРОЕКЦИИ КООРДИНАТАМ (0, 0) СООТВЕТСТВУЕТ ЛЕВЫЙ НИЖНИЙ ПИКСЕЛ ПОВЕРХНОСТИ!

// настройка вьюпорта
D3DVIEWPORT8 ViewPort;
ViewPort->X = 0;
ViewPort->Y = 0;
ViewPort->Width = ClientWidth;
ViewPort->Height = ClientHeight;
ViewPort->MinZ = 0;
ViewPort->MaxZ = 1;
d3ddev->SetViewport( &ViewPort );

d3ddev->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); // отключение Z-буферизации
d3ddev->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); // отключение куллинга
d3ddev->SetRenderState( D3DRS_LIGHTING, 0 ); // отключение освещения

// выбор текстуры спрайта, которая должна быть с альфа-каналом (например, в формате D3DFMT_A8R8G8B8)
d3ddev->SetTexture( 0, d3dtex );

// выбор POINT-фильтрации (т.е. без линейной интерполяции)
d3ddev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT );
d3ddev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT );

// включение и настрока прозрачности
d3ddev.SetRenderState( D3DRS_ALPHABLENDENABLE, 1 );
d3ddev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
d3ddev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

---
создание/заполнение вершинного буфера
должно быть 4 вершины прямоугольника
например, если ширина спрайта = 100, высота = 50, то координаты будут такими:
(0, 0, 0)  (99, 0, 0)  (99, 49, 0)  (0, 49, 0)
и соответствующие текстурные координаты:
(0, 0)     (1, 0)      (1, 1)       (0, 1)
---

// рисование прямоугольника
d3ddev->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 4 );

//...

d3ddev->EndScene();
d3ddev->Present( NULL, NULL, 0, NULL );

Цитата(Div @ 10.8.2005, 06:47)
Наверное в Microsoft должны были предусматреть вывод таких картинок. Может есть другой способ?
Вряд ли... Только если какие-то левые библиотеки, но они будут работать по такому же принципу. Да и в чем проблема-то ? Всё проще пареной репы smile


Автор: Div 14.8.2005, 17:07
Я написал свой способ вывода картинки на передний план. Он чем-то похож на разъяснения pOsOl'а. Вставил несколько комментарием, так что должно быть понятно, что к чему. Все что относиться к выводу картинки находиться в AppInit() и RenderScene(). Кому интересно, можете скачать готовый пример http://www.ekbsity.h15.ru/bbs/books/FrontScreen.rar

Я писал на Microsoft Visual Studio .NET (C++), но .dsp файл создается => на VS C++ тоже пойдет!

Автор: NordWolf 26.9.2007, 00:52
при выводе текста проблема возникла. Вообщем код программы таков:

Код

#include <windows.h>  // Заголовочный файл для Windows
#include <stdio.h>    // Заголовочный файл для стандартной библиотеки ввода/вывода
#include <gl\gl.h>    // Заголовочный файл для библиотеки OpenGL32
#include <gl\glu.h>   // Заголовочный файл для библиотеки GLu32 
#include <gl\glaux.h> // Заголовочный файл для библиотеки GLaux 
#include <math.h>     // Заголовочный файл для математической библиотеки 
#include <stdarg.h>   // Заголовочный файл для функций для работы с переменным


HDC        hDC=NULL;  // Приватный контекст устройства GDI
HGLRC      hRC=NULL;  // Постоянный контекст рендеринга
HWND       hWnd=NULL; // Сохраняет дескриптор окна
HINSTANCE  hInstance; // Сохраняет экземпляр приложения

GLuint  base;      // База списка отображения для фонта
GLfloat  cnt1;     // Первый счетчик для передвижения и закрашивания текста
GLfloat  cnt2;     // Второй счетчик для передвижения и закрашивания текста
 
long int keys[256];      // Массив для работы с клавиатурой
long int active=TRUE;    // Флаг активации окна, по умолчанию = TRUE
long int fullscreen=TRUE; // Флаг полноэкранного режима
 
LRESULT  CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  // Объявление WndProc

GLvoid BuildFont(GLvoid)  // Построение нашего растрового шрифта
{
  HFONT  font;            // Идентификатор фонта
  base = glGenLists(96);  // Выделим место для 96 символов
  font = CreateFont(  -24, 0, 0, 0, FW_BOLD, FALSE, TRUE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,FF_DONTCARE|DEFAULT_PITCH,"Courier New"); 

 SelectObject(hDC, font);        // Выбрать шрифт, созданный нами 
 wglUseFontBitmaps(hDC, 32, 96, base); // Построить 96 символов начиная с пробела 

}

GLvoid KillFont(GLvoid)            // Удаление шрифта

{
    glDeleteLists(base, 96);        // Удаление всех 96 списков отображения 
}

GLvoid glPrint(const char *fmt, ...)        // Заказная функция «Печати» GL
{
  char    text[256];      // Место для нашей строки
  va_list    ap;          // Указатель на список аргументов
  if (fmt == NULL)     // Если нет текста
    return;            // Ничего не делать

  va_start(ap, fmt);           // Разбор строки переменных
  vsprintf(text, fmt, ap);    // И конвертирование символов в реальные коды
  va_end(ap);                  // Результат помещается в строку
  glPushAttrib(GL_LIST_BIT);      // Протолкнуть биты списка отображения 
  glListBase(base - 32);          // Задать базу символа в 32 
 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);// Текст списками отображения
 glPopAttrib(); // Возврат битов списка отображения 

}

int InitGL(GLvoid)            // Все начальные настройки OpenGL здесь

{
  glShadeModel(GL_SMOOTH);    // Разрешить плавное затенение
  glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Черный фон
  glClearDepth(1.0f);         // Установка буфера глубины
  glEnable(GL_DEPTH_TEST);    // Разрешение теста глубины
  glDepthFunc(GL_LEQUAL);     // Тип теста глубины

  // Действительно хорошие вычисления перспективы
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  BuildFont();            // Построить шрифт
  return TRUE;            // Инициализация окончена

}

int DrawGLScene(GLvoid) // Здесь мы будем рисовать все

{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Очистка экран и буфера глубины
  glLoadIdentity(); // Сброс просмотра
  glTranslatef(0.0f,0.0f,-1.0f); // Передвижение на одну единицу вглубь
 
  // Цветовая пульсация, основанная на положении текста
  glColor3f(0.0f*float(cos(cnt1)),0.0f*float(sin(cnt2)),0.0f-0.5f*float(cos(cnt1+cnt2)));
  

  // Позиционирование текста на экране
  glRasterPos2f(-0.45f+0.05f*float(cos(cnt1)), 0.35f*float(sin(cnt2)));
  glPrint("Active OpenGL Text With NeHe - %7.2f", cnt1);  // Печать текста GL на экран
  cnt1+=0.051f;  // Увеличение первого счетчика
  cnt2+=0.005f;  // Увеличение второго счетчика
  return TRUE;   // Все отлично
}

 if (!UnregisterClass("OpenGL",hInstance))    // Если класс не зарегистрирован

  {
    MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR", MB_OK|MB_ICONINFORMATION);
    hInstance=NULL;          // Установить копию приложения в ноль
  KillFont();            // Уничтожить шрифт
 }




при компиляции появяются следующие ошибки:

E:\Development\OpenGL\Text\text.c(83) : error C2059: syntax error : 'type'
E:\Development\OpenGL\Text\text.c(87) : error C2059: syntax error : 'type'
E:\Development\OpenGL\Text\text.c(94) : error C2059: syntax error : 'if'

что это и как это исправить?


Автор: Ferrisgeneral 7.6.2010, 15:45
встала задача соединить 2 проектика, в одном интерфейс (2D), а в другом 3D объект.

посмотрел как p0s0l предлогал выводить совместно 2D и 3D графику, но нехотелось бы все мешать в секции render. Можно ли отдельно подготовить для вывода отдельно 2D часть, а отдельно 3D часть ... , а потом в секции render  поочереди вывести обе части.

как понимаю, нельзя сделать 2 секции render для каждой и частей (2D и 3D).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)