📄 bmpsurf.cpp
字号:
// (C) Copyright 1996 by Anthony J. Carin. All Rights Reserved.
#include "stdafx.h"
#include "3dengine.h"
#include "bmpsurf.h"
#include "3dtools.h"
bmpsurf::bmpsurf(CString& filename) : surfs()
{
m_red = new float[256];
m_green = new float[256];
m_blue = new float[256];
LoadBitmapFile(filename);
CreateColorTables();
prev = 0;
next = Game->Bmpsurfs()->m_First;
if (Game->Bmpsurfs()->m_First)
Game->Bmpsurfs()->m_First->prev = this;
Game->Bmpsurfs()->m_First = this;
m_exempt = FALSE;
if (fabs(m_a.y() - m_c.y()) < 1.0)
m_higharea = new higharea(*this);
else
m_higharea = NULL;
}
bmpsurf::~bmpsurf()
{
char *ptr = (char *) m_pBmInfo;
delete [] ptr;
delete [] m_red;
delete [] m_green;
delete [] m_blue;
delete m_higharea;
if (prev)
{
prev->next = next;
if (next)
next->prev = prev;
if (Game->Bmpsurfs()->m_Curr == this)
Game->Bmpsurfs()->m_Curr = Game->Bmpsurfs()->m_First;
}
else
{
Game->Bmpsurfs()->m_First = next;
if (Game->Bmpsurfs()->m_Curr == this)
Game->Bmpsurfs()->m_Curr = Game->Bmpsurfs()->m_First;
if (next)
next->prev = 0;
}
}
void bmpsurf::LoadBitmapFile(CString& filename)
{
CFile file(filename, CFile::modeRead);
BITMAPFILEHEADER bmFileHeader;
file.Read((void*)&bmFileHeader, sizeof(bmFileHeader));
if (bmFileHeader.bfType != 0x4d42)
{
AfxMessageBox("Not a bitmap file");
m_pBmFileHeader = 0;
m_pBmInfo = 0;
m_pBmInfoHeader = 0;
m_pRGBTable = 0;
m_pDibBits = 0;
m_numColors = 0;
}
else
{
DWORD fileLength = file.GetLength();
dibSize = fileLength - sizeof(bmFileHeader);
char* pDib = new char[dibSize];
file.Read((void*)pDib, dibSize);
file.Close();
m_pBmInfo = (LPBITMAPINFO) pDib;
m_pBmInfoHeader = (LPBITMAPINFOHEADER) pDib;
m_pRGBTable = (RGBQUAD*)(pDib + m_pBmInfoHeader->biSize);
uint m_numColors = GetDibNumColors();
m_pBmInfoHeader->biSizeImage = GetDibSizeImage();
if (m_pBmInfoHeader->biClrUsed == 0)
m_pBmInfoHeader->biClrUsed = m_numColors;
DWORD clrTableSize = m_numColors * sizeof(RGBQUAD);
m_pDibBits = pDib + m_pBmInfoHeader->biSize + clrTableSize;
}
}
DWORD bmpsurf::GetDibSizeImage()
{
if (m_pBmInfoHeader->biSizeImage == 0)
{
DWORD byteWidth = (DWORD) GetDibWidth();
DWORD height = (DWORD) GetDibHeight();
DWORD imageSize = byteWidth * height;
return imageSize;
}
else
return m_pBmInfoHeader->biSizeImage;
}
uint bmpsurf::GetDibNumColors()
{
if ((m_pBmInfoHeader->biClrUsed == 0) &&
(m_pBmInfoHeader->biBitCount < 9))
return (1 << m_pBmInfoHeader->biBitCount);
else
return (int) m_pBmInfoHeader->biClrUsed;
}
void bmpsurf::CreateColorTables()
{
LPRGBQUAD pColorTable = GetDibRGBTablePtr();
for (uint i = 0; i < 256; i++)
{
m_red[i] = (float) pColorTable[i].rgbRed / 255;
m_green[i] = (float) pColorTable[i].rgbGreen / 255;
m_blue[i] = (float) pColorTable[i].rgbBlue / 255;
}
wglMakeCurrent(Game->hdc, Game->hrc);
glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 256, m_red);
glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 256, m_green);
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, m_blue);
glPixelTransferi(GL_MAP_COLOR, TRUE);
wglMakeCurrent(Game->hdc, NULL);
}
void bmpsurf::draw()
{
glTexImage2D(GL_TEXTURE_2D, 0, 3, GetDibWidth(), GetDibHeight(),
0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid*) GetDibBitsPtr());
Game->Tool3d()->beginbmp();
Game->Tool3d()->bmpvertex1(m_a.x(), m_a.y(), m_a.z());
Game->Tool3d()->bmpvertex2(m_b.x(), m_b.y(), m_b.z());
Game->Tool3d()->bmpvertex3(m_c.x(), m_c.y(), m_c.z());
Game->Tool3d()->bmpvertex4(m_d.x(), m_d.y(), m_d.z());
Game->Tool3d()->endbmp();
}
void bmpsurf::operator =(surfs& s)
{
if (m_higharea)
*((surfs *)m_higharea) = s;
surfs::operator =(s);
}
char bmpsurf::intersects(coordinate &a, coordinate &b)
{
if (m_exempt)
return FALSE;
if (!sameintersectpoints(a,b))
calcintersect(a,b);
return m_intersects;
}
void bmpsurf::calcintersect(coordinate& pa,coordinate& pb)
{
point mid;
float b, m;
point tmpcoord;
coordinate savecenter;
coordinate center = savecenter = getcenter();
m_intersectfrom = pa;
m_intersectto = pb;
surfs tmpsurf((coordinate)(m_a - center),
(coordinate)(m_b - center),
(coordinate)(m_c - center),
(coordinate)(m_d - center));
point npa = pa - center;
point npb = pb - center;
center.setx(0.0f);
center.sety(0.0f);
center.setz(0.0f);
mid.setto((tmpsurf.a().x() + tmpsurf.b().x()) / 2,
(tmpsurf.a().y() + tmpsurf.b().y()) / 2,
(tmpsurf.a().z() + tmpsurf.b().z()) / 2);
direction ydir = center.ydirectionto(mid);
ydir = ydir - (direction) TC_PI_2;
tmpsurf.yrotate(ydir);
npa.yrotate(ydir);
npb.yrotate(ydir);
mid.setto((tmpsurf.a().x() + tmpsurf.b().x()) / 2,
(tmpsurf.a().y() + tmpsurf.b().y()) / 2,
(tmpsurf.a().z() + tmpsurf.b().z()) / 2);
direction zdir = center.zdirectionto(mid);
zdir = zdir - (direction) TC_PI_2;
tmpsurf.zrotate(zdir);
npa.zrotate(zdir);
npb.zrotate(zdir);
mid.setto((tmpsurf.a().x() + tmpsurf.b().x()) / 2,
(tmpsurf.a().y() + tmpsurf.b().y()) / 2,
(tmpsurf.a().z() + tmpsurf.b().z()) / 2);
direction xdir = mid.xdirectionto(tmpsurf.a());
tmpsurf.xrotate(xdir);
npa.xrotate(xdir);
npb.xrotate(xdir);
if ((npa.y() < 0 && npb.y() < 0) ||
(npa.y() >= 0 && npb.y() >= 0))
{
m_intersects = FALSE;
return;
}
m = npa.x() - npb.x();
tmpcoord.sety(0.0f);
if (m == 0)
tmpcoord.setx(npa.x());
else
{
m = (npa.y() - npb.y()) / m;
if (m == 0)
{
m_intersects = FALSE;
return;
}
b = npa.y() - m * npa.x();
tmpcoord.setx(-b/m);
}
m = npa.z() - npb.z();
if (m == 0)
tmpcoord.setz(npa.z());
else
{
m = (npa.y() - npb.y()) / m;
if (m == 0)
{
m_intersects = FALSE;
return;
}
b = npa.y() - m * npa.z();
tmpcoord.setz(-b/m);
}
if (!tmpsurf.iswithin(tmpcoord))
{
m_intersects = FALSE;
return;
}
m_intersects = TRUE;
tmpcoord.xrotate(-xdir);
tmpcoord.zrotate(-zdir);
tmpcoord.yrotate(-ydir);
m_intersectpoint = tmpcoord + savecenter;
return;
}
void bmpsurf::operator +=(coordinate& c)
{
if (m_higharea)
m_higharea->operator +=(c);
surfs::operator +=(c);
}
void bmpsurf::setto(coordinate& a, coordinate& b, coordinate& c, coordinate& d)
{
if (m_higharea)
m_higharea->setto(a,b,c,d);
surfs::setto(a,b,c,d);
}
void bmpsurf::ExemptFromIntersect()
{
m_exempt = TRUE;
if (m_higharea)
{
delete m_higharea;
m_higharea = NULL;
}
}
void bmpsurf::OKToIntersect()
{
m_exempt = FALSE;
if (!m_higharea)
{
if (fabs(m_a.y() - m_c.y()) < 1.0)
m_higharea = new higharea(*this);
else
m_higharea = NULL;
}
}
void bmplist::Purge()
{
bmpsurf *TmpFirst = m_First;
bmpsurf *TmpCurr;
while (TmpFirst)
{
TmpCurr = TmpFirst;
TmpFirst = TmpFirst->next;
delete m_Curr;
}
m_First = m_Curr = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -