⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openglpanel.cpp

📁 OpenGL Panel Component for Borland C++ Builder 2006
💻 CPP
📖 第 1 页 / 共 2 页
字号:
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 + -