-// File: OpenGl_View_2.cxx
-// Created: 20 September 2011
-// Author: Sergey ZERCHANINOV
-// Copyright: OPEN CASCADE 2011
+// Created on: 2011-09-20
+// Created by: Sergey ZERCHANINOV
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
#include <stdio.h>
#include <stdlib.h>
#include <OpenGl_GlCore11.hxx>
#include <OpenGl_tgl_funcs.hxx>
-#include <OpenGl_TextureBox.hxx>
-#include <AlienImage.hxx>
-#include <Image_Image.hxx>
+#include <Graphic3d_TextureParams.hxx>
+#include <Graphic3d_Texture2Dmanual.hxx>
+#include <Image_AlienPixMap.hxx>
#include <Visual3d_Layer.hxx>
+#include <NCollection_Mat4.hxx>
+
#include <OpenGl_AspectLine.hxx>
-#include <OpenGl_Display.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_Matrix.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Trihedron.hxx>
#include <OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_PrinterContext.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
-
-#include <GL/glu.h> // gluBuild2DMipmaps()
+#include <OpenGl_ArbFBO.hxx>
#define EPSI 0.0001
-static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F };
-static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
-static const GLfloat default_sptexpo = 0.F;
-static const GLfloat default_sptcutoff = 180.F;
+namespace
+{
-extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
+ static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
+ static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
+ static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
+
+};
+
+extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
/*----------------------------------------------------------------------*/
* Fonctions privees
*/
+#if !defined(GL_ES_VERSION_2_0)
/*-----------------------------------------------------------------*/
/*
* Set des lumieres
*/
-static void bind_light(const OpenGl_Light *lptr, int *gl_lid)
+static void bindLight (const OpenGl_Light& theLight,
+ GLenum& theLightGlId,
+ Graphic3d_Vec4& theAmbientColor,
+ const Handle(OpenGl_Workspace)& theWorkspace)
{
// Only 8 lights in OpenGL...
- if (*gl_lid > GL_LIGHT7) return;
-
- // the light is a headlight ?
- GLint cur_matrix;
- if (lptr->HeadLight)
+ if (theLightGlId > GL_LIGHT7)
{
- glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
+ return;
}
- GLfloat data_amb[4];
- GLfloat data_diffu[4];
- GLfloat data_pos[4];
- GLfloat data_sptdir[3];
- GLfloat data_sptexpo;
- GLfloat data_sptcutoff;
- GLfloat data_constantattenuation;
- GLfloat data_linearattenuation;
-
- /* set la light en fonction de son type */
- switch (lptr->type)
+ if (theLight.Type == Visual3d_TOLS_AMBIENT)
{
- case TLightAmbient:
- data_amb[0] = lptr->col.rgb[0];
- data_amb[1] = lptr->col.rgb[1];
- data_amb[2] = lptr->col.rgb[2];
- data_amb[3] = 1.0;
-
- /*------------------------- Ambient ---------------------------*/
- /*
- * The GL_AMBIENT parameter refers to RGBA intensity of the ambient
- * light.
- */
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb);
- break;
-
-
- case TLightDirectional:
- data_diffu[0] = lptr->col.rgb[0];
- data_diffu[1] = lptr->col.rgb[1];
- data_diffu[2] = lptr->col.rgb[2];
- data_diffu[3] = 1.0;
-
- /*------------------------- Direction ---------------------------*/
- /* From Open GL Programming Rev 1 Guide Chapt 6 :
- Lighting The Mathematics of Lighting ( p 168 )
-
- Directional Light Source ( Infinite ) :
- if the last parameter of GL_POSITION , w , is zero, the
- corresponding light source is a Directional one.
-
- GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
- To create a realistic effect, set the GL_SPECULAR parameter
- to the same value as the GL_DIFFUSE.
- */
-
- data_pos[0] = -lptr->dir[0];
- data_pos[1] = -lptr->dir[1];
- data_pos[2] = -lptr->dir[2];
- data_pos[3] = 0.0;
-
- glLightfv(*gl_lid, GL_AMBIENT, default_amb);
- glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
- glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
-
- glLightfv(*gl_lid, GL_POSITION, data_pos);
- glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
- glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
- glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
- break;
-
-
- case TLightPositional:
- data_diffu[0] = lptr->col.rgb[0];
- data_diffu[1] = lptr->col.rgb[1];
- data_diffu[2] = lptr->col.rgb[2];
- data_diffu[3] = 1.0;
-
- /*------------------------- Position -----------------------------*/
- /* From Open GL Programming Rev 1 Guide Chapt 6 :
- Lighting The Mathematics of Lighting ( p 168 )
- Positional Light Source :
- if the last parameter of GL_POSITION , w , is nonzero,
- the corresponding light source is a Positional one.
-
- GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
-
- To create a realistic effect, set the GL_SPECULAR parameter
- to the same value as the GL_DIFFUSE.
- */
-
- data_pos[0] = lptr->pos[0];
- data_pos[1] = lptr->pos[1];
- data_pos[2] = lptr->pos[2];
- data_pos[3] = 1.0;
-
- data_constantattenuation = lptr->atten[0];
- data_linearattenuation = lptr->atten[1];
-
- glLightfv(*gl_lid, GL_AMBIENT, default_amb);
- glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
- glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
-
- glLightfv(*gl_lid, GL_POSITION, data_pos);
- glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
- glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
- glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
- glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
- glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
- glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
- break;
-
-
- case TLightSpot:
- data_diffu[0] = lptr->col.rgb[0];
- data_diffu[1] = lptr->col.rgb[1];
- data_diffu[2] = lptr->col.rgb[2];
- data_diffu[3] = 1.0;
-
- data_pos[0] = lptr->pos[0];
- data_pos[1] = lptr->pos[1];
- data_pos[2] = lptr->pos[2];
- data_pos[3] = 1.0;
-
- data_sptdir[0] = lptr->dir[0];
- data_sptdir[1] = lptr->dir[1];
- data_sptdir[2] = lptr->dir[2];
-
- data_sptexpo = ( float )lptr->shine * 128.0F;
- data_sptcutoff = ( float )(lptr->angle * 180.0F)/( float )M_PI;
-
- data_constantattenuation = lptr->atten[0];
- data_linearattenuation = lptr->atten[1];
-
- glLightfv(*gl_lid, GL_AMBIENT, default_amb);
- glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
- glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
-
- glLightfv(*gl_lid, GL_POSITION, data_pos);
- glLightfv(*gl_lid, GL_SPOT_DIRECTION, data_sptdir);
- glLightf(*gl_lid, GL_SPOT_EXPONENT, data_sptexpo);
- glLightf(*gl_lid, GL_SPOT_CUTOFF, data_sptcutoff);
- glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
- glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
- glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
- break;
+ // add RGBA intensity of the ambient light
+ theAmbientColor += theLight.Color;
+ return;
}
- if (lptr->type != TLightAmbient)
- {
- glEnable(*gl_lid);
- (*gl_lid)++;
- }
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
- /* si la light etait une headlight alors restaure la matrice precedente */
- if (lptr->HeadLight)
+ // the light is a headlight?
+ if (theLight.IsHeadlight)
{
- glPopMatrix();
- glMatrixMode(cur_matrix);
- }
-}
-/*----------------------------------------------------------------------*/
-/*
-* Prototypes
-*/
-
-static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
- float *ox, float *oy, float *oz );
-static void call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c);
-
-/*----------------------------------------------------------------------*/
-/*
-* Fonctions externes
-*/
-
-/*
-* Evaluates orientation matrix.
-*/
-/* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
-void call_func_eval_ori_matrix3 (const point3* vrp, // view reference point
- const vec3* vpn, // view plane normal
- const vec3* vup, // view up vector
- int* err_ind,
- float mout[4][4]) // OUT view orientation matrix
-{
+ aContext->WorldViewState.Push();
+ aContext->WorldViewState.SetIdentity();
- /* Translate to VRP then change the basis.
- * The old basis is: e1 = < 1, 0, 0>, e2 = < 0, 1, 0>, e3 = < 0, 0, 1>.
- * The new basis is: ("x" means cross product)
- * e3' = VPN / |VPN|
- * e1' = VUP x VPN / |VUP x VPN|
- * e2' = e3' x e1'
- * Therefore the transform from old to new is x' = TAx, where:
- *
- * | e1'x e2'x e3'x 0 | | 1 0 0 0 |
- * A = | e1'y e2'y e3'y 0 |, T = | 0 1 0 0 |
- * | e1'z e2'z e3'z 0 | | 0 0 1 0 |
- * | 0 0 0 1 | | -vrp.x -vrp.y -vrp.z 1 |
- *
- */
-
- /*
- * These ei's are really ei primes.
- */
- register float (*m)[4][4];
- point3 e1, e2, e3, e4;
- double s, v;
-
- /*
- * e1' = VUP x VPN / |VUP x VPN|, but do the division later.
- */
- e1.x = vup->delta_y * vpn->delta_z - vup->delta_z * vpn->delta_y;
- e1.y = vup->delta_z * vpn->delta_x - vup->delta_x * vpn->delta_z;
- e1.z = vup->delta_x * vpn->delta_y - vup->delta_y * vpn->delta_x;
- s = sqrt( e1.x * e1.x + e1.y * e1.y + e1.z * e1.z);
- e3.x = vpn->delta_x;
- e3.y = vpn->delta_y;
- e3.z = vpn->delta_z;
- v = sqrt( e3.x * e3.x + e3.y * e3.y + e3.z * e3.z);
- /*
- * Check for vup and vpn colinear (zero dot product).
- */
- if ((s > -EPSI) && (s < EPSI))
- *err_ind = 2;
- else
- /*
- * Check for a normal vector not null.
- */
- if ((v > -EPSI) && (v < EPSI))
- *err_ind = 3;
- else {
- /*
- * Normalize e1
- */
- e1.x /= ( float )s;
- e1.y /= ( float )s;
- e1.z /= ( float )s;
- /*
- * e3 = VPN / |VPN|
- */
- e3.x /= ( float )v;
- e3.y /= ( float )v;
- e3.z /= ( float )v;
- /*
- * e2 = e3 x e1
- */
- e2.x = e3.y * e1.z - e3.z * e1.y;
- e2.y = e3.z * e1.x - e3.x * e1.z;
- e2.z = e3.x * e1.y - e3.y * e1.x;
- /*
- * Add the translation
- */
- e4.x = -( e1.x * vrp->x + e1.y * vrp->y + e1.z * vrp->z);
- e4.y = -( e2.x * vrp->x + e2.y * vrp->y + e2.z * vrp->z);
- e4.z = -( e3.x * vrp->x + e3.y * vrp->y + e3.z * vrp->z);
- /*
- * Homogeneous entries
- *
- * | e1.x e2.x e3.x 0.0 | | 1 0 0 0 |
- * | e1.y e2.y e3.y 0.0 | * | 0 1 0 0 |
- * | e1.z e2.z e3.z 0.0 | | a b 1 c |
- * | e4.x e4.y e4.z 1.0 | | 0 0 0 1 |
- */
-
- m = (float (*)[4][4])mout;
-
- (*m)[0][0] = e1.x;
- (*m)[0][1] = e2.x;
- (*m)[0][2] = e3.x;
- (*m)[0][3] = ( float )0.0;
-
- (*m)[1][0] = e1.y;
- (*m)[1][1] = e2.y;
- (*m)[1][2] = e3.y;
- (*m)[1][3] = ( float )0.0;
-
- (*m)[2][0] = e1.z;
- (*m)[2][1] = e2.z;
- (*m)[2][2] = e3.z;
- (*m)[2][3] = ( float )0.0;
-
- (*m)[3][0] = e4.x;
- (*m)[3][1] = e4.y;
- (*m)[3][2] = e4.z;
- (*m)[3][3] = ( float )1.0;
-
- *err_ind = 0;
- }
-}
+ aContext->ApplyWorldViewMatrix();
+ }
-/*----------------------------------------------------------------------*/
-/*
-* Evaluates mapping matrix.
-*/
-/* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
-void call_func_eval_map_matrix3(
- view_map3 *Map,
- int *err_ind,
- matrix3 mat)
-{
- int i, j;
- matrix3 Tpar, Spar;
- matrix3 Tper, Sper;
- matrix3 Shear;
- matrix3 Scale;
- matrix3 Tprp;
- matrix3 aux_mat1, aux_mat2, aux_mat3;
- point3 Prp;
-
- *err_ind = 0;
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- Spar[i][j] = Sper[i][j] = aux_mat1[i][j] = aux_mat2[i][j] =
- aux_mat3[i][j] = Tper[i][j] = Tpar[i][j] = Tprp[i][j] =
- Shear[i][j] = Scale[i][j] = ( float )(i == j);
-
- Prp.x = Map->proj_ref_point.x;
- Prp.y = Map->proj_ref_point.y;
- Prp.z = Map->proj_ref_point.z;
-
- /*
- * Type Parallele
- */
- if (Map->proj_type == TYPE_PARAL)
+ // setup light type
+ switch (theLight.Type)
{
- float umid, vmid;
- point3 temp;
-
-#ifdef FMN
- float cx, cy, gx, gy, xsf, ysf, zsf;
- float fpd, bpd;
- float dopx, dopy, dopz;
- matrix3 tmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
- matrix3 smat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
- matrix3 shmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
- matrix3 tshmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
- { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
-
- /* centers */
- cx = Map->win.x_min + Map->win.x_max, cx /= ( float )2.0;
- cy = Map->win.y_min + Map->win.y_max, cy /= ( float )2.0;
-
- gx = 2.0/ (Map->win.x_max - Map->win.x_min);
- gy = 2.0/ (Map->win.y_max - Map->win.y_min);
-
- tmat[0][3] = -cx;
- tmat[1][3] = -cy;
- tmat[2][3] = (Map->front_plane + Map->back_plane)/(Map->front_plane - Map->back_plane);
-
- smat[0][0] = gx;
- smat[1][1] = gy;
- smat[2][2] = -2./(Map->front_plane - Map->back_plane);
-
- /* scale factors */
- dopx = cx - Prp.x;
- dopy = cy - Prp.y;
- dopz = - Prp.z;
-
- /* map matrix */
- shmat[0][2] = -(dopx/dopz);
- shmat[1][2] = -(dopy/dopz);
-
- /* multiply to obtain mapping matrix */
- call_util_mat_mul( tmat, shmat, tshmat );
- call_util_mat_mul( smat, tshmat, mat );
-
- return;
-#endif
-
- /* CAL */
- Map->proj_vp.z_min = ( float )0.0;
- Map->proj_vp.z_max = ( float )1.0;
- /* CAL */
-
- /* Shear matrix calculation */
- umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0;
- vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0;
- if(Prp.z == Map->view_plane){
- /* Projection reference point is on the view plane */
- *err_ind = 1;
- return;
+ case Visual3d_TOLS_DIRECTIONAL:
+ {
+ // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
+ const OpenGl_Vec4 anInfDir = -theLight.Direction;
+
+ // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
+ glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
+ glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
+ glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
+ glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
+ glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
+ break;
}
- Shear[2][0] = ( float )(-1.0) * ((Prp.x-umid)/(Prp.z-Map->view_plane));
- Shear[2][1] = ( float )(-1.0) * ((Prp.y-vmid)/(Prp.z-Map->view_plane));
-
- /*
- * Calculate the lower left coordinate of the view plane
- * after the Shearing Transformation.
- */
- call_util_apply_trans2(Map->win.x_min, Map->win.y_min,
- Map->view_plane, Shear, &(temp.x), &(temp.y), &(temp.z));
-
- /* Translate the back plane to the origin */
- Tpar[3][0] = ( float )(-1.0) * temp.x;
- Tpar[3][1] = ( float )(-1.0) * temp.y;
- Tpar[3][2] = ( float )(-1.0) * Map->back_plane;
-
- call_util_mat_mul(Shear, Tpar, aux_mat1);
-
- /* Calculation of Scaling transformation */
- Spar[0][0] = ( float )1.0 / (Map->win.x_max - Map->win.x_min);
- Spar[1][1] = ( float )1.0 / (Map->win.y_max - Map->win.y_min);
- Spar[2][2] = ( float )1.0 / (Map->front_plane - Map->back_plane );
- call_util_mat_mul (aux_mat1, Spar, aux_mat2);
- /* Atlast we transformed view volume to NPC */
-
- /* Translate and scale the view plane to projection view port */
- if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
- Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
- Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
- Map->proj_vp.x_min > Map->proj_vp.x_max ||
- Map->proj_vp.y_min > Map->proj_vp.y_max ||
- Map->proj_vp.z_min > Map->proj_vp.z_max){
- *err_ind = 1;
- return;
- }
- for(i=0; i<4; i++)
- for(j=0; j<4; j++)
- aux_mat1[i][j] = (float)(i==j);
- aux_mat1[0][0] = Map->proj_vp.x_max-Map->proj_vp.x_min;
- aux_mat1[1][1] = Map->proj_vp.y_max-Map->proj_vp.y_min;
- aux_mat1[2][2] = Map->proj_vp.z_max-Map->proj_vp.z_min;
- aux_mat1[3][0] = Map->proj_vp.x_min;
- aux_mat1[3][1] = Map->proj_vp.y_min;
- aux_mat1[3][2] = Map->proj_vp.z_min;
- call_util_mat_mul (aux_mat2, aux_mat1, mat);
-
- return;
- }
-
- /*
- * Type Perspective
- */
- else if (Map->proj_type == TYPE_PERSPECT)
- {
- float umid, vmid;
- float B, F, V;
- float Zvmin;
-
- /* CAL */
- Map->proj_vp.z_min = ( float )0.0;
- Map->proj_vp.z_max = ( float )1.0;
- /* CAL */
-
- B = Map->back_plane;
- F = Map->front_plane;
- V = Map->view_plane;
-
- if(Prp.z == Map->view_plane){
- /* Centre of Projection is on the view plane */
- *err_ind = 1;
- return;
+ case Visual3d_TOLS_POSITIONAL:
+ {
+ // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
+ glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
+ glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
+ glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
+ glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
+ glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
+ glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
+ glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
+ glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
+ break;
}
- if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
- Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
- Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
- Map->proj_vp.x_min > Map->proj_vp.x_max ||
- Map->proj_vp.y_min > Map->proj_vp.y_max ||
- Map->proj_vp.z_min > Map->proj_vp.z_max ||
- F < B){
- *err_ind = 1;
- return;
- }
-
- /* This is the transformation to move VRC to Center Of Projection */
- Tprp[3][0] = ( float )(-1.0)*Prp.x;
- Tprp[3][1] = ( float )(-1.0)*Prp.y;
- Tprp[3][2] = ( float )(-1.0)*Prp.z;
-
- /* Calculation of Shear matrix */
- umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0-Prp.x;
- vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0-Prp.y;
- Shear[2][0] = ( float )(-1.0)*umid/(Map->view_plane-Prp.z);
- Shear[2][1] = ( float )(-1.0)*vmid/(Map->view_plane-Prp.z);
- call_util_mat_mul(Tprp, Shear, aux_mat3);
-
- /* Scale the view volume to canonical view volume
- * Centre of projection at origin.
- * 0 <= N <= -1, -0.5 <= U <= 0.5, -0.5 <= V <= 0.5
- */
- Scale[0][0] = (( float )(-1.0)*Prp.z+V)/
- ((Map->win.x_max-Map->win.x_min)*(( float )(-1.0)*Prp.z+B));
- Scale[1][1] = (( float )(-1.0)*Prp.z+V)/
- ((Map->win.y_max-Map->win.y_min)*(( float )(-1.0)*Prp.z+B));
- Scale[2][2] = ( float )(-1.0) / (( float )(-1.0)*Prp.z+B);
-
- call_util_mat_mul(aux_mat3, Scale, aux_mat1);
-
- /*
- * Transform the Perspective view volume into
- * Parallel view volume.
- * Lower left coordinate: (-0.5,-0.5, -1)
- * Upper right coordinate: (0.5, 0.5, 1.0)
- */
- Zvmin = ( float )(-1.0*(-1.0*Prp.z+F)/(-1.0*Prp.z+B));
- aux_mat2[2][2] = ( float )1.0/(( float )1.0+Zvmin);
- aux_mat2[2][3] = ( float )(-1.0);
- aux_mat2[3][2] = ( float )(-1.0)*Zvmin*aux_mat2[2][2];
- aux_mat2[3][3] = ( float )0.0;
- call_util_mat_mul(aux_mat1, aux_mat2, Shear);
-
- for(i=0; i<4; i++)
- for(j=0; j<4; j++)
- aux_mat1[i][j] = aux_mat2[i][j] = (float)(i==j);
-
- /* Translate and scale the view plane to projection view port */
- aux_mat2[0][0] = (Map->proj_vp.x_max-Map->proj_vp.x_min);
- aux_mat2[1][1] = (Map->proj_vp.y_max-Map->proj_vp.y_min);
- aux_mat2[2][2] = (Map->proj_vp.z_max-Map->proj_vp.z_min);
- aux_mat2[3][0] = aux_mat2[0][0]/( float )2.0+Map->proj_vp.x_min;
- aux_mat2[3][1] = aux_mat2[1][1]/( float )2.0+Map->proj_vp.y_min;
- aux_mat2[3][2] = aux_mat2[2][2]+Map->proj_vp.z_min;
- call_util_mat_mul (Shear, aux_mat2, mat);
+ case Visual3d_TOLS_SPOT:
+ {
+ glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
+ glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
+ glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
+ glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
+ glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
+ glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
+ glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
+ glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
+ glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
+ break;
+ }
+ }
- return;
+ // restore matrix in case of headlight
+ if (theLight.IsHeadlight)
+ {
+ aContext->WorldViewState.Pop();
}
- else
- *err_ind = 1;
+
+ glEnable (theLightGlId++);
}
+#endif
/*----------------------------------------------------------------------*/
-static void
-call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
- float *ox, float *oy, float *oz )
+void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
{
- float temp;
- *ox = ix*mat[0][0]+iy*mat[1][0]+iz*mat[2][0]+mat[3][0];
- *oy = ix*mat[0][1]+iy*mat[1][1]+iz*mat[2][1]+mat[3][1];
- *oz = ix*mat[0][2]+iy*mat[1][2]+iz*mat[2][2]+mat[3][2];
- temp = ix * mat[0][3]+iy * mat[1][3]+iz * mat[2][3]+mat[3][3];
- *ox /= temp;
- *oy /= temp;
- *oz /= temp;
-}
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
-/*----------------------------------------------------------------------*/
+ if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
+ || (!myBgTextureArray->IsDefined() // no texture
+ && !myBgGradientArray->IsDefined())) // no gradient
+ {
+ return;
+ }
-static void
-call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
-{
- int i, j, k;
+ aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
+
+ aCtx->WorldViewState.Push();
+ aCtx->ProjectionState.Push();
+ aCtx->WorldViewState.SetIdentity();
+ aCtx->ProjectionState.SetIdentity();
+ aCtx->ApplyProjectionMatrix();
+ aCtx->ApplyWorldViewMatrix();
+
+ // Drawing background gradient if:
+ // - gradient fill type is not Aspect_GFM_NONE and
+ // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
+ if (myBgGradientArray->IsDefined()
+ && (!myTextureParams->DoTextureMap()
+ || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
+ || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
+ {
+ #if !defined(GL_ES_VERSION_2_0)
+ GLint aShadingModelOld = GL_SMOOTH;
+ if (aCtx->core11 != NULL)
+ {
+ aCtx->core11fwd->glDisable (GL_LIGHTING);
+ aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
+ aCtx->core11->glShadeModel (GL_SMOOTH);
+ }
+ #endif
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- for (mat_c[i][j] = ( float )0.0,k=0; k<4; k++)
- mat_c[i][j] += mat_a[i][k] * mat_b[k][j];
-}
+ if (myBgGradientArray->IsDataChanged())
+ {
+ myBgGradientArray->Init (theWorkspace);
+ }
-/*----------------------------------------------------------------------*/
+ myBgGradientArray->Render (theWorkspace);
-//call_func_redraw_all_structs_proc
-void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
- const Graphic3d_CView& ACView,
- const Aspect_CLayer2d& ACUnderLayer,
- const Aspect_CLayer2d& ACOverLayer)
-{
- // Reset FLIST status after modification of myBackfacing
- if (myResetFLIST)
- {
- AWorkspace->NamedStatus &= ~OPENGL_NS_FLIST;
- myResetFLIST = Standard_False;
+ #if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->core11 != NULL)
+ {
+ aCtx->core11->glShadeModel (aShadingModelOld);
+ }
+ #endif
}
- // Store and disable current clipping planes
- GLint maxplanes;
- glGetIntegerv(GL_MAX_CLIP_PLANES, &maxplanes);
- const GLenum lastid = GL_CLIP_PLANE0 + maxplanes;
- OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[maxplanes];
- OPENGL_CLIP_PLANE *ptrPlane = oldPlanes;
- GLenum planeid = GL_CLIP_PLANE0;
- for ( ; planeid < lastid; planeid++, ptrPlane++ )
+ // Drawing background image if it is defined
+ // (texture is defined and fill type is not Aspect_FM_NONE)
+ if (myBgTextureArray->IsDefined()
+ && myTextureParams->DoTextureMap())
{
- glGetClipPlane( planeid, ptrPlane->Equation );
- if ( ptrPlane->isEnabled )
+ aCtx->core11fwd->glDisable (GL_BLEND);
+
+ const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
+
+ if (myBgTextureArray->IsDataChanged()
+ || myBgTextureArray->IsViewSizeChanged (theWorkspace))
{
- glDisable( planeid );
- ptrPlane->isEnabled = GL_TRUE;
+ myBgTextureArray->Init (theWorkspace);
}
- else
- ptrPlane->isEnabled = GL_FALSE;
+
+ myBgTextureArray->Render (theWorkspace);
+
+ // restore aspects
+ theWorkspace->SetAspectFace (anOldAspectFace);
}
- /////////////////////////////////////////////////////////////////////////////
- // Step 1: Prepare for redraw
+ aCtx->WorldViewState.Pop();
+ aCtx->ProjectionState.Pop();
+ aCtx->ApplyProjectionMatrix();
- // Render background
- if ( (AWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
- ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
+ if (theWorkspace->UseZBuffer())
{
- const Standard_Integer aViewWidth = AWorkspace->Width();
- const Standard_Integer aViewHeight = AWorkspace->Height();
-
- glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
-
- glMatrixMode( GL_PROJECTION );
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode( GL_MODELVIEW );
- glPushMatrix();
- glLoadIdentity();
-
- if ( glIsEnabled( GL_DEPTH_TEST ) )
- glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
-
- // drawing bg gradient if:
- // - gradient fill type is not Aspect_GFM_NONE and
- // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
- if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
- ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
- myBgTexture.Style == Aspect_FM_NONE ) )
- {
- Tfloat* corner1 = 0;/* -1,-1*/
- Tfloat* corner2 = 0;/* 1,-1*/
- Tfloat* corner3 = 0;/* 1, 1*/
- Tfloat* corner4 = 0;/* -1, 1*/
- Tfloat dcorner1[3];
- Tfloat dcorner2[3];
-
- switch( myBgGradient.type )
- {
- case Aspect_GFM_HOR:
- corner1 = myBgGradient.color1.rgb;
- corner2 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color2.rgb;
- corner4 = myBgGradient.color1.rgb;
- break;
- case Aspect_GFM_VER:
- corner1 = myBgGradient.color2.rgb;
- corner2 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color1.rgb;
- corner4 = myBgGradient.color1.rgb;
- break;
- case Aspect_GFM_DIAG1:
- corner2 = myBgGradient.color2.rgb;
- corner4 = myBgGradient.color1.rgb;
- dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
- dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
- dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
- corner1 = dcorner1;
- corner3 = dcorner2;
- break;
- case Aspect_GFM_DIAG2:
- corner1 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color1.rgb;
- dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
- dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
- dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
- corner2 = dcorner1;
- corner4 = dcorner2;
- break;
- case Aspect_GFM_CORNER1:
- corner1 = myBgGradient.color2.rgb;
- corner2 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color2.rgb;
- corner4 = myBgGradient.color1.rgb;
- break;
- case Aspect_GFM_CORNER2:
- corner1 = myBgGradient.color2.rgb;
- corner2 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color1.rgb;
- corner4 = myBgGradient.color2.rgb;
- break;
- case Aspect_GFM_CORNER3:
- corner1 = myBgGradient.color2.rgb;
- corner2 = myBgGradient.color1.rgb;
- corner3 = myBgGradient.color2.rgb;
- corner4 = myBgGradient.color2.rgb;
- break;
- case Aspect_GFM_CORNER4:
- corner1 = myBgGradient.color1.rgb;
- corner2 = myBgGradient.color2.rgb;
- corner3 = myBgGradient.color2.rgb;
- corner4 = myBgGradient.color2.rgb;
- break;
- default:
- //printf("gradient background type not right\n");
- break;
- }
+ aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
+ }
+}
- // Save GL parameters
- glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
+/*----------------------------------------------------------------------*/
- GLint curSM;
- glGetIntegerv( GL_SHADE_MODEL, &curSM );
- if ( curSM != GL_SMOOTH )
- glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
+//call_func_redraw_all_structs_proc
+void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
+ const Handle(OpenGl_Workspace)& theWorkspace,
+ const Graphic3d_CView& theCView,
+ const Aspect_CLayer2d& theCUnderLayer,
+ const Aspect_CLayer2d& theCOverLayer,
+ const Standard_Boolean theToDrawImmediate)
+{
+ // ==================================
+ // Step 1: Prepare for redraw
+ // ==================================
- glBegin(GL_TRIANGLE_FAN);
- if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
- {
- glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
- glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
- glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
- glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
- }
- else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
- {
- glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
- glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
- glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
- glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
- }
- glEnd();
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
- // Restore GL parameters
- if ( curSM != GL_SMOOTH )
- glShadeModel( curSM );
- }
- // drawing bg image if:
- // - it is defined and
- // - fill type is not Aspect_FM_NONE
- if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
+#if !defined(GL_ES_VERSION_2_0)
+ // store and disable current clipping planes
+ const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
+ NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
+ if (aContext->core11 != NULL)
+ {
+ for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
{
- GLfloat texX_range = 1.F; // texture <s> coordinate
- GLfloat texY_range = 1.F; // texture <t> coordinate
-
- // Set up for stretching or tiling
- GLfloat x_offset, y_offset;
- if ( myBgTexture.Style == Aspect_FM_CENTERED )
+ OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
+ aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
+ if (aPlane.isEnabled)
{
- x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
- y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
+ aContext->core11fwd->glDisable (aClipPlaneId);
+ aPlane.isEnabled = GL_TRUE;
}
else
{
- x_offset = 1.F;
- y_offset = 1.F;
- if ( myBgTexture.Style == Aspect_FM_TILED )
- {
- texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
- texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
- }
+ aPlane.isEnabled = GL_FALSE;
}
+ }
+ }
+#endif
- glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
- glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
+ // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
+ Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
+ Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
+ if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
+ {
+ isProjectionMatUpdateNeeded = Standard_True;
+ myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
+ }
+ if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
+ {
+ isOrientationMatUpdateNeeded = Standard_True;
+ myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
+ }
- glDisable( GL_BLEND ); //push GL_ENABLE_BIT
+ if (isProjectionMatUpdateNeeded
+ || isOrientationMatUpdateNeeded)
+ {
+ myBVHSelector.SetViewVolume (myCamera);
+ }
- glColor3fv( AWorkspace->BackgroundColor().rgb );
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
+ const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
+ const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
+ if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
+ {
+ aManager->UpdateLightSourceStateTo (&myLights);
+ myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
+ }
- glBegin( GL_QUADS );
- glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -y_offset );
- glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -y_offset );
- glTexCoord2f(texX_range, texY_range); glVertex2f( x_offset, y_offset );
- glTexCoord2f(0.F, texY_range); glVertex2f( -x_offset, y_offset );
- glEnd();
- }
+ if (myProjectionState != myCamera->ProjectionState()
+ || !isSameView)
+ {
+ myProjectionState = myCamera->ProjectionState();
+ aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
+ aContext->ApplyProjectionMatrix();
+ }
- glPopMatrix();
- glMatrixMode( GL_PROJECTION );
- glPopMatrix();
- glMatrixMode( GL_MODELVIEW );
+ if (myModelViewState != myCamera->ModelViewState()
+ || !isSameView)
+ {
+ myModelViewState = myCamera->ModelViewState();
+ aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
+ aContext->ApplyWorldViewMatrix();
+ }
- glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
+ if (aManager->ModelWorldState().Index() == 0)
+ {
+ aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
+ }
- if ( AWorkspace->UseZBuffer() )
- glEnable( GL_DEPTH_TEST );
+ // ====================================
+ // Step 2: Redraw background
+ // ====================================
- /* GL_DITHER on/off pour le trace */
- if (AWorkspace->Dither())
- glEnable (GL_DITHER);
- else
- glDisable (GL_DITHER);
+ // Render background
+ if (!theToDrawImmediate)
+ {
+ DrawBackground (theWorkspace);
}
+#if !defined(GL_ES_VERSION_2_0)
// Switch off lighting by default
- glDisable(GL_LIGHTING);
+ if (aContext->core11 != NULL)
+ {
+ glDisable(GL_LIGHTING);
+ }
+#endif
- /////////////////////////////////////////////////////////////////////////////
- // Step 2: Draw underlayer
- RedrawLayer2d(AWorkspace, ACView, ACUnderLayer);
+ // =================================
+ // Step 3: Draw underlayer
+ // =================================
+ if (!theToDrawImmediate)
+ {
+ RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
+ }
- /////////////////////////////////////////////////////////////////////////////
- // Step 3: Redraw main plane
+ // =================================
+ // Step 4: Redraw main plane
+ // =================================
// Setup face culling
GLboolean isCullFace = GL_FALSE;
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
}
- else
+ else
glDisable( GL_CULL_FACE );
}
- //TsmPushAttri(); /* save previous graphics context */
-
- // if the view is scaled normal vectors are scaled to unit length for correct displaying of shaded objects
- if(myExtra.scaleFactors[0] != 1.F ||
- myExtra.scaleFactors[1] != 1.F ||
- myExtra.scaleFactors[2] != 1.F)
- glEnable(GL_NORMALIZE);
- else if(glIsEnabled(GL_NORMALIZE))
- glDisable(GL_NORMALIZE);
-
- // Apply View Projection
- // This routine activates the Projection matrix for a view.
-
- glMatrixMode( GL_PROJECTION );
-
-#ifdef WNT
- // add printing scale/tiling transformation
- OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext(AWorkspace->GetGContext());
-
- if (aPrinterContext)
+#if !defined(GL_ES_VERSION_2_0)
+ // if the view is scaled normal vectors are scaled to unit
+ // length for correct displaying of shaded objects
+ const gp_Pnt anAxialScale = myCamera->AxialScale();
+ if (anAxialScale.X() != 1.F ||
+ anAxialScale.Y() != 1.F ||
+ anAxialScale.Z() != 1.F)
{
- GLfloat aProjMatrix[16];
- aPrinterContext->GetProjTransformation(aProjMatrix);
- glLoadMatrixf((GLfloat*) aProjMatrix);
+ aContext->SetGlNormalizeEnabled (Standard_True);
}
else
-#endif
- glLoadIdentity();
-
- glMultMatrixf( (const GLfloat *) myMappingMatrix );
-
- // Add translation necessary for the environnement mapping
- if (mySurfaceDetail != Visual3d_TOD_NONE)
{
- // OCC280: FitAll work incorrect for perspective view if the SurfaceDetail mode is V3d_TEX_ENVIRONMENT or V3d_TEX_ALL
- // const GLfloat dep = vptr->vrep.extra.map.fpd * 0.5F;
- const GLfloat dep = (myExtra.map.fpd + myExtra.map.bpd) * 0.5F;
- glTranslatef(-dep*myExtra.vpn[0],-dep*myExtra.vpn[1],-dep*myExtra.vpn[2]);
+ aContext->SetGlNormalizeEnabled (Standard_False);
}
- // Apply matrix
- AWorkspace->SetViewMatrix((const OpenGl_Matrix *)myOrientationMatrix);
-
-/*
-While drawing after a clipplane has been defined and enabled, each vertex
-is transformed to eye-coordinates, where it is dotted with the transformed
-clipping plane equation. Eye-coordinate vertexes whose dot product with
-the transformed clipping plane equation is positive or zero are in, and
-require no clipping. Those eye-coordinate vertexes whose dot product is
-negative are clipped. Because clipplane clipping is done in eye-
-coordinates, changes to the projection matrix have no effect on its
-operation.
-
-A point and a normal are converted to a plane equation in the following manner:
-
-point = [Px,Py,Pz]
-
-normal = |Nx|
-|Ny|
-|Nz|
-
-plane equation = |A|
-|B|
-|C|
-|D|
-A = Nx
-B = Ny
-C = Nz
-D = -[Px,Py,Pz] dot |Nx|
-|Ny|
-|Nz|
-
-*/
-
- glPushAttrib( GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT );
-
// Apply Fog
- if ( myFog.IsOn )
+ if (myFog.IsOn
+ && aContext->core11 != NULL)
{
- const GLfloat ramp = myExtra.map.fpd - myExtra.map.bpd;
- const GLfloat fog_start = myFog.Front * ramp - myExtra.map.fpd;
- const GLfloat fog_end = myFog.Back * ramp - myExtra.map.fpd;
+ Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
+ if (myCamera->ZFar() < aFogFrontConverted)
+ {
+ aFogFrontConverted = myCamera->ZFar();
+ myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
+ }
+
+ Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
+ if (myCamera->ZFar() < aFogFrontConverted)
+ {
+ aFogBackConverted = myCamera->ZFar();
+ myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
+ }
+
+ if (aFogFrontConverted > aFogBackConverted)
+ {
+ myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
+ myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
+ }
glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogf(GL_FOG_START, fog_start);
- glFogf(GL_FOG_END, fog_end);
+ glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
+ glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
glEnable(GL_FOG);
}
- else
- glDisable(GL_FOG);
+ else if (aContext->core11 != NULL)
+ {
+ glDisable (GL_FOG);
+ }
- // Apply Lights
+ // Apply InteriorShadingMethod
+ if (aContext->core11 != NULL)
{
- int i;
+ aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
+ || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
+ }
+#endif
- // Switch off all lights
- for (i = GL_LIGHT0; i <= GL_LIGHT7; i++)
- glDisable(i);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
+ aManager->SetShadingModel (myShadingModel);
- /* set les lights */
- int gl_lid = GL_LIGHT0;
- OpenGl_ListOfLight::Iterator itl(myLights);
- for (; itl.More(); itl.Next())
- {
- const OpenGl_Light &alight = itl.Value();
- bind_light(&alight, &gl_lid);
- }
+ // Apply AntiAliasing
+ if (myAntiAliasing)
+ theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
+ else
+ theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
- if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING);
+ if (!aManager->IsEmpty())
+ {
+ aManager->UpdateClippingState();
}
- // Apply InteriorShadingMethod
- glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
-
- // Apply clipping planes
+ // Redraw 3d scene
+ if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
+ {
+ // single-pass monographic rendering
+ // redraw scene with normal orientation and projection
+ RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
+ }
+ else
{
- // Define starting plane id
- planeid = GL_CLIP_PLANE0;
+ // two stereographic passes
- GLdouble equation[4];
+ // safely switch to left Eye buffer
+ aContext->SetDrawBufferLeft();
- if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
- {
- // Apply front and back clipping planes
- GLfloat mat[4][4];
- glMatrixMode( GL_MODELVIEW );
- glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
- glLoadIdentity();
+ aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
+ aContext->ApplyProjectionMatrix();
- const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
+ // redraw left Eye
+ RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
- if ( myZClip.Back.IsOn )
- {
- const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
- equation[0] = 0.0; /* Nx */
- equation[1] = 0.0; /* Ny */
- equation[2] = 1.0; /* Nz */
- equation[3] = -back; /* P dot N */
- glClipPlane( planeid, equation );
- glEnable( planeid );
- planeid++;
- }
+ // reset depth buffer of first rendering pass
+ if (theWorkspace->UseDepthTest())
+ {
+ glClear (GL_DEPTH_BUFFER_BIT);
+ }
+ // safely switch to right Eye buffer
+ aContext->SetDrawBufferRight();
- if ( myZClip.Front.IsOn )
- {
- const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
- equation[0] = 0.0; /* Nx */
- equation[1] = 0.0; /* Ny */
- equation[2] = -1.0; /* Nz */
- equation[3] = front; /* P dot N */
- glClipPlane( planeid, equation );
- glEnable( planeid );
- planeid++;
- }
+ aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
+ aContext->ApplyProjectionMatrix();
- glLoadMatrixf( (GLfloat *) mat );
- }
+ // redraw right Eye
+ RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
- // Apply user clipping planes
- NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
- for ( ; planeIter.More(); planeIter.Next() )
- {
- glClipPlane( planeid, planeIter.Value().equation );
- glEnable( planeid );
- planeid++;
- }
+ // switch back to monographic rendering
+ aContext->SetDrawBufferMono();
}
- // Apply AntiAliasing
- {
- if (myAntiAliasing)
- AWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
- else
- AWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
- }
+ // ===============================
+ // Step 5: Trihedron
+ // ===============================
+
+ // Resetting GL parameters according to the default aspects
+ // in order to synchronize GL state with the graphic driver state
+ // before drawing auxiliary stuff (trihedrons, overlayer)
+ // and invoking optional callbacks
+ theWorkspace->ResetAppliedAspect();
- Standard_Boolean isAnimationListOpen = Standard_False;
+ aContext->ChangeClipping().RemoveAll();
- // Request for update of animation mode?
- if ( (AWorkspace->NamedStatus & OPENGL_NS_UPDATEAM) != 0 )
+ if (!aManager->IsEmpty())
{
- // Request to rebuild display list
- myAnimationListReady = Standard_False;
- // Reset request for update of animation mode
- AWorkspace->NamedStatus &= ~OPENGL_NS_UPDATEAM;
+ aManager->ResetMaterialStates();
+ aManager->RevertClippingState();
+
+ // We need to disable (unbind) all shaders programs to ensure
+ // that all objects without specified aspect will be drawn
+ // correctly (such as background)
+ aContext->BindProgram (NULL);
}
- // Is in animation mode?
- if ( AWorkspace->NamedStatus & OPENGL_NS_ANIMATION )
+ // Render trihedron
+ if (!theToDrawImmediate)
{
- // Is the animation list ready?
- if (myAnimationListReady)
- {
- // Execute the animation list
- glCallList(myAnimationListIndex);
- }
- else
+ RedrawTrihedron (theWorkspace);
+
+ // Restore face culling
+ if ( myBackfacing )
{
- // Update the animation list
- if ( AWorkspace->NamedStatus & OPENGL_NS_FLIST )
+ if ( isCullFace )
{
- if (myAnimationListIndex == 0)
- myAnimationListIndex = glGenLists(1);
-
- if (myAnimationListIndex != 0)
- {
- glNewList(myAnimationListIndex, GL_COMPILE_AND_EXECUTE);
- isAnimationListOpen = Standard_True;
- }
+ glEnable ( GL_CULL_FACE );
+ glCullFace ( GL_BACK );
}
else
- AWorkspace->NamedStatus |= OPENGL_NS_FLIST;
+ glDisable ( GL_CULL_FACE );
}
}
- else
- myAnimationListReady = Standard_False;
- if (!myAnimationListReady)
+ // ===============================
+ // Step 6: Redraw overlay
+ // ===============================
+ if (!theToDrawImmediate)
{
- // Clear status bitfields
- AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
-
- // Added PCT for handling of textures
- switch (mySurfaceDetail)
- {
- case Visual3d_TOD_NONE:
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- DisableTexture();
- // Render the view
- RenderStructs(AWorkspace);
- break;
-
- case Visual3d_TOD_ENVIRONMENT:
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- SetCurrentTexture(myTextureEnv);
- EnableTexture();
- // Render the view
- RenderStructs(AWorkspace);
- DisableTexture();
- break;
+ const int aMode = 0;
+ theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
- case Visual3d_TOD_ALL:
- // First pass
- AWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
- // Render the view
- RenderStructs(AWorkspace);
- DisableTexture();
-
- // Second pass
- if (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
- {
- AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
- SetCurrentTexture(myTextureEnv);
- EnableTexture();
-
- /* sauvegarde de quelques parametres OpenGL */
- GLint blend_dst, blend_src;
- GLint zbuff_f;
- GLboolean zbuff_w;
- glGetBooleanv(GL_DEPTH_WRITEMASK, &zbuff_w);
- glGetIntegerv(GL_DEPTH_FUNC, &zbuff_f);
- glGetIntegerv(GL_BLEND_DST, &blend_dst);
- glGetIntegerv(GL_BLEND_SRC, &blend_src);
- GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
- GLboolean blend_state = glIsEnabled(GL_BLEND);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glDepthFunc(GL_EQUAL);
- glDepthMask(GL_FALSE);
- glEnable(GL_DEPTH_TEST);
-
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
-
- // Render the view
- RenderStructs(AWorkspace);
- DisableTexture();
-
- /* restauration des parametres OpenGL */
- glBlendFunc(blend_src, blend_dst);
- if (!blend_state) glDisable(GL_BLEND);
-
- glDepthFunc(zbuff_f);
- glDepthMask(zbuff_w);
- if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
- }
- break;
- }
+ RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
- if (isAnimationListOpen)
- {
- glEndList();
- myAnimationListReady = Standard_True;
- }
+ theWorkspace->DisplayCallback (theCView, aMode);
}
- /* restore previous graphics context; before update lights */
- //TsmPopAttri();
-
- // Disable current clipping planes
- for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
- glDisable( planeid );
+ // ===============================
+ // Step 7: Finalize
+ // ===============================
- /* affichage de Triedre Non Zoomable de la vue s'il existe */
- if (!myTrihedron.IsNull())
- myTrihedron->Render(AWorkspace);
- if (!myGraduatedTrihedron.IsNull())
- myGraduatedTrihedron->Render(AWorkspace);
-
- glPopAttrib(); // GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT
-
- // Restore face culling
- if ( myBackfacing )
+#if !defined(GL_ES_VERSION_2_0)
+ // restore clipping planes
+ if (aContext->core11 != NULL)
{
- if ( isCullFace )
+ for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
{
- glEnable ( GL_CULL_FACE );
- glCullFace ( GL_BACK );
+ const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
+ aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
+ if (aPlane.isEnabled)
+ aContext->core11fwd->glEnable (aClipPlaneId);
+ else
+ aContext->core11fwd->glDisable (aClipPlaneId);
}
- else
- glDisable ( GL_CULL_FACE );
}
+#endif
- /////////////////////////////////////////////////////////////////////////////
- // Step 6: Draw overlayer
- const int aMode = 0;
- AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
-
- RedrawLayer2d(AWorkspace, ACView, ACOverLayer);
-
- AWorkspace->DisplayCallback (ACView, aMode);
+ // ==============================================================
+ // Step 8: Keep shader manager informed about last View
+ // ==============================================================
- // Restore clipping planes
- for ( ptrPlane = oldPlanes, planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++, ptrPlane++ )
+ if (!aManager.IsNull())
{
- glClipPlane( planeid, ptrPlane->Equation );
- if ( ptrPlane->isEnabled )
- glEnable( planeid );
- else
- glDisable( planeid );
+ aManager->SetLastView (this);
}
- delete[] oldPlanes;
+}
+
+// =======================================================================
+// function : InvalidateBVHData
+// purpose :
+// =======================================================================
+void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
+{
+ myZLayers.InvalidateBVHData (theLayerId);
}
/*----------------------------------------------------------------------*/
//ExecuteViewDisplay
-void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
+void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
+ const Graphic3d_CView& theCView,
+ const Standard_Boolean theToDrawImmediate)
{
if ( myZLayers.NbStructures() <= 0 )
return;
- glPushAttrib ( GL_DEPTH_BUFFER_BIT );
-
- const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine( Standard_True );
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- //TsmPushAttri(); /* save previous graphics context */
-
- if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
+ if ( (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
{
- const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
+ #if !defined(GL_ES_VERSION_2_0)
+ const int anAntiAliasingMode = theWorkspace->AntiAliasingMode();
+ #endif
if ( !myAntiAliasing )
{
- glDisable(GL_POINT_SMOOTH);
+ #if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->core11 != NULL)
+ {
+ glDisable (GL_POINT_SMOOTH);
+ }
glDisable(GL_LINE_SMOOTH);
- if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
+ if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
+ #endif
glBlendFunc (GL_ONE, GL_ZERO);
glDisable (GL_BLEND);
}
else
{
- glEnable(GL_POINT_SMOOTH);
+ #if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->core11 != NULL)
+ {
+ glEnable(GL_POINT_SMOOTH);
+ }
glEnable(GL_LINE_SMOOTH);
- if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
+ #endif
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
}
}
- myZLayers.Render (AWorkspace);
-
- //TsmPopAttri(); /* restore previous graphics context; before update lights */
+ Standard_Boolean toRenderGL = theToDrawImmediate ||
+ theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myRaytraceInitStatus == OpenGl_RT_FAIL;
- if ( AWorkspace->DegenerateModel > 1 )
+ if (!toRenderGL)
{
- glLineWidth ( aspect_line->Width() );
- if ( aspect_line->Type() != Aspect_TOL_SOLID ) glEnable ( GL_LINE_STIPPLE );
+ toRenderGL = !initRaytraceResources (theCView, aCtx) ||
+ !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
+
+ OpenGl_FrameBuffer* anOutputFBO = NULL;
+
+ if (theWorkspace->ResultFBO()->IsValid())
+ {
+ anOutputFBO = theWorkspace->ResultFBO().operator->();
+ }
+ else if (theCView.ptrFBO != NULL)
+ {
+ anOutputFBO = (OpenGl_FrameBuffer* )theCView.ptrFBO;
+ }
+ else
+ {
+ //toRenderGL = Standard_True; // failed to get valid FBO
+ }
+
+ if (!toRenderGL && myIsRaytraceDataValid)
+ {
+ const Standard_Integer aSizeX = anOutputFBO != NULL ?
+ anOutputFBO->GetVPSizeX() : theWorkspace->Width();
+ const Standard_Integer aSizeY = anOutputFBO != NULL ?
+ anOutputFBO->GetVPSizeY() : theWorkspace->Height();
+
+ if (myOpenGlFBO.IsNull())
+ myOpenGlFBO = new OpenGl_FrameBuffer;
+
+ if (myOpenGlFBO->GetVPSizeX() != aSizeX
+ || myOpenGlFBO->GetVPSizeY() != aSizeY)
+ {
+ myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
+ }
+
+ if (myRaytraceFilter.IsNull())
+ myRaytraceFilter = new OpenGl_RaytraceFilter;
+
+ myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
+
+ if (anOutputFBO != NULL)
+ anOutputFBO->UnbindBuffer (aCtx);
+
+ // Prepare preliminary OpenGL output
+ if (aCtx->arbFBOBlit != NULL)
+ {
+ // Render bottom OSD layer
+ myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
+
+ theWorkspace->SetRenderFilter (myRaytraceFilter);
+ {
+ if (anOutputFBO != NULL)
+ {
+ anOutputFBO->BindReadBuffer (aCtx);
+ }
+ else
+ {
+ aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
+ }
+
+ myOpenGlFBO->BindDrawBuffer (aCtx);
+
+ aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
+ 0, 0, aSizeX, aSizeY,
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ GL_NEAREST);
+
+ // Render non-polygonal elements in default layer
+ myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
+ }
+ theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
+ }
+
+ if (anOutputFBO != NULL)
+ {
+ anOutputFBO->BindBuffer (aCtx);
+ }
+ else
+ {
+ aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
+ }
+
+ // Ray-tracing polygonal primitive arrays
+ raytrace (theCView, aSizeX, aSizeY, anOutputFBO, aCtx);
+
+ // Render upper (top and topmost) OpenGL layers
+ myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
+ }
}
- glPopAttrib ();
+ // Redraw 3D scene using OpenGL in standard
+ // mode or in case of ray-tracing failure
+ if (toRenderGL)
+ {
+ myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
+
+ // Set flag that scene was redrawn by standard pipeline
+ theCView.WasRedrawnGL = Standard_True;
+ }
}
/*----------------------------------------------------------------------*/
//call_togl_redraw_layer2d
-void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer)
+void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
+ const Handle(OpenGl_Workspace)& theWorkspace,
+ const Graphic3d_CView& /*ACView*/,
+ const Aspect_CLayer2d& ACLayer)
{
+#if !defined(GL_ES_VERSION_2_0)
if (&ACLayer == NULL
|| ACLayer.ptrLayer == NULL
|| ACLayer.ptrLayer->listIndex == 0) return;
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+ if (aContext->core11 == NULL)
+ {
+ return;
+ }
+
GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
- const GLboolean isl = glIsEnabled(GL_LIGHTING); /*OCC6247*/
- if (isl)
- glDisable(GL_LIGHTING); /*OCC6247*/
+ aContext->WorldViewState.Push();
+ aContext->ProjectionState.Push();
- /*
- * On positionne la projection
- */
- glMatrixMode( GL_MODELVIEW );
- glPushMatrix ();
- glLoadIdentity ();
+ aContext->WorldViewState.SetIdentity();
+ aContext->ProjectionState.SetIdentity();
- glMatrixMode (GL_PROJECTION);
- glPushMatrix ();
- glLoadIdentity ();
+ aContext->ApplyWorldViewMatrix();
+ aContext->ApplyProjectionMatrix();
if (!ACLayer.sizeDependent)
- glViewport (0, 0, dispWidth, dispHeight);
+ aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
float left = ACLayer.ortho[0];
float right = ACLayer.ortho[1];
int attach = ACLayer.attach;
- float ratio;
- if (!ACLayer.sizeDependent)
- ratio = (float) dispWidth/dispHeight;
- else
- ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
+ const float ratio = !ACLayer.sizeDependent
+ ? float(dispWidth) / float(dispHeight)
+ : float(theWorkspace->Width()) / float(theWorkspace->Height());
float delta;
- if (ratio >= 1.0) { /* fenetre horizontale */
+ if (ratio >= 1.0) {
delta = (float )((top - bottom)/2.0);
switch (attach) {
case 0: /* Aspect_TOC_BOTTOM_LEFT */
break;
}
}
- else { /* fenetre verticale */
+ else {
delta = (float )((right - left)/2.0);
switch (attach) {
case 0: /* Aspect_TOC_BOTTOM_LEFT */
}
}
-#ifdef WNT
+#ifdef _WIN32
// Check printer context that exists only for print operation
- OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext (AWorkspace->GetGContext());
-
- if (aPrinterContext)
+ if (!thePrintContext.IsNull())
{
// additional transformation matrix could be applied to
// render only those parts of viewport that will be
// tiling; scaling of graphics by matrix helps render a
// part of a view (frame) in same viewport, but with higher
// resolution
- GLfloat aProjMatrix[16];
- aPrinterContext->GetProjTransformation (aProjMatrix);
- glLoadMatrixf ((GLfloat*) aProjMatrix);
+
+ // set printing scale/tiling transformation
+ aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
+ aContext->ApplyProjectionMatrix();
// printing operation also assumes other viewport dimension
// to comply with transformation matrix or graphics scaling
// factors for tiling for layer redraw
GLsizei anViewportX = 0;
GLsizei anViewportY = 0;
- aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
+ thePrintContext->GetLayerViewport (anViewportX, anViewportY);
if (anViewportX != 0 && anViewportY != 0)
- glViewport (0, 0, anViewportX, anViewportY);
+ aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
}
-#endif
+#endif
glOrtho (left, right, bottom, top, -1.0, 1.0);
- /*
- * On trace la display-list associee au layer.
- */
glPushAttrib (
GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
+
glDisable (GL_DEPTH_TEST);
+ glDisable (GL_TEXTURE_1D);
+ glDisable (GL_TEXTURE_2D);
+ glDisable (GL_LIGHTING);
+
+ // TODO: Obsolete code, the display list is always empty now, to be removed
glCallList (ACLayer.ptrLayer->listIndex);
//calling dynamic render of LayerItems
if ( ACLayer.ptrLayer->layerData )
{
- InitLayerProp(ACLayer.ptrLayer->listIndex);
+ InitLayerProp (ACLayer.ptrLayer->listIndex);
((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
- InitLayerProp(0);
+ InitLayerProp (0);
}
glPopAttrib ();
- /*
- * On retire la projection
- */
- glMatrixMode (GL_PROJECTION);
- glPopMatrix ();
+ aContext->WorldViewState.Pop();
+ aContext->ProjectionState.Pop();
- glMatrixMode( GL_MODELVIEW );
- glPopMatrix ();
+ aContext->ApplyProjectionMatrix();
+ aContext->ApplyWorldViewMatrix();
- /*
- * Restauration du Viewport en cas de modification
- */
if (!ACLayer.sizeDependent)
- glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
+ aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
glFlush ();
-
- if (isl)
- glEnable(GL_LIGHTING); /*OCC6247*/
+#endif
}
/*----------------------------------------------------------------------*/
-//call_togl_create_bg_texture
-void OpenGl_View::CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle)
+void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
{
- // Delete existing texture
- if ( myBgTexture.TexId != 0 )
+ // display global trihedron
+ if (myToShowTrihedron)
{
- glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
- myBgTexture.TexId = 0;
+ myTrihedron.Render (theWorkspace);
}
-
- Standard_Integer width, height;
- Handle(Image_Image) image;
- if ( AlienImage::LoadImageFile( AFileName, image, width, height ) )
+ if (myToShowGradTrihedron)
{
- const int nbbytes = width * height * 3;
- GLubyte *data = new GLubyte[nbbytes];
- GLubyte *pdata = data;
- Standard_Integer i, j;
- for ( j = height - 1; j >= 0; j-- )
- for ( i = 0; i < width; i++ )
- {
- const Quantity_Color &color = image->PixelColor( i, j );
- *pdata++ = (GLubyte)( 255 * color.Red() );
- *pdata++ = (GLubyte)( 255 * color.Green() );
- *pdata++ = (GLubyte)( 255 * color.Blue() );
- }
+ myGraduatedTrihedron.Render (theWorkspace);
+ }
+}
- GLuint texture = 0;
- glGenTextures( 1, &texture );
- glBindTexture( GL_TEXTURE_2D, texture );
+/*----------------------------------------------------------------------*/
- /* Create MipMapped Texture */
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+//call_togl_create_bg_texture
+void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
+ const Aspect_FillMethod theFillStyle)
+{
+ // Prepare aspect for texture storage
+ Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+ Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
+ aTextureMap->EnableRepeat();
+ aTextureMap->DisableModulate();
+ aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+ anAspect->SetTextureMap (aTextureMap);
+ anAspect->SetInteriorStyle (Aspect_IS_SOLID);
+ // Enable texture mapping
+ if (aTextureMap->IsDone())
+ {
+ anAspect->SetTextureMapOn();
+ }
+ else
+ {
+ anAspect->SetTextureMapOff();
+ return;
- gluBuild2DMipmaps( GL_TEXTURE_2D, 3/*4*/, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );
+ }
- delete[] data;
+ // Set texture parameters
+ myTextureParams->SetAspect (anAspect);
- myBgTexture.TexId = texture;
- myBgTexture.Width = width;
- myBgTexture.Height = height;
- myBgTexture.Style = AFillStyle;
- }
+ myBgTextureArray->SetTextureParameters (theFillStyle);
}
/*----------------------------------------------------------------------*/
//call_togl_set_bg_texture_style
-void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
+void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle)
{
- myBgTexture.Style = AFillStyle;
+ myBgTextureArray->SetTextureFillMethod (theFillStyle);
}
/*----------------------------------------------------------------------*/
//call_togl_gradient_background
-void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
- const Quantity_Color& AColor2,
- const Aspect_GradientFillMethod AType)
+void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1,
+ const Quantity_Color& theColor2,
+ const Aspect_GradientFillMethod theType)
{
- Standard_Real R,G,B;
- AColor1.Values( R, G, B, Quantity_TOC_RGB );
- myBgGradient.color1.rgb[0] = ( Tfloat )R;
- myBgGradient.color1.rgb[1] = ( Tfloat )G;
- myBgGradient.color1.rgb[2] = ( Tfloat )B;
- myBgGradient.color1.rgb[3] = 0.F;
-
- AColor2.Values( R, G, B, Quantity_TOC_RGB );
- myBgGradient.color2.rgb[0] = ( Tfloat )R;
- myBgGradient.color2.rgb[1] = ( Tfloat )G;
- myBgGradient.color2.rgb[2] = ( Tfloat )B;
- myBgGradient.color2.rgb[3] = 0.F;
-
- myBgGradient.type = AType;
+ myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType);
}
/*----------------------------------------------------------------------*/
//call_togl_set_gradient_type
-void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
+void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType)
{
- myBgGradient.type = AType;
+ myBgGradientArray->SetGradientFillMethod (theType);
}
//=======================================================================
//function : AddZLayer
-//purpose :
+//purpose :
//=======================================================================
-void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
+void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
{
myZLayers.AddLayer (theLayerId);
}
//=======================================================================
//function : RemoveZLayer
-//purpose :
+//purpose :
//=======================================================================
-void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
+void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
{
myZLayers.RemoveLayer (theLayerId);
}
//=======================================================================
//function : DisplayStructure
-//purpose :
+//purpose :
+//=======================================================================
+
+void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure,
+ const Standard_Integer thePriority)
+{
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
+ const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
+ myZLayers.AddStructure (aStruct, aZLayer, thePriority);
+}
+
+//=======================================================================
+//function : DisplayImmediateStructure
+//purpose :
//=======================================================================
-void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
- const Standard_Integer thePriority)
+void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure)
{
- Standard_Integer aZLayer = theStructure->GetZLayer ();
- myZLayers.AddStructure (theStructure, aZLayer, thePriority);
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->());
+ for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
+ anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == aStruct)
+ {
+ return;
+ }
+ }
+
+ myImmediateList.Append (aStruct);
}
//=======================================================================
//function : EraseStructure
-//purpose :
+//purpose :
//=======================================================================
-void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
+void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure)
{
- Standard_Integer aZLayer = theStructure->GetZLayer ();
- myZLayers.RemoveStructure (theStructure, aZLayer);
+ myZLayers.RemoveStructure (theStructure);
+}
+
+//=======================================================================
+//function : EraseImmediateStructure
+//purpose :
+//=======================================================================
+
+void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
+{
+ for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
+ anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == theStructure)
+ {
+ myImmediateList.Remove (anIter);
+ return;
+ }
+ }
}
//=======================================================================
//purpose :
//=======================================================================
-void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
- const Standard_Integer theNewLayerId)
+void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure,
+ const Graphic3d_ZLayerId theNewLayerId)
{
- Standard_Integer anOldLayer = theStructure->GetZLayer ();
+ const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
}
+
+//=======================================================================
+//function : SetZLayerSettings
+//purpose :
+//=======================================================================
+void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
+ const Graphic3d_ZLayerSettings& theSettings)
+{
+ myZLayers.SetLayerSettings (theLayerId, theSettings);
+}
+
+//=======================================================================
+//function : ChangePriority
+//purpose :
+//=======================================================================
+void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
+ const Standard_Integer theNewPriority)
+{
+ const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
+ myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
+}
+
+//=======================================================================
+//function : RedrawScene
+//purpose :
+//=======================================================================
+
+void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
+ const Handle(OpenGl_Workspace)& theWorkspace,
+ const Graphic3d_CView& theCView,
+ const Standard_Boolean theToDrawImmediate)
+{
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+
+ if (myZClip.Back.IsOn || myZClip.Front.IsOn)
+ {
+ Handle(Graphic3d_ClipPlane) aPlaneBack;
+ Handle(Graphic3d_ClipPlane) aPlaneFront;
+
+ if (myZClip.Back.IsOn)
+ {
+ Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
+ if (myCamera->ZFar() < aClipBackConverted)
+ {
+ aClipBackConverted = myCamera->ZFar();
+ myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
+ }
+ const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
+ aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
+ }
+
+ if (myZClip.Front.IsOn)
+ {
+ Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
+ if (myCamera->ZNear() > aClipFrontConverted)
+ {
+ aClipFrontConverted = myCamera->ZNear();
+ myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
+ }
+ const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
+ aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
+ }
+
+ // Specify slicing planes with identity transformation
+ if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
+ {
+ Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
+ if (!aPlaneBack.IsNull())
+ {
+ aSlicingPlanes.Append (aPlaneBack);
+ }
+
+ if (!aPlaneFront.IsNull())
+ {
+ aSlicingPlanes.Append (aPlaneFront);
+ }
+
+ // add planes at loaded view matrix state
+ aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
+ }
+ }
+
+#ifdef _WIN32
+ // set printing scale/tiling transformation
+ if (!thePrintContext.IsNull())
+ {
+ aContext->ProjectionState.Push();
+ aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
+ aContext->ApplyProjectionMatrix();
+ }
+#endif
+
+ // Specify clipping planes in view transformation space
+ if (!myClipPlanes.IsEmpty())
+ {
+ Graphic3d_SequenceOfHClipPlane aUserPlanes;
+ Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
+ for (; aClippingIt.More(); aClippingIt.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
+ if (aClipPlane->IsOn())
+ {
+ aUserPlanes.Append (aClipPlane);
+ }
+ }
+
+ if (!aUserPlanes.IsEmpty())
+ {
+ aContext->ChangeClipping().AddWorld (aUserPlanes);
+ }
+
+ if (!aContext->ShaderManager()->IsEmpty())
+ {
+ aContext->ShaderManager()->UpdateClippingState();
+ }
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ // Apply Lights
+ if (aContext->core11 != NULL)
+ {
+ // setup lights
+ Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
+ THE_DEFAULT_AMBIENT[1],
+ THE_DEFAULT_AMBIENT[2],
+ THE_DEFAULT_AMBIENT[3]);
+ GLenum aLightGlId = GL_LIGHT0;
+ for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
+ aLightIt.More(); aLightIt.Next())
+ {
+ bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
+ }
+
+ // apply accumulated ambient color
+ anAmbientColor.a() = 1.0f;
+ glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
+
+ if (aLightGlId != GL_LIGHT0)
+ {
+ glEnable (GL_LIGHTING);
+ }
+ // switch off unused lights
+ for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
+ {
+ glDisable (aLightGlId);
+ }
+ }
+#endif
+
+ // Clear status bitfields
+ theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
+
+ // Update state of surface detail level
+ theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
+
+ // Added PCT for handling of textures
+ switch (mySurfaceDetail)
+ {
+ case Visual3d_TOD_NONE:
+ theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+ theWorkspace->DisableTexture();
+ // Render the view
+ RenderStructs (theWorkspace, theCView, theToDrawImmediate);
+ break;
+
+ case Visual3d_TOD_ENVIRONMENT:
+ theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+ theWorkspace->EnableTexture (myTextureEnv);
+ // Render the view
+ RenderStructs (theWorkspace, theCView, theToDrawImmediate);
+ theWorkspace->DisableTexture();
+ break;
+
+ case Visual3d_TOD_ALL:
+ // First pass
+ theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
+ // Render the view
+ RenderStructs (theWorkspace, theCView, theToDrawImmediate);
+ theWorkspace->DisableTexture();
+
+ // Second pass
+ if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
+ {
+ theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
+ theWorkspace->EnableTexture (myTextureEnv);
+
+ // Remember OpenGl properties
+ GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
+ GLint aSaveZbuffFunc;
+ GLboolean aSaveZbuffWrite;
+ glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
+ glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
+ #if !defined(GL_ES_VERSION_2_0)
+ glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
+ glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
+ #endif
+ GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
+ GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
+
+ // Change the properties for second rendering pass
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable (GL_BLEND);
+
+ glDepthFunc (GL_EQUAL);
+ glDepthMask (GL_FALSE);
+ glEnable (GL_DEPTH_TEST);
+
+ theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+
+ // Render the view
+ RenderStructs (theWorkspace, theCView, theToDrawImmediate);
+ theWorkspace->DisableTexture();
+
+ // Restore properties back
+ glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
+ if (!wasBlendEnabled)
+ glDisable (GL_BLEND);
+
+ glDepthFunc (aSaveZbuffFunc);
+ glDepthMask (aSaveZbuffWrite);
+ if (!wasZbuffEnabled)
+ glDisable (GL_DEPTH_FUNC);
+ }
+ break;
+ }
+
+ // Apply restored view matrix.
+ aContext->ApplyWorldViewMatrix();
+
+#ifdef _WIN32
+ // set printing scale/tiling transformation
+ if (!thePrintContext.IsNull())
+ {
+ aContext->ProjectionState.Pop();
+ aContext->ApplyProjectionMatrix();
+ }
+#endif
+
+}