1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/OpenGl/OpenGl_Workspace_3.cxx
kgv 5f8b738ea5 0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one place
Extend OpenGl_Context to provide GL2.0 core functionality

Added 'glext.h' header provided by Khronos group with definitions
and GL functions' types.
Added OpenGl_GlCoreXX structures with function list
to appropriate GL core functionality.
Fixed memory leak in OpenGl_Context destructor.
Eliminate inclusions of gl.h header
Use OpenGl_GlCore11.hxx instead.
Removed obsolote M_PI redefinitions.
Slightly cleaned up included headers.
Reuse definitions from glext.h
OpenGl_ArbVBO and OpenGl_ExtFBO originally provide own definitions
for OpenGL extensions.
2012-03-15 13:58:13 +04:00

468 lines
12 KiB
C++

// File: OpenGl_Workspace_3.cxx
// Created: 20 September 2011
// Author: Sergey ZERCHANINOV
// Copyright: OPEN CASCADE 2011
#include <math.h>
#include <stdio.h>
#include <OpenGl_GlCore11.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_telem_util.hxx>
#include <OpenGl_AspectLine.hxx>
#include <OpenGl_Structure.hxx>
#ifdef HAVE_GL2PS
#include <gl2ps.h>
#endif
/*----------------------------------------------------------------------*/
/*
* Prototypes Private functions
*/
static void call_util_transform_pt (float *x, float *y, float *z);
static void call_util_transpose_mat (float tmat[16], float mat[4][4]);
/*----------------------------------------------------------------------*/
/*
* Variables statiques
*/
static int openglNumberOfPoints = 0;
static int myImmediateMatIsIdentity = 1;
static int partial = -1; /* -1 init, 0 complete, 1 partielle */
static float xm, ym, zm, XM, YM, ZM;
static float myImmediateMat[4][4] = {
{1., 0., 0., 0.},
{0., 1., 0., 0.},
{0., 0., 1., 0.},
{0., 0., 0., 1.},
};
/*----------------------------------------------------------------------*/
/* Mode Ajout */
/*----------------------------------------------------------------------*/
//call_togl_begin_ajout_mode
Standard_Boolean OpenGl_Workspace::BeginAddMode ()
{
if (!Activate())
return Standard_False;
NamedStatus |= OPENGL_NS_ADD;
MakeFrontAndBackBufCurrent();
//TsmPushAttri();
return Standard_True;
}
/*----------------------------------------------------------------------*/
//call_togl_end_ajout_mode
void OpenGl_Workspace::EndAddMode ()
{
if (NamedStatus & OPENGL_NS_ADD)
{
OpenGl_Workspace::MakeBackBufCurrent();
// Clear add mode flag
NamedStatus &= ~OPENGL_NS_ADD;
}
myImmediateMatIsIdentity = 1;
/* FMN necessaire pour l'affichage sur WNT */
glFlush();
//TsmPopAttri();
}
/*----------------------------------------------------------------------*/
/* Mode Transient */
/*----------------------------------------------------------------------*/
//call_togl_clear_immediat_mode
void OpenGl_Workspace::ClearImmediatMode (const Graphic3d_CView& ACView, const Standard_Boolean AFlush)
{
if ( myIsTransientOpen )
EndImmediatMode();
if (!Activate()) return;
if ( !myBackBufferRestored )
{
EraseAnimation();
Redraw1(ACView,*((CALL_DEF_LAYER *)ACView.ptrUnderLayer),*((CALL_DEF_LAYER *)ACView.ptrOverLayer),AFlush);
// After a redraw,
// Made the back identical to the front buffer.
// Always perform full copy (partial update optimization is useless on mordern hardware)!
if (myRetainMode)
CopyBuffers (ACView.ViewId, 1 /* GL_FRONT -> GL_BACK */, xm, ym, zm, XM, YM, ZM, 0);
myBackBufferRestored = Standard_True;
}
else if ( partial >= 0 )
{
// Restore pixels from the back buffer.
// Always perform full copy (partial update optimization is useless on mordern hardware)!
CopyBuffers (ACView.ViewId, 0 /* GL_BACK -> GL_FRONT */, xm, ym, zm, XM, YM, ZM, 0);
}
if (myTransientList)
{
/* Clear current list contents */
glNewList( (GLuint) myTransientList, GL_COMPILE_AND_EXECUTE);
glEndList();
}
partial = -1;
XM = YM = ZM = (float ) shortrealfirst ();
xm = ym = zm = (float ) shortreallast ();
}
/*----------------------------------------------------------------------*/
//call_togl_redraw_immediat_mode
void OpenGl_Workspace::RedrawImmediatMode ()
{
if (myRetainMode)
{
if (myTransientList)
{
MakeFrontBufCurrent();
glDisable(GL_LIGHTING);
glCallList((GLuint) myTransientList);
/* FMN necessaire pour l'affichage sur WNT */
glFlush();
MakeBackBufCurrent();
}
}
}
/*----------------------------------------------------------------------*/
//call_togl_begin_immediat_mode
Standard_Boolean OpenGl_Workspace::BeginImmediatMode (const Graphic3d_CView& ACView, const Standard_Boolean UseDepthTest, const Standard_Boolean RetainMode)
{
if (!Activate())
return Standard_False;
OpenGl_Workspace::ClearImmediatMode(ACView,1);
NamedStatus |= OPENGL_NS_IMMEDIATE;
myRetainMode = RetainMode;
MakeFrontBufCurrent();
//TsmPushAttri();
if ( myRetainMode )
{
GLuint listid = (GLuint) myTransientList;
if (!listid)
listid = glGenLists(1);
if (!listid) return Standard_False;
glNewList(listid, GL_COMPILE_AND_EXECUTE);
myTransientList = listid;
myIsTransientOpen = Standard_True;
}
if ( UseDepthTest )
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
return Standard_True;
}
/*----------------------------------------------------------------------*/
//call_togl_end_immediat_mode
void OpenGl_Workspace::EndImmediatMode ()
{
if (NamedStatus & OPENGL_NS_IMMEDIATE)
{
if (myIsTransientOpen)
{
glEndList();
myIsTransientOpen = Standard_False;
}
MakeBackBufCurrent();
// Clear immediate mode flag
NamedStatus &= ~OPENGL_NS_IMMEDIATE;
}
// Ajout CAL : pour voir quelque chose avant le prochain begin_immediat_mode
glFinish ();
myImmediateMatIsIdentity = 1;
//TsmPopAttri();
}
/*----------------------------------------------------------------------*/
//call_togl_transform
void OpenGl_Workspace::Transform (const TColStd_Array2OfReal& AMatrix, const Graphic3d_TypeOfComposition AType)
{
//call_togl_transform in OpenGl_togl_begin_immediat_mode.cxx
const Standard_Integer lr = AMatrix.LowerRow ();
const Standard_Integer lc = AMatrix.LowerCol ();
Standard_Integer i, j;
if ((AType == Graphic3d_TOC_REPLACE) || myImmediateMatIsIdentity)
{
for (i=0; i<4; i++)
for (j=0; j<4; j++)
myImmediateMat[i][j] = float (AMatrix (i+lr, j+lc));
}
else
{
float theMatrix[4][4];
for (i=0; i<4; i++)
for (j=0; j<4; j++)
theMatrix[i][j] = float (AMatrix (i+lr, j+lc));
TelMultiplymat3 (myImmediateMat, myImmediateMat, theMatrix);
}
myImmediateMatIsIdentity = 1;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (myImmediateMat[i][j] != (i == j? 1. : 0.))
{
myImmediateMatIsIdentity = 0;
return;
}
}
/*----------------------------------------------------------------------*/
//call_togl_begin_polyline
void OpenGl_Workspace::BeginPolyline ()
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
openglNumberOfPoints = 0;
glDisable(GL_LIGHTING);
glBegin(GL_LINE_STRIP);
}
}
/*----------------------------------------------------------------------*/
//call_togl_end_polyline
void OpenGl_Workspace::EndPolyline ()
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
glEnd();
}
/*----------------------------------------------------------------------*/
//call_togl_draw
void OpenGl_Workspace::Draw (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
openglNumberOfPoints++;
float x = X, y = Y, z = Z;
if (!myImmediateMatIsIdentity)
call_util_transform_pt (&x, &y, &z);
if (x > XM) XM = x;
if (y > YM) YM = y;
if (z > ZM) ZM = z;
if (x < xm) xm = x;
if (y < ym) ym = y;
if (z < zm) zm = z;
glVertex3f (x, y, z);
partial = 1;
}
}
/*----------------------------------------------------------------------*/
//call_togl_move
void OpenGl_Workspace::Move (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
if (openglNumberOfPoints != 0)
{
OpenGl_Workspace::EndPolyline();
OpenGl_Workspace::BeginPolyline();
}
OpenGl_Workspace::Draw(X,Y,Z);
}
}
/*----------------------------------------------------------------------*/
//call_togl_set_linecolor
void OpenGl_Workspace::SetLineColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
GLfloat color[3];
color[0] = R;
color[1] = G;
color[2] = B;
glColor3fv(color);
}
}
/*----------------------------------------------------------------------*/
//call_togl_set_linetype
void OpenGl_Workspace::SetLineType (const Standard_Integer Type)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
myDisplay->SetTypeOfLine((Aspect_TypeOfLine)Type);
}
}
/*----------------------------------------------------------------------*/
//call_togl_set_linewidth
void OpenGl_Workspace::SetLineWidth (const Standard_ShortReal Width)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
glLineWidth( (GLfloat)Width );
#ifdef HAVE_GL2PS
gl2psLineWidth( (GLfloat)Width );
#endif
}
}
/*----------------------------------------------------------------------*/
//call_togl_draw_structure
void OpenGl_Workspace::DrawStructure (const OpenGl_Structure *AStructure)
{
if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
{
float mat16[16];
GLint mode1;
//TsmPushAttri();
/* mise en place de la matrice de transformation du trace transient */
if (!myImmediateMatIsIdentity)
{
call_util_transpose_mat (mat16, myImmediateMat);
glGetIntegerv (GL_MATRIX_MODE, &mode1);
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glScalef (1.F, 1.F, 1.F);
glMultMatrixf (mat16);
}
// Render structure
Handle(OpenGl_Workspace) aWS(this);
AStructure->Render(aWS);
//TsmPopAttri();
if (!myImmediateMatIsIdentity)
{
glPopMatrix ();
glMatrixMode (mode1);
}
}
}
/*----------------------------------------------------------------------*/
//call_togl_set_minmax
void OpenGl_Workspace::SetMinMax (const Standard_ShortReal X1, const Standard_ShortReal Y1, const Standard_ShortReal Z1, const Standard_ShortReal X2, const Standard_ShortReal Y2, const Standard_ShortReal Z2)
{
if ((X1 > shortreallast ()) || (Y1 > shortreallast ()) || (Z1 > shortreallast ()) ||
(X2 > shortreallast ()) || (Y2 > shortreallast ()) || (Z2 > shortreallast ()) ||
(X1 < shortrealfirst ()) || (Y1 < shortrealfirst ()) || (Z1 < shortrealfirst ()) ||
(X2 < shortrealfirst ()) || (Y2 < shortrealfirst ()) || (Z2 < shortrealfirst ()))
{
XM = YM = ZM = (float ) shortreallast ();
xm = ym = zm = (float ) shortrealfirst ();
partial = 0;
}
else
{
float x1=X1,y1=Y1,z1=Z1,x2=X2,y2=Y2,z2=Z2;
if (!myImmediateMatIsIdentity)
{
call_util_transform_pt (&x1, &y1, &z1);
call_util_transform_pt (&x2, &y2, &z2);
}
if (x1 > XM) XM = x1;
if (x1 < xm) xm = x1;
if (y1 > YM) YM = y1;
if (y1 < ym) ym = y1;
if (z1 > ZM) ZM = z1;
if (z1 < zm) zm = z1;
if (x2 > XM) XM = x2;
if (x2 < xm) xm = x2;
if (y2 > YM) YM = y2;
if (y2 < ym) ym = y2;
if (z2 > ZM) ZM = z2;
if (z2 < zm) zm = z2;
if (partial != 0) partial = 1;
}
}
/*----------------------------------------------------------------------*/
/*
* Private functions
*/
/*----------------------------------------------------------------------*/
/*
Transform the point pt
*/
static void call_util_transform_pt ( float *x, float *y, float *z )
{
float tpt[4], pt[4];
pt[0] = *x, pt[1] = *y, pt[2] = *z, pt[3] = 1.0;
int i, j;
for (i = 0; i < 4; i++)
{
float sum = 0.;
for (j = 0; j < 4; j++)
sum += myImmediateMat[i][j] * pt[j];
tpt[i] = sum;
}
*x = tpt[0], *y = tpt[1], *z = tpt[2];
}
/*----------------------------------------------------------------------*/
/*
void call_util_transpose_mat (tmat, mat)
float tmat[16];
float mat[4][4];
Transpose mat and returns tmat.
*/
static void call_util_transpose_mat (float tmat[16], float mat[4][4])
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
tmat[j*4+i] = mat[i][j];
}