
Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Тихомиров Ю. Программирование трёхмерной графики / Files / Texture / DibGL
.cpp// DibGL.cpp: implementation of the CDibGL class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DibGL.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const int MAXPALCOLORS = 256;
IMPLEMENT_DYNAMIC(CDibGL, CObject)
CDibGL::CDibGL()
{
memset(&m_bm, 0, sizeof(m_bm));
m_hdd = NULL;
colorTab = new RGBQUAD[MAXPALCOLORS];
}
CDibGL::~CDibGL()
{
DeleteObject();
}
//////////////////
// Удаляем объект: DIB и палитру
//
BOOL CDibGL::DeleteObject()
{
m_pal.DeleteObject();
if (m_hdd) {
m_hdd = NULL;
}
memset(&m_bm, 0, sizeof(m_bm));
delete colorTab;
return CBitmap::DeleteObject();
}
//////////////////
// Читаем DIB из файла
//
BOOL CDibGL::Load(LPCTSTR lpszPathName)
{
return Attach(::LoadImage(NULL, lpszPathName, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE));
}
//////////////////
// Загружаем битовый массив из ресурсов
//
BOOL CDibGL::Load(HINSTANCE hInst, LPCTSTR lpResourceName)
{
return Attach(::LoadImage(hInst, lpResourceName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE));
}
BOOL CDibGL::Attach(HGDIOBJ hbm)
{
if (CBitmap::Attach(hbm)) {
if (!GetBitmap(&m_bm)) // load BITMAP for speed
return FALSE;
m_pal.DeleteObject(); // in case one is already there
return CreatePalette(m_pal); // create palette
}
return FALSE;
}
//////////////////
// Получаем размер битового массива
CSize GetBitmapSize(CBitmap* pBitmap)
{
BITMAP bm;
return pBitmap->GetBitmap(&bm) ?
CSize(bm.bmWidth, bm.bmHeight) : CSize(0,0);
}
//////////////////
// Рисуем битовый массив
BOOL DrawBitmap(CDC& dc, CBitmap* pBitmap,
const CRect* rcDst, const CRect* rcSrc)
{
// Рассчитываем соответствующий прямоугольник
CRect rc;
if (!rcSrc) {
rc = CRect(CPoint(0,0), GetBitmapSize(pBitmap));
rcSrc = &rc;
}
if (!rcDst) {
rcDst=rcSrc;
}
// Создаем контекст памяти
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap* pOldBm = memdc.SelectObject(pBitmap);
BOOL bRet = FALSE;
if (rcDst->Size()==rcSrc->Size()) {
bRet = dc.BitBlt(rcDst->left, rcDst->top,
rcDst->Width(), rcDst->Height(),
&memdc, rcSrc->left, rcSrc->top, SRCCOPY);
} else {
dc.SetStretchBltMode(COLORONCOLOR);
bRet = dc.StretchBlt(rcDst->left, rcDst->top, rcDst->Width(),
rcDst->Height(), &memdc, rcSrc->left, rcSrc->top, rcSrc->Width(),
rcSrc->Height(), SRCCOPY);
}
memdc.SelectObject(pOldBm);
return bRet;
}
BOOL CDibGL::Draw(CDC& dc, const CRect* rcDst, const CRect* rcSrc,
BOOL bUseDrawDib, CPalette* pPal, BOOL bForeground)
{
if (!m_hObject)
return FALSE;
if (pPal==NULL)
pPal = GetPalette();
CPalette* pOldPal = dc.SelectPalette(pPal, !bForeground);
dc.RealizePalette();
BOOL bRet = FALSE;
if (bUseDrawDib) {
CRect rc(0,0,-1,-1); // по умолчанию для DrawDibDraw
if (!rcSrc)
rcSrc = &rc;
if (!rcDst)
rcDst=rcSrc;
DIBSECTION ds;
VERIFY(GetObject(sizeof(ds), &ds)==sizeof(ds));
char buf[sizeof(BITMAPINFOHEADER) + MAXPALCOLORS*sizeof(RGBQUAD)];
BITMAPINFOHEADER& bmih = *(BITMAPINFOHEADER*)buf;
RGBQUAD* colors = (RGBQUAD*)(&bmih+1);
memcpy(&bmih, &ds.dsBmih, sizeof(bmih));
GetColorTable(colors, MAXPALCOLORS);
} else {
// используем обычные функции рисования
bRet = DrawBitmap(dc, this, rcDst, rcSrc);
}
if (pOldPal)
dc.SelectPalette(pOldPal, TRUE);
return bRet;
}
#define PALVERSION 0x300 // магическое число для LOGPALETTE
//////////////////
// Создаем палитру
//
BOOL CDibGL::CreatePalette(CPalette& pal)
{
ASSERT(pal.m_hObject==NULL);
BOOL bRet = FALSE;
RGBQUAD* colors = new RGBQUAD[MAXPALCOLORS];
UINT nColors = GetColorTable(colors, MAXPALCOLORS);
if (nColors > 0) {
int len = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nColors;
LOGPALETTE* pLogPal = (LOGPALETTE*)new char[len];
if (!pLogPal)
return NULL;
pLogPal->palVersion = PALVERSION;
pLogPal->palNumEntries = nColors;
for (UINT i = 0; i < nColors; i++) {
pLogPal->palPalEntry[i].peRed = colors[i].rgbRed;
pLogPal->palPalEntry[i].peGreen = colors[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue = colors[i].rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
}
bRet = pal.CreatePalette(pLogPal);
delete [] (char*)pLogPal;
} else {
CWindowDC dcScreen(NULL);
bRet = pal.CreateHalftonePalette(&dcScreen);
}
delete colors;
return bRet;
}
UINT CDibGL::GetColorTable(RGBQUAD* colorTab, UINT nColors)
{
CWindowDC dcScreen(NULL);
CDC memdc;
memdc.CreateCompatibleDC(&dcScreen);
CBitmap* pOldBm = memdc.SelectObject(this);
nColors = GetDIBColorTable(memdc, 0, nColors, colorTab);
memdc.SelectObject(pOldBm);
return nColors;
}