mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-08 18:40:55 +03:00
300 lines
7.7 KiB
C++
300 lines
7.7 KiB
C++
// File: OpenGl_Display.cxx
|
|
// Created: 20 September 2011
|
|
// Author: Sergey ZERCHANINOV
|
|
// Copyright: OPEN CASCADE 2011
|
|
|
|
#include <OpenGl_Display.hxx>
|
|
|
|
#include <OSD_Environment.hxx>
|
|
#include <TCollection_AsciiString.hxx>
|
|
#include <Aspect_GraphicDeviceDefinitionError.hxx>
|
|
|
|
#include <OpenGl_tgl_all.hxx>
|
|
#include <GL/gl.h>
|
|
|
|
#include <OpenGl_Light.hxx>
|
|
|
|
IMPLEMENT_STANDARD_HANDLE(OpenGl_Display,MMgt_TShared)
|
|
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Display,MMgt_TShared)
|
|
|
|
Handle(OpenGl_Display) openglDisplay;
|
|
|
|
namespace
|
|
{
|
|
#if (defined(_WIN32) || defined(__WIN32__))
|
|
static char* TheDummyDisplay = "DISPLAY";
|
|
#endif
|
|
|
|
static const OpenGl_Facilities myDefaultFacilities = { 1, 1, 1, 1, OpenGLMaxLights, 10000 };
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
OpenGl_Display::OpenGl_Display (const Standard_CString theDisplay)
|
|
: myDisplay(NULL),
|
|
myFacilities(myDefaultFacilities),
|
|
myDBuffer(Standard_True),
|
|
myDither(Standard_True),
|
|
myBackDither(Standard_False),
|
|
myWalkthrough(Standard_False),
|
|
mySymPerspective(Standard_False),
|
|
myOffsetFactor(1.F),
|
|
myOffsetUnits(0.F),
|
|
myAntiAliasingMode(3),
|
|
myLinestyleBase(0),
|
|
myPatternBase(0),
|
|
myMarkerBase(0),
|
|
myFont(-1),
|
|
myFontSize(-1)
|
|
{
|
|
#if (defined(_WIN32) || defined(__WIN32__))
|
|
myDisplay = TheDummyDisplay;
|
|
#else
|
|
if (theDisplay != NULL && *theDisplay != '\0')
|
|
{
|
|
OSD_Environment aDispEnv ("DISPLAY", theDisplay);
|
|
aDispEnv.Build();
|
|
}
|
|
|
|
// Specifies the hardware display name, which determines the
|
|
// display and communications domain to be used.
|
|
// On a POSIX system, if the display_name is NULL, it defaults
|
|
// to the value of the DISPLAY environment variable.
|
|
myDisplay = XOpenDisplay (NULL);
|
|
#endif
|
|
|
|
Init();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
OpenGl_Display::OpenGl_Display (const Aspect_Display theDisplay)
|
|
: myDisplay(NULL),
|
|
myFacilities(myDefaultFacilities),
|
|
myDBuffer(Standard_True),
|
|
myDither(Standard_True),
|
|
myBackDither(Standard_False),
|
|
myWalkthrough(Standard_False),
|
|
mySymPerspective(Standard_False),
|
|
myOffsetFactor(1.F),
|
|
myOffsetUnits(0.F),
|
|
myAntiAliasingMode(3),
|
|
myLinestyleBase(0),
|
|
myPatternBase(0),
|
|
myMarkerBase(0),
|
|
myFont(-1),
|
|
myFontSize(-1)
|
|
{
|
|
#if (defined(_WIN32) || defined(__WIN32__))
|
|
myDisplay = TheDummyDisplay;
|
|
#else
|
|
myDisplay = theDisplay;
|
|
#endif
|
|
|
|
Init();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
OpenGl_Display::~OpenGl_Display ()
|
|
{
|
|
// Delete line styles
|
|
if (myLinestyleBase)
|
|
{
|
|
glDeleteLists((GLuint)myLinestyleBase,5);
|
|
myLinestyleBase = 0;
|
|
}
|
|
// Delete surface patterns
|
|
if (myPatternBase)
|
|
{
|
|
glDeleteLists((GLuint)myPatternBase,TEL_HS_USER_DEF_START);
|
|
myPatternBase = 0;
|
|
}
|
|
// Delete markers
|
|
if (myMarkerBase)
|
|
{
|
|
glDeleteLists((GLuint)myMarkerBase,60);
|
|
myMarkerBase = 0;
|
|
}
|
|
// Delete user markers
|
|
OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
|
|
for (; itm.More(); itm.Next())
|
|
{
|
|
const OPENGL_MARKER_DATA &aData = itm.Value();
|
|
if (aData.Array)
|
|
{
|
|
delete[] aData.Array;
|
|
}
|
|
else if (aData.ListId != 0)
|
|
{
|
|
glDeleteLists ( aData.ListId, 1 );
|
|
}
|
|
}
|
|
myDisplay = NULL;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
Handle(OpenGl_Window) OpenGl_Display::GetWindow (const Aspect_Drawable AParent) const
|
|
{
|
|
Handle(OpenGl_Window) aWindow;
|
|
if ( myMapOfWindows.IsBound( AParent ) )
|
|
{
|
|
aWindow = myMapOfWindows.Find( AParent );
|
|
}
|
|
return aWindow;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void OpenGl_Display::SetWindow (const Aspect_Drawable AParent, const Handle(OpenGl_Window) &AWindow)
|
|
{
|
|
if ( !myMapOfWindows.IsBound( AParent ) )
|
|
{
|
|
myMapOfWindows.Bind( AParent, AWindow );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
//GenerateMarkerBitmap
|
|
void OpenGl_Display::AddUserMarker (const Standard_Integer AIndex,
|
|
const Standard_Integer AMarkWidth,
|
|
const Standard_Integer AMarkHeight,
|
|
const Handle(TColStd_HArray1OfByte)& ATexture)
|
|
{
|
|
if (!myMapOfUM.IsBound(AIndex))
|
|
{
|
|
const OPENGL_MARKER_DATA anEmptyData = { 0, 0, 0, NULL };
|
|
myMapOfUM.Bind(AIndex,anEmptyData);
|
|
}
|
|
|
|
OPENGL_MARKER_DATA &aData = myMapOfUM.ChangeFind(AIndex);
|
|
|
|
if (aData.Array)
|
|
{
|
|
delete[] aData.Array;
|
|
aData.Array = NULL;
|
|
}
|
|
|
|
unsigned char *anArray = new unsigned char[ATexture->Length()];
|
|
|
|
const int aByteWidth = AMarkWidth / 8;
|
|
int i, anIndex = ATexture->Upper() - ATexture->Lower() - aByteWidth + 1;
|
|
for ( ; anIndex >= 0; anIndex -= aByteWidth )
|
|
for ( i = 0; i < aByteWidth; i++ )
|
|
anArray[ATexture->Upper() - ATexture->Lower() - aByteWidth + 1 - anIndex + i ] = ATexture->Value( anIndex + i + 1 );
|
|
|
|
aData.Width = AMarkWidth;
|
|
aData.Height = AMarkHeight;
|
|
aData.Array = anArray;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void OpenGl_Display::UpdateUserMarkers ()
|
|
{
|
|
OpenGl_MapOfUserMarker::Iterator itm(myMapOfUM);
|
|
for (; itm.More(); itm.Next())
|
|
{
|
|
OPENGL_MARKER_DATA &aData = itm.ChangeValue();
|
|
if (aData.Array)
|
|
{
|
|
if (aData.ListId == 0)
|
|
aData.ListId = glGenLists(1);
|
|
|
|
glNewList( (GLuint)aData.ListId, GL_COMPILE );
|
|
|
|
GLint w = ( GLsizei ) aData.Width;
|
|
GLint h = ( GLsizei ) aData.Height;
|
|
glBitmap( w, h,
|
|
0.5F * ( float )aData.Width, 0.5F * ( float )aData.Height,
|
|
( float )30.0, ( float )30.0,
|
|
( GLubyte* )aData.Array );
|
|
|
|
glEndList();
|
|
|
|
delete[] aData.Array;
|
|
aData.Array = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
Standard_Integer OpenGl_Display::GetUserMarkerListIndex (const Standard_Integer AIndex) const
|
|
{
|
|
if (myMapOfUM.IsBound(AIndex))
|
|
{
|
|
const OPENGL_MARKER_DATA &aData = myMapOfUM.Find(AIndex);
|
|
if (!aData.Array)
|
|
return aData.ListId;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void OpenGl_Display::Init()
|
|
{
|
|
if (myDisplay != NULL)
|
|
{
|
|
#if (!defined(_WIN32) && !defined(__WIN32__))
|
|
XSynchronize ((Display* )myDisplay, (getenv("CALL_SYNCHRO_X") != NULL) ? 1 : 0);
|
|
|
|
if (getenv("CSF_GraphicSync") != NULL)
|
|
XSynchronize ((Display* )myDisplay, 1);
|
|
|
|
// does the server know about OpenGL & GLX?
|
|
int aDummy;
|
|
if (!XQueryExtension ((Display* )myDisplay, "GLX", &aDummy, &aDummy, &aDummy))
|
|
{
|
|
#ifdef DEBUG
|
|
std::cerr << "This system doesn't appear to support OpenGL\n";
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
TCollection_AsciiString msg("OpenGl_Display::Init");
|
|
#if (!defined(_WIN32) && !defined(__WIN32__))
|
|
msg += " : Cannot connect to X server ";
|
|
msg += XDisplayName ((char*) NULL);
|
|
#endif
|
|
Aspect_GraphicDeviceDefinitionError::Raise(msg.ToCString());
|
|
}
|
|
|
|
if (getenv("CALL_OPENGL_NO_DBF") != NULL)
|
|
myDBuffer = Standard_False;
|
|
|
|
if (getenv("CALL_OPENGL_NO_DITHER") != NULL)
|
|
myDither = Standard_False;
|
|
|
|
if (getenv("CALL_OPENGL_NO_BACKDITHER") != NULL)
|
|
myBackDither = Standard_False;
|
|
|
|
if (getenv("CSF_WALKTHROUGH") != NULL)
|
|
myWalkthrough = Standard_True;
|
|
|
|
/* OCC18942: Test if symmetric perspective projection should be turned on */
|
|
if (getenv("CSF_SYM_PERSPECTIVE") != NULL)
|
|
mySymPerspective = Standard_True;
|
|
|
|
const char* pvalue = getenv("CALL_OPENGL_POLYGON_OFFSET");
|
|
if (pvalue)
|
|
{
|
|
float v1, v2;
|
|
const int n = sscanf(pvalue, "%f %f", &v1, &v2);
|
|
if (n > 0) myOffsetFactor = v1;
|
|
if (n > 1) myOffsetUnits = v2;
|
|
}
|
|
|
|
pvalue = getenv("CALL_OPENGL_ANTIALIASING_MODE");
|
|
if (pvalue)
|
|
{
|
|
int v;
|
|
if ( sscanf(pvalue,"%d",&v) > 0 ) myAntiAliasingMode = v;
|
|
}
|
|
}
|