📄 openglpanel.cpp
字号:
void __fastcall TOpenGLPanel::CreateParams(TCreateParams &Params)
{
if (FOnPreInit) FOnPreInit(this);
TCustomPanel::CreateParams(Params);
Params.Style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
Params.ExStyle|= 0; // Place Holder
Params.WindowClass.style|=CS_OWNDC;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Paint(void)
{
//TCustomPanel::Paint();
if (FOnPaint)
{
HPALETTE OldPalette=NULL;
if (Palette)
{
OldPalette=SelectPalette(DisplayDeviceContext,Palette,FALSE);
if (RealizePalette(DisplayDeviceContext)==GDI_ERROR)
{
ShowMessage("RealizePalette:"+IntToStr(GetLastError()));
return;
}
}
if (wglMakeCurrent(DisplayDeviceContext,GLRenderingContext)==false)
{
ShowMessage("wglMakeCurrent:" + IntToStr(GetLastError()));
return;
}
FOnPaint(this);
if ((FSwapBuffers==Auto) && (DoubleBuffer))
::SwapBuffers(DisplayDeviceContext);
if (OldPalette)
SelectPalette(DisplayDeviceContext,OldPalette,TRUE);
wglMakeCurrent(NULL, NULL) ;
}
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Resize(void)
{
TCustomPanel::Resize();
if (FOnResize)
{
if (wglMakeCurrent(DisplayDeviceContext,GLRenderingContext)==false)
{
ShowMessage("wglMakeCurrent:" + IntToStr(GetLastError()));
return;
}
FOnResize(this);
wglMakeCurrent(NULL, NULL) ;
}
return;
}
//---------------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Public Methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::MakeOpenGLPanelCurrent(void)
{
if (wglMakeCurrent(DisplayDeviceContext,GLRenderingContext)==false)
{
ShowMessage("wglMakeCurrent:" + IntToStr(GetLastError()));
}
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::MakeOpenGLPanelNotCurrent(void)
{
wglMakeCurrent(NULL, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SwapBuffers(void)
{
if (DoubleBuffer) ::SwapBuffers(DisplayDeviceContext);
}
//---------------------------------------------------------------------------
bool __fastcall TOpenGLPanel::PanelShareLists(TOpenGLPanel *WithOpenGLPanel)
{
return(wglShareLists(this->GLRenderingContext,
WithOpenGLPanel->GLRenderingContext));
}
//---------------------------------------------------------------------------
BMPTexture * __fastcall TOpenGLPanel::LoadBMPTexture(AnsiString FileName,
Boolean WithAlpha)
{
Graphics::TBitmap * Bitmap= new Graphics::TBitmap();
BMPTexture * BMPTex =new BMPTexture();;
try
{
int Onedarray;
Bitmap->LoadFromFile(FileName);
if (WithAlpha) BMPTex->Components=4;
else BMPTex->Components=3;
BMPTex->Width= Bitmap->Width;
BMPTex->Height=Bitmap->Height;
BMPTex->Format=WithAlpha?GL_RGBA:GL_RGB;
BMPTex->Type=GL_UNSIGNED_BYTE;
BMPTex->Pixels = new GLubyte[BMPTex->Width*BMPTex->Height*BMPTex->Components];
for (long i=0; i<BMPTex->Height; i++)
for (long j=0; j<BMPTex->Width; j++)
{
Onedarray=i*BMPTex->Width*BMPTex->Components+j*BMPTex->Components;
BMPTex->Pixels[Onedarray+0] =
GetRValue(Bitmap->Canvas->Pixels[j][BMPTex->Height-i-1]);
BMPTex->Pixels[Onedarray+1] =
GetGValue(Bitmap->Canvas->Pixels[j][BMPTex->Height-i-1]);
BMPTex->Pixels[Onedarray+2] =
GetBValue(Bitmap->Canvas->Pixels[j][BMPTex->Height-i-1]);
if (WithAlpha) BMPTex->Pixels[Onedarray+3] = 255;
}
}
catch (...)
{
delete Bitmap;
delete BMPTex;
return(NULL);
}
delete Bitmap;
return(BMPTex);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::PrintOpenGLPanel(void)
{
Graphics::TBitmap *BitMap = new Graphics::TBitmap();
int XPixelsPerInch,YPixelsPerInch,
XSizeInPixels,YSizeInPixels;
unsigned int BitMapInfoSize,BitMapImageSize;
void *BitMapImage;
BITMAPINFO *BitMapInfo;
RECT Rect;
BitMap->Height= Height;
BitMap->Width = Width;
BringToFront();
Paint();
BitMap->Canvas->CopyRect(ClientRect ,Canvas,ClientRect);
XPixelsPerInch=GetDeviceCaps(Printer()->Handle,LOGPIXELSX);
YPixelsPerInch=GetDeviceCaps(Printer()->Handle,LOGPIXELSY);
Rect.left =0.18*XPixelsPerInch;
Rect.top =0.18*YPixelsPerInch;
if (FOpenGLPrintScale==pglPrintToFit)
{
XSizeInPixels=GetDeviceCaps(Printer()->Handle,HORZRES)-2*Rect.left;
YSizeInPixels=GetDeviceCaps(Printer()->Handle,VERTRES)-2*Rect.top;
if (XSizeInPixels > YSizeInPixels)
{
Rect.right=BitMap->Width*(YSizeInPixels/BitMap->Height);
Rect.bottom=YSizeInPixels;
}
else
{
Rect.right= XSizeInPixels;
Rect.bottom = BitMap->Height* (XSizeInPixels / BitMap->Width);
}
}
else if (FOpenGLPrintScale==pglProportional)
{
if (FOpenGLPixelsPerInch<=0) FOpenGLPixelsPerInch=96;
Rect.right =(int)(((float)BitMap->Width/(float)FOpenGLPixelsPerInch)*
(float)XPixelsPerInch)+Rect.left;
Rect.bottom=(int)(((float)BitMap->Height/(float)FOpenGLPixelsPerInch)*
(float)YPixelsPerInch)+Rect.top;
}
else // pglNone
{
Rect.right =BitMap->Width+Rect.left;
Rect.bottom=BitMap->Height+Rect.right;
}
GetDIBSizes(BitMap->Handle,BitMapInfoSize,BitMapImageSize);
BitMapInfo=(BITMAPINFO *)malloc(BitMapInfoSize);
BitMapImage=malloc(BitMapImageSize);
if ((BitMapInfo==NULL) || (BitMapImage==NULL))
{
ShowMessage("Print: Malloc Error");
if (BitMapInfo) free(BitMapInfo);
if (BitMapImage) free(BitMapImage);
return;
}
Printer()->BeginDoc();
GetDIB(BitMap->Handle,BitMap->Palette,BitMapInfo,BitMapImage);
StretchDIBits(Printer()->Canvas->Handle,
Rect.left,Rect.top,
Rect.right-Rect.left,
Rect.bottom-Rect.top,
0,0,
BitMap->Width,BitMap->Height,
BitMapImage,
BitMapInfo,
DIB_RGB_COLORS,
SRCCOPY);
free(BitMapInfo);
free(BitMapImage);
Printer()->EndDoc();
delete BitMap;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SaveOpenGLPanelToFile(const String &FileName)
{
Graphics::TBitmap *BitMap = new Graphics::TBitmap();
BitMap->Height= Height;
BitMap->Width = Width;
BringToFront();
Paint();
BitMap->Canvas->CopyRect(ClientRect ,Canvas,ClientRect);
BitMap->SaveToFile(FileName);
delete BitMap;
return;
}
//---------------------------------------------------------------------------
OpenGLFont3D * __fastcall TOpenGLPanel::Create3DFont(TFont *Font,
int FirstGylph,
int NumGylph,
float Deviation,
float Extrusion,
int Format)
{
HFONT HFont;
LOGFONT LogFont;
GLuint Base;
if (Font==NULL) return(NULL);
if ((Base=glGenLists(NumGylph))==0) return(NULL);
OpenGLFont3D *Font3D=new OpenGLFont3D();
Font3D->FirstGylph=FirstGylph;
Font3D->NumGylph=NumGylph;
Font3D->ListBase=Base;
Font3D->Extrusion=Extrusion;
Font3D->GlyphMetrics= new GLYPHMETRICSFLOAT[NumGylph];
GetObject(Font->Handle,sizeof(LOGFONT),&LogFont);
// FYI To go from LogFont -> Handle use:
// Font->Handle =CreateFontIndirect(LogFont);
HFont = CreateFontIndirect(&LogFont);
SelectObject (DisplayDeviceContext, HFont);
wglUseFontOutlines(DisplayDeviceContext, FirstGylph, NumGylph, Base,
Deviation, Extrusion, Format, Font3D->GlyphMetrics);
DeleteObject(HFont);
return(Font3D);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Get3DTextSize(AnsiString Text,GLdouble *XYZ)
{
Get3DTextSize(Font3DDefault,Text,XYZ);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Get3DTextSize(OpenGLFont3D *Font,
AnsiString Text,GLdouble *XYZ)
{
unsigned char *c=(unsigned char *)Text.c_str();
int Index,Length=strlen((char *)c);
if ((Font==NULL)||(XYZ==NULL)||(Length==0)) return;
XYZ[0]=0.0;
XYZ[1]=0.0;
XYZ[2]=Font->Extrusion;
for (int i=0;i<Length;i++)
{
Index=c[i]- Font->FirstGylph;
if ((Index<0)||(Index>Font->NumGylph-1))
{
XYZ[0]=XYZ[1]=XYZ[2]=0.0;
return;
}
XYZ[0]+=Font->GlyphMetrics[Index].gmfCellIncX;
// XYZ[1]+=Font->GlyphMetrics[Index].gmfCellIncY;
}
Index=c[Length-1]- Font->FirstGylph;
if ((Index<0)||(Index>Font->NumGylph-1))
{
XYZ[0]=XYZ[1]=XYZ[2]=0.0;
return;
}
// XYZ[0]+=Font->GlyphMetrics[Index].gmfBlackBoxX;
XYZ[1]+=Font->GlyphMetrics[Index].gmfBlackBoxY;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Draw3DText(AnsiString Text)
{
Draw3DText(Font3DDefault,Text);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Draw3DText(OpenGLFont3D *Font,AnsiString Text)
{
GLint FaceMode;
unsigned char *c=(unsigned char *)Text.c_str();
int Index,Length=strlen((char *)c);
if ((Font==NULL)||(Length==0)) return;
for (int i=0;i<Length;i++)
{
Index=c[i]- Font->FirstGylph;
if ((Index<0)||(Index>Font->NumGylph-1)) return;
}
glPushAttrib(GL_LIST_BIT);
glGetIntegerv(GL_FRONT_FACE,&FaceMode);
glListBase(Font->ListBase-Font->FirstGylph);
glCallLists (Length, GL_UNSIGNED_BYTE,c);
glFrontFace(FaceMode);
glPopAttrib();
return;
}
//---------------------------------------------------------------------------
OpenGLFont2D * __fastcall TOpenGLPanel::Create2DFont(TFont *Font,
int FirstGylph,
int NumGylph)
{
HFONT HFont;
LOGFONT LogFont;
GLuint Base;
if (Font==NULL) return(NULL);
if ((Base=glGenLists(NumGylph))==0) return(NULL);
OpenGLFont2D *Font2D=new OpenGLFont2D();
Font2D->FirstGylph=FirstGylph;
Font2D->NumGylph=NumGylph;
Font2D->ListBase=Base;
GetObject(Font->Handle,sizeof(LOGFONT),&LogFont);
// FYI To go from LogFont -> Handle use:
// Font->Handle =CreateFontIndirect(LogFont);
HFont = CreateFontIndirect(&LogFont);
SelectObject (DisplayDeviceContext, HFont);
wglUseFontBitmaps(DisplayDeviceContext, FirstGylph, NumGylph, Base);
DeleteObject(HFont);
return(Font2D);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Draw2DText(AnsiString Text)
{
Draw2DText(Font2DDefault,Text);
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Draw2DText(OpenGLFont2D *Font,AnsiString Text)
{
unsigned char *c=(unsigned char *)Text.c_str();
int Index,Length=strlen((char *)c);
if ((Font==NULL)||(Length==0)) return;
for (int i=0;i<Length;i++)
{
Index=c[i]- Font->FirstGylph;
if ((Index<0)||(Index>Font->NumGylph-1)) return;
}
glPushAttrib(GL_LIST_BIT);
glListBase(Font->ListBase-Font->FirstGylph);
glCallLists (Length, GL_UNSIGNED_BYTE,c);
glPopAttrib();
return;
}
//---------------------------------------------------------------------------
bool __fastcall TOpenGLPanel::QueryOpenGLExtention(AnsiString ExtentionName)
{
char *GLExtentions,*LastChar,*ExtQName=ExtentionName.c_str();
int ExtLen,ExtQNameLen= strlen(ExtQName);
if ((GLExtentions =(char *)glGetString(GL_EXTENSIONS))==NULL) return(false);
LastChar = GLExtentions + strlen(GLExtentions);
while (GLExtentions < LastChar)
{
ExtLen= strcspn(GLExtentions, " ");
if ((ExtQNameLen == ExtLen) && (strncmp(ExtQName,GLExtentions,ExtLen) == 0))
return true;
GLExtentions += (ExtLen + 1);
}
return false;
}
//---------------------------------------------------------------------------
int __fastcall TOpenGLPanel::GetDisplayBPP(void)
{
int BPP;
HDC DeviceContext=GetDC(NULL);
BPP=GetDeviceCaps(DeviceContext,BITSPIXEL);
ReleaseDC(NULL,DeviceContext);
return(BPP);
}
//---------------------------------------------------------------------------
bool __fastcall TOpenGLPanel::SetDisplayBPP(int BPP)
{
// Warning:: this code does not work correctly
// It was intended to be executed in the OnPreInit Event
// The display mode changes but then GL Initializaion Fails??
DEVMODE LPDevMode;
ZeroMemory(&LPDevMode,sizeof(LPDevMode));
LPDevMode.dmSize=sizeof(LPDevMode);
LPDevMode.dmBitsPerPel=BPP;
LPDevMode.dmFields=DM_BITSPERPEL;
return(ChangeDisplaySettings(&LPDevMode,0)==DISP_CHANGE_SUCCESSFUL?true:false);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -