📄 openglpanel.cpp
字号:
//|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//| TOpenGLPanel.cpp Version 0.5BCB5 ALPHA
//|
//| This is a implementation of a OpenGL Component for C++ Builder Version 5.0.
//|
//| This code was created by Daniel Plakosh. There are no restrictions on the
//| use or distribution of this code, except that you may not restrict its use
//| or distribution. Any project which is created from this code, or any
//| significant modification of this code, may be distributed in any way you
//| choose; you may even sell it or its source code. However, any limitations
//| placed on the distribution or use of such a project or modification may not
//| in any way limit the distribution or use of this original code.
//|
//| The developer makes no representations about the suitability of this
//| software for any purpose. It is provided "as is" without express or implied
//| warranty.
//|
//| Contact Daniel Plakosh at <dplakosh@cobweb.net> or
//| <dplakosh@sei.cmu.edu> to request assistance or to report a problem with
//| this software. Criticism, suggestions and comments are also greatly
//| appreciated. Remember to always include the TOpenGLPanel version and system
//| information in your messages.
//|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <float.h>
#include <stdlib.h>
#include <Printers.hpp>
#include "OpenGLPanel.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TOpenGLPanel *)
{
new TOpenGLPanel(NULL);
}
//---------------------------------------------------------------------------
namespace Openglpanel
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TOpenGLPanel)};
RegisterComponents("OpenGL_DP", classes, 0);
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TOpenGLPanel::TOpenGLPanel(TComponent* Owner)
: TCustomPanel(Owner)
{
_control87(MCW_EM, MCW_EM);
FdwFlags.Clear();
FdwFlags << f_PFD_DRAW_TO_WINDOW << f_PFD_SUPPORT_OPENGL <<f_PFD_DOUBLEBUFFER;
FiPixelType=f_PFD_TYPE_RGBA;
SavedPixelType=PFD_TYPE_RGBA;
FcColorBits=32;
FcDepthBits=32;
FSwapBuffers=Auto;
FOpenGLPrintScale=pglProportional;
FOpenGLPixelsPerInch=96;
Font3DEnabled=false;
Font3DType= new TFont;
Font3DType->Name="Arial";
Font3DType->Style<< fsBold;
Font3DType->Height=-9;
Font3DType->Charset=ANSI_CHARSET;
Font3DFirstGylph=32;
Font3DNumGylph=96;
Font3DMaxDeviation=0.0;
Font3DExtrusion=0.1;
Font3DFormat=f_WGL_FONT_POLYGONS;
SavedFont3DFormat=WGL_FONT_POLYGONS;
Font3DDefault=NULL;
Font2DEnabled=false;
Font2DType= new TFont;
Font2DType->Name="Arial";
Font2DType->Style<< fsBold;
Font2DType->Height=-9;
Font2DType->Charset=ANSI_CHARSET;
Font2DFirstGylph=32;
Font2DNumGylph=96;
Font2DDefault=NULL;
}
//---------------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private Methods (non-Property)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------------------------------------------------------------------
bool __fastcall TOpenGLPanel::CreateGLContext(void)
{
int PixelFormatIndex;
PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR), // size
1, // version 1
0, // Flags
SavedPixelType, // Color Mode
FcColorBits, // Number of color bits
0,0,0,0,0,0, // RGB color bits with shift (not used)
0,0, // Alpha bits with shift (not used)
0, // Number of accumulator bits
0,0,0,0, // RGBA accumulator bits
FcDepthBits, // Number of bits for Z-Buffer Depth
0, // Stencil buffer depth
0, // Auxiliary buffer depth
PFD_MAIN_PLANE, // Layer type
0, // Reserved
0, // Layer mask
0, // Visible mask
0 // Damage mask
};
if (FdwFlags.Contains(f_PFD_DRAW_TO_WINDOW))
pfd.dwFlags|=PFD_DRAW_TO_WINDOW;
if (FdwFlags.Contains(f_PFD_DRAW_TO_BITMAP))
pfd.dwFlags|= PFD_DRAW_TO_BITMAP;
if (FdwFlags.Contains(f_PFD_SUPPORT_GDI))
pfd.dwFlags|= PFD_SUPPORT_GDI;
else pfd.dwFlags|= PFD_DOUBLEBUFFER;
if (FdwFlags.Contains(f_PFD_SUPPORT_OPENGL))
pfd.dwFlags|= PFD_SUPPORT_OPENGL;
if (FdwFlags.Contains(f_PFD_GENERIC_ACCELERATED))
pfd.dwFlags|= PFD_GENERIC_ACCELERATED;
if (FdwFlags.Contains(f_PFD_GENERIC_FORMAT))
pfd.dwFlags|= PFD_GENERIC_FORMAT;
if (FdwFlags.Contains(f_PFD_NEED_PALETTE))
pfd.dwFlags|=PFD_NEED_PALETTE ;
if (FdwFlags.Contains(f_PFD_NEED_SYSTEM_PALETTE))
pfd.dwFlags|= PFD_NEED_SYSTEM_PALETTE;
if (FdwFlags.Contains(f_PFD_STEREO))
pfd.dwFlags|= PFD_STEREO;
if (FdwFlags.Contains(f_PFD_SWAP_LAYER_BUFFERS))
pfd.dwFlags|=PFD_SWAP_LAYER_BUFFERS;
DisplayDeviceContext=GetDC(this->Handle);
if ((PixelFormatIndex = ChoosePixelFormat(DisplayDeviceContext,&pfd))==0)
{
ShowMessage("ChoosePixelFormat:" + IntToStr(GetLastError()));
ReleaseDC(this->Handle,DisplayDeviceContext);
return false;
}
if (SetPixelFormat(DisplayDeviceContext,PixelFormatIndex,&pfd)!=true)
{
ShowMessage("SetPixelFormat:" + IntToStr(GetLastError()));
ReleaseDC(this->Handle,DisplayDeviceContext);
return false;
}
if (pfd.dwFlags & PFD_DOUBLEBUFFER) DoubleBuffer=true;
else DoubleBuffer=false;
DescribePixelFormat(DisplayDeviceContext,PixelFormatIndex,
sizeof(PIXELFORMATDESCRIPTOR),&pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE)
{
if (ConstructPalette(pfd)==false)
{
ReleaseDC(this->Handle,DisplayDeviceContext);
return false;
}
}
else Palette=NULL;
if ((GLRenderingContext=wglCreateContext(DisplayDeviceContext))==NULL)
{
ShowMessage("wglRenderingContext:" + IntToStr(GetLastError()));
if (Palette)
{
SelectPalette(DisplayDeviceContext,
GetStockObject(DEFAULT_PALETTE),false);
if (DeleteObject(Palette)==false)
ShowMessage("DeleteObject: Failed");
}
ReleaseDC(this->Handle,DisplayDeviceContext);
return false;
}
return true;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::DestroyGLContext(void)
{
delete Font3DDefault;
delete Font2DDefault;
wglMakeCurrent(NULL,NULL);
if (GLRenderingContext!=NULL)
{
if (wglDeleteContext(GLRenderingContext)==false)
ShowMessage("wglDeleteContext:"+IntToStr(GetLastError()));
if ((Palette) && (DeleteObject(Palette)==false))
ShowMessage("DeleteObject: Failed");
if (ReleaseDC(this->Handle,GLRenderingContext)!=0)
ShowMessage("ReleaseDC: Failed");
}
return;
}
//---------------------------------------------------------------------------
bool __fastcall TOpenGLPanel::ConstructPalette(PIXELFORMATDESCRIPTOR &pfd)
{
LOGPALETTE *LPalettep;
WORD NumColors= (WORD)(1 << pfd.cColorBits);
if (( LPalettep=(LOGPALETTE * )
malloc(sizeof(LOGPALETTE)+(sizeof(PALETTEENTRY)*NumColors)))==NULL)
{
ShowMessage("ConstructPalette: Malloc failure");
return false;
}
LPalettep->palVersion=0x300;
LPalettep->palNumEntries=NumColors;
int RedMask =( 1 << pfd.cRedBits ) -1;
int GreenMask =( 1 << pfd.cGreenBits) -1;
int BlueMask =( 1 << pfd.cBlueBits ) -1;
for (int i=0;i<NumColors;i++)
{
LPalettep->palPalEntry[i].peRed=(BYTE)
((((i >> pfd.cRedShift) & RedMask) *255)/RedMask);
LPalettep->palPalEntry[i].peGreen=(BYTE)
((((i >> pfd.cGreenShift) & GreenMask) *255)/GreenMask);
LPalettep->palPalEntry[i].peBlue=(BYTE)
((((i >> pfd.cBlueShift) & BlueMask) *255)/BlueMask);
}
if ((Palette=CreatePalette(LPalettep))==NULL)
{
ShowMessage("CreatePalette:"+IntToStr(GetLastError()));
return false;
}
free(LPalettep);
return true;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Create3DFont(void)
{
delete Font3DDefault;
Font3DDefault=Create3DFont(Font3DType,Font3DFirstGylph,Font3DNumGylph,
Font3DMaxDeviation,Font3DExtrusion,
SavedFont3DFormat);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::Create2DFont(void)
{
delete Font2DDefault;
Font2DDefault=Create2DFont(Font2DType,Font2DFirstGylph,Font2DNumGylph);
}
//---------------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private Methods (Property)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetPFDPixelType(const TPFDPixelTypes Value)
{
if (Value==f_PFD_TYPE_RGBA) SavedPixelType=PFD_TYPE_RGBA;
else SavedPixelType=PFD_TYPE_COLORINDEX;
FiPixelType=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetPFDFlags(const TPFDFlagsSet Value)
{
TPFDFlagsSet Temp=Value;
if ((Value.Contains(f_PFD_SUPPORT_GDI)) &&
(Value.Contains(f_PFD_DOUBLEBUFFER)))
{
if (FdwFlags.Contains(f_PFD_SUPPORT_GDI)) Temp >> f_PFD_SUPPORT_GDI;
else Temp >> f_PFD_DOUBLEBUFFER;
}
else if ((!Value.Contains(f_PFD_SUPPORT_GDI)) &&
(!Value.Contains(f_PFD_DOUBLEBUFFER)))
{
if (FdwFlags.Contains(f_PFD_SUPPORT_GDI)) Temp << f_PFD_DOUBLEBUFFER;
else Temp << f_PFD_SUPPORT_GDI;
}
FdwFlags=Temp;
return;
}
//--------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetPFDNumColorBits(const BYTE Value)
{
FcColorBits=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetPFDNumDepthBits(const BYTE Value)
{
FcDepthBits=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetOpenGLPrintScale(const TOpenGLPrintScale Value)
{
FOpenGLPrintScale=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetOpenGLPixelsPerInch(const int Value)
{
FOpenGLPixelsPerInch=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetFont3DType(TFont* Value)
{
Font3DType->Assign(Value);
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetFont3DFormat(const TFont3DFormat Value)
{
if (Value==f_WGL_FONT_LINES) SavedFont3DFormat=f_WGL_FONT_LINES;
else SavedFont3DFormat=WGL_FONT_POLYGONS;
Font3DFormat=Value;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::SetFont(TFont* Value)
{
Font2DType->Assign(Value);
return;
}
//---------------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Protected Methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::WMCreate(TWMCreate &Message)
{
if (!CreateGLContext())
{
ShowMessage("Open GL Context Create Failed");
return;
}
if (FOnInit)
{
if (wglMakeCurrent(DisplayDeviceContext,GLRenderingContext)==false)
ShowMessage("wglMakeCurrent:" + IntToStr(GetLastError()));
if (Font3DEnabled) Create3DFont();
if (Font2DEnabled) Create2DFont();
FOnInit(this);
wglMakeCurrent(NULL, NULL);
}
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::WMPaletteChanged(TWMPaletteChanged &Message)
{
TWMQueryNewPalette Dummy;
if (Message.PalChg==Handle) return;
WMQueryNewPalette(Dummy);
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::WMQueryNewPalette(TWMQueryNewPalette &Message)
{
UINT num;
HPALETTE OldPalette=SelectPalette(DisplayDeviceContext,Palette,FALSE);
if ((num=RealizePalette(DisplayDeviceContext))==GDI_ERROR)
{
ShowMessage("RealizePalette:"+IntToStr(GetLastError()));
return;
}
if (wglMakeCurrent(DisplayDeviceContext,GLRenderingContext)==false)
{
Message.Result=0;
return;
}
wglMakeCurrent(NULL, NULL);
SelectPalette(GLRenderingContext,OldPalette,TRUE);
if (num) InvalidateRect(Handle,NULL,TRUE); // Force Repaint
Message.Result=num;
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::WMDestroy(TWMDestroy &Message)
{
DestroyGLContext();
return;
}
//---------------------------------------------------------------------------
void __fastcall TOpenGLPanel::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
if (ComponentState.Contains(csDesigning))
{
TRect Rect;
TColor OldColor=Canvas->Brush->Color;
Rect =GetClientRect();
Canvas->Brush->Color=clBtnFace;
Canvas->FillRect(Rect);
Canvas->Brush->Color=OldColor;
}
Message.Result=TRUE;
return;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -