[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: Spam, Jack  
DirectDraw
StAngerrrДата: Суббота, 07 Февраля 2009, 17:42 | Сообщение # 1
Начинающий
Группа: Пользователи
Сообщений: 4
Награды: 0
Замечания: 0%
Статус:

Профессия: Программист
Проектов: 1
Есть код инициализации directDraw.
#include <vcl.h>
#pragma hdrstop
#include <windows.h>
#include <ddraw.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

LPDIRECTDRAW lpDD; // указатель на объект DirectDraw
// вообще их может быть несколько, я ,например, использовал
//по одному объекту на каждое окно в MDI приложении (см пример
//использования DirectDraw c MFC)
/*
* Функция инициализации объекта DirectDraw
* 1) Создаем Direct Draw Object
* 2) Устанавливаем вид доступа
* 3) Устанавливаем видео моду дисплея
*
*/
bool DirectDrawInit(HWND hwnd)
{
HRESULT ddrval;

/*
* Создание (получение) указателя на основной объект DirectDraw.
*
*/
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
if( ddrval != DD_OK )
{
goto lError;
}

/*
* Теперь зададим уровень доступа, который может иметь следующие значения
*
* DDSCL_EXCLUSIVE дает Вам полный доступ к видеопамяти и управлению видеорежимами
* требует флаг DDSCL_FULLSCREEN , т.е. Вы работаете со всем экраном сразу
* Это основной (типовой режим работы DirectDraw
* DDSCL_NORMAL используется для обеспечения оконного доступа. Правда доступ
* у вас все равно ко всему экрану , обеспечивать оконность все равно приходится вручную
* (обычные недоделки Microsoft)
* как добиться оконного поведения см пример класса CDDrawView доступном для download на данном
* сайте
*/
ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
if( ddrval != DD_OK )
{
lpDD->Release();
goto lError;
}

/*
* Установим видео моду 800x600 256 цветов
* (видео моду можно изменять, только если установлен флаг DDSCL_EXCLUSIVE
*/
ddrval = lpDD->SetDisplayMode( 800, 600, 8);
if( ddrval != DD_OK )
{
lpDD->Release();
goto lError;
}

return TRUE;
lError:
// здесь можно вставить код для оповещения пользователя о невозможности
// инициализации DirectDraw

return FALSE;
};

LPDIRECTDRAWSURFACE lpDDSPrimary; // указатель на первичную поверхность DirectDraw
LPDIRECTDRAWSURFACE lpDDSBack; // указатель на вторичную поверхность DirectDraw

bool CreatePrimarySurface()
{
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HRESULT ddrval;

// создадим первичную поверхность с одной вторичной
memset( &ddsd, 0, sizeof(ddsd) );
ddsd.dwSize = sizeof( ddsd );

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // поле ddsCaps принимается в рассмотрение и в
// нем имеет значение только количество вторичных
//буферов(поверхностей)
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

ddsd.dwBackBufferCount = 1;

ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if( ddrval != DD_OK )
{
lpDD->Release();
return FALSE;
}

// Теперь получим вторичный буфер (поверхность)
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if( ddrval != DD_OK )
{
lpDDSPrimary->Release();
lpDD->Release();
return FALSE;
}

return TRUE;
}

/*
* Функция DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap) создает поверхность
* и загружает файл с диска. Параметр szBitmap имя файла изображения.
*/
IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap)
{
HBITMAP hbm;
BITMAP bm;
IDirectDrawSurface *pdds;
// загрузим с диска
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE/LR_CREATEDIBSECTION);

if (hbm == NULL) return NULL;

GetObject(hbm, sizeof(bm), &bm); // получим размер

//создадим поверхность для данного изображения

pdds = CreateOffScreenSurface( 680, 439);
if (pdds)
{
DDCopyBitmap(pdds, hbm, bm.bmWidth, bm.bmHeight);
}

DeleteObject(hbm);

return pdds;
}

/*
* Функция создания поверхности для изображения заданного размера
* Эта поверхность окажется в видеопамяти, если ее еще достаточно,
* в противном случае - в системной памяти
*/
IDirectDrawSurface * CreateOffScreenSurface(IDirectDraw *pdd, int dx, int dy)
{
DDSURFACEDESC ddsd;
IDirectDrawSurface *pdds;

//
// Создание поверхности
//
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; // имеет значение высота и ширина
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; // это заэкранная поверхность
ddsd.dwWidth = dx;
ddsd.dwHeight = dy;

if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
{
return NULL;
}
else
{
return pdds;
}
}

/*
* Функция копирования ранее загруженного изображения в видео поверхность
* (Используется обычный GDI интерфейс)
* Это, конечно, не самый быстрый способ - но зато надежный
* A в данный момент спешить некуда. Если у Вас происходит динамическая подгрузка
* изображений в процессе то лучше эту функцию переписать аккуратнее
*/
HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
HRESULT hr;
HBITMAP hbmOld;

//
// привяжем контекст изображения (DC) к загруженному изображению
//
hdcImage = CreateCompatibleDC(NULL);
hbmOld = (HBITMAP)SelectObject(hdcImage, hbm);

if ((hr = pdds->GetDC(&hdc)) == DD_OK)
{
BitBlt(hdc, 0, 0, dx, dy, hdcImage, 0, 0, SRCCOPY);
pdds->ReleaseDC(hdc);
}

SelectObject(hdcImage, hbmOld);
DeleteDC(hdcImage);

return hr;
}
/*
* Создание палитры DirectDraw для файла загружаемого с диска
* параметр szBitmap имя файла
*/
IDirectDrawPalette * LoadPaletteFromDibFile(IDirectDraw *pdd, LPCSTR szBitmap)
{
IDirectDrawPalette* ddpal;
int i;
int n;
int fh;
PALETTEENTRY ape[256];

if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;

_lread(fh, &bf, sizeof(bf));
_lread(fh, &bi, sizeof(bi));
_lread(fh, ape, sizeof(ape));
_lclose(fh);

if (bi.biSize != sizeof(BITMAPINFOHEADER))
n = 0;
else if (bi.biBitCount > 8)
n = 0;
else if (bi.biClrUsed == 0)
n = 1 << bi.biBitCount;
else
n = bi.biClrUsed;

//
// цветовая таблица DIB имеет BGR кодировку а не RGB
// сделаем необходимую транспозицию.
//
for(i=0; iCreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL)!=DD_OK;)
{
return NULL;
} else
{
return ddpal;
}

};
return false;
}
возникают такие ошибки
[BCC32 Error] Unit1.cpp(140): E2268 Call to undefined function 'createOffScreenSurface'
[BCC32 Error] Unit1.cpp(140): E2034 Cannot convert 'int' to 'IDirectDrawSurface *'
[BCC32 Error] Unit1.cpp(143): E2268 Call to undefined function 'DDCopyBitmap'
[BCC32 Error] Unit1.cpp(247): E2268 Call to undefined function 'iCreatePalette'
[BCC32 Error] Unit1.cpp(250): E2054 Misplaced else
[BCC32 Warning] Unit1.cpp(257): W8004 'n' is assigned a value that is never used
[BCC32 Warning] Unit1.cpp(257): W8004 'i' is assigned a value that is never used

где что не так?

 
StAngerrrДата: Суббота, 07 Февраля 2009, 18:08 | Сообщение # 2
Начинающий
Группа: Пользователи
Сообщений: 4
Награды: 0
Замечания: 0%
Статус:

Профессия: Программист
Проектов: 1
IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap)
{
HBITMAP hbm;
BITMAP bm;
IDirectDrawSurface *pdds;
// загрузим с диска
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE/LR_CREATEDIBSECTION);

if (hbm == NULL) return NULL;

GetObject(hbm, sizeof(bm), &bm); // получим размер

//создадим поверхность для данного изображения

pdds = CreateOffScreenSurface(pdd, bm.bmWidth, bm.bmHeight);
E2268 Call to undefined function 'CreateOffScreenSurface'
E2268 Call to undefined function 'DDCopyBitmap'
E2268 Call to undefined function 'ICreatePalette'
E2034 Cannot convert 'int' to 'IDirectDrawSurface *'
if (pdds)
{
DDCopyBitmap(pdds, hbm, bm.bmWidth, bm.bmHeight);

}

DeleteObject(hbm);

return pdds;
}
IDirectDrawPalette * LoadPaletteFromDibFile(IDirectDraw *pdd, LPCSTR szBitmap)
{
IDirectDrawPalette* ddpal;
int i;
int n;
int fh;
PALETTEENTRY ape[256];

if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;

_lread(fh, &bf, sizeof(bf));
_lread(fh, &bi, sizeof(bi));
_lread(fh, ape, sizeof(ape));
_lclose(fh);

if (bi.biSize != sizeof(BITMAPINFOHEADER))
n = 0;
else if (bi.biBitCount > 8)
n = 0;
else if (bi.biClrUsed == 0)
n = 1 << bi.biBitCount;
else
n = bi.biClrUsed;

//
// цветовая таблица DIB имеет BGR кодировку а не RGB
// сделаем необходимую транспозицию.
//
for(i=0; ICreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL)!=DD_OK;)
E2268 Call to undefined function 'ICreatePalette'
{
return NULL;
} else
{
return ddpal;
}

};

если поможет этот код брал отсюда http://www.helloworld.ru/texts/comp/games/directx/ddraw/directx.htm

 
StAngerrrДата: Суббота, 07 Февраля 2009, 18:55 | Сообщение # 3
Начинающий
Группа: Пользователи
Сообщений: 4
Награды: 0
Замечания: 0%
Статус:

Профессия: Программист
Проектов: 1
Хоть на этом спасибо)) roll

А как я тогда могу создать неэкранную поверхность с указанием изображения?

Сообщение отредактировал StAngerrr - Суббота, 07 Февраля 2009, 18:57
 
  • Страница 1 из 1
  • 1
Поиск: