// Created on: 2011-09-20
// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
#include <stdio.h>
#include <stdlib.h>
#include <Image_AlienPixMap.hxx>
#include <Visual3d_Layer.hxx>
+#include <NCollection_Mat4.hxx>
+
#include <OpenGl_AspectLine.hxx>
+#include <OpenGl_Context.hxx>
#include <OpenGl_Display.hxx>
+#include <OpenGl_Matrix.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Trihedron.hxx>
#include <OpenGl_GraduatedTrihedron.hxx>
#include <OpenGl_PrinterContext.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.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
+{
+
+ 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 AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
+};
+
+extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
/*----------------------------------------------------------------------*/
/*
* Set des lumieres
*/
-static void bind_light(const OpenGl_Light *lptr, int *gl_lid)
+static void bind_light (const OpenGl_Light& theLight,
+ GLenum& theLightGlId,
+ Graphic3d_Vec4& theAmbientColor)
{
// 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)
+ // the light is a headlight?
+ GLint aMatrixModeOld = 0;
+ if (theLight.IsHeadlight)
{
- glEnable(*gl_lid);
- (*gl_lid)++;
+ glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
+ glMatrixMode (GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
}
- /* si la light etait une headlight alors restaure la matrice precedente */
- if (lptr->HeadLight)
+ // setup light type
+ switch (theLight.Type)
{
- 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
-{
-
- /* 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;
+ 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;
}
-}
-
-/*----------------------------------------------------------------------*/
-/*
-* 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)
- {
- 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_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;
+ }
+ 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;
}
- 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)
+ // restore matrix in case of headlight
+ if (theLight.IsHeadlight)
{
- 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;
- }
- 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);
-
- return;
+ glPopMatrix();
+ glMatrixMode (aMatrixModeOld);
}
- else
- *err_ind = 1;
-}
-
-/*----------------------------------------------------------------------*/
-static void
-call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
- float *ox, float *oy, float *oz )
-{
- 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;
+ glEnable (theLightGlId++);
}
/*----------------------------------------------------------------------*/
-static void
-call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
+void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
{
- int i, j, k;
-
- 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];
-}
-
-/*----------------------------------------------------------------------*/
-
-//call_func_redraw_all_structs_proc
-void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
- const Handle(OpenGl_Workspace) &AWorkspace,
- const Graphic3d_CView& ACView,
- const Aspect_CLayer2d& ACUnderLayer,
- const Aspect_CLayer2d& ACOverLayer)
-{
- // 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++ )
- {
- glGetClipPlane( planeid, ptrPlane->Equation );
- if ( ptrPlane->isEnabled )
- {
- glDisable( planeid );
- ptrPlane->isEnabled = GL_TRUE;
- }
- else
- ptrPlane->isEnabled = GL_FALSE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Step 1: Prepare for redraw
-
- // Render background
- if ( (AWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
- ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
+ if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
+ ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
{
- const Standard_Integer aViewWidth = AWorkspace->Width();
- const Standard_Integer aViewHeight = AWorkspace->Height();
+ const Standard_Integer aViewWidth = theWorkspace.Width();
+ const Standard_Integer aViewHeight = theWorkspace.Height();
glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
// - 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 ) )
+ ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
+ myBgTexture.Style == Aspect_FM_NONE ) )
{
Tfloat* corner1 = 0;/* -1,-1*/
Tfloat* corner2 = 0;/* 1,-1*/
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;
+ 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;
}
// Save GL parameters
GLfloat texX_range = 1.F; // texture <s> coordinate
GLfloat texY_range = 1.F; // texture <t> coordinate
- // Set up for stretching or tiling
+ // Set up for stretching or tiling
GLfloat x_offset, y_offset;
if ( myBgTexture.Style == Aspect_FM_CENTERED )
{
glDisable( GL_BLEND ); //push GL_ENABLE_BIT
- glColor3fv( AWorkspace->BackgroundColor().rgb );
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
+ glColor3fv (theWorkspace.BackgroundColor().rgb);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
// Note that texture is mapped using GL_REPEAT wrapping mode so integer part
// is simply ignored, and negative multiplier is here for convenience only
glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
- if ( AWorkspace->UseZBuffer() )
- glEnable( GL_DEPTH_TEST );
+ if (theWorkspace.UseZBuffer())
+ glEnable (GL_DEPTH_TEST);
/* GL_DITHER on/off pour le trace */
- if (AWorkspace->Dither())
+ if (theWorkspace.Dither())
glEnable (GL_DITHER);
else
glDisable (GL_DITHER);
}
+}
- // Switch off lighting by default
- glDisable(GL_LIGHTING);
+/*----------------------------------------------------------------------*/
+
+//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)
+{
+ // ==================================
+ // Step 1: Prepare for redraw
+ // ==================================
- /////////////////////////////////////////////////////////////////////////////
- // Step 2: Draw underlayer
- RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACUnderLayer);
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
- /////////////////////////////////////////////////////////////////////////////
- // Step 3: Redraw main plane
+ // Store and disable current clipping planes
+ Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
- // Setup face culling
- GLboolean isCullFace = GL_FALSE;
- if ( myBackfacing )
+ OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
+ OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
+
+ GLenum aClipPlaneId = GL_CLIP_PLANE0;
+ const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
+ for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
{
- isCullFace = glIsEnabled( GL_CULL_FACE );
- if ( myBackfacing < 0 )
+ glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
+ if (aPtrPlane->isEnabled)
{
- glEnable( GL_CULL_FACE );
- glCullFace( GL_BACK );
+ glDisable (aClipPlaneId);
+ aPtrPlane->isEnabled = GL_TRUE;
+ }
+ else
+ {
+ aPtrPlane->isEnabled = GL_FALSE;
}
- else
- glDisable( GL_CULL_FACE );
}
- //TsmPushAttri(); /* save previous graphics context */
+ // Set OCCT state uniform variables
+ const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
+ if (!aManager->IsEmpty())
+ {
+ if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
+ {
+ aManager->UpdateLightSourceStateTo (&myLights);
+ myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
+ }
- // 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);
+ if (myProjectionState != myCamera->ProjectionState())
+ {
+ myProjectionState = myCamera->ProjectionState();
+ aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
+ }
- // Apply View Projection
- // This routine activates the Projection matrix for a view.
+ if (myModelViewState != myCamera->ModelViewState())
+ {
+ myModelViewState = myCamera->ModelViewState();
+ aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
+ }
- glMatrixMode( GL_PROJECTION );
+ if (aManager->ModelWorldState().Index() == 0)
+ {
+ Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
+ { 0.f, 1.f, 0.f, 0.f },
+ { 0.f, 0.f, 1.f, 0.f },
+ { 0.f, 0.f, 0.f, 1.f } };
-#ifdef _WIN32
- // add printing scale/tiling transformation
- if (!thePrintContext.IsNull())
- {
- thePrintContext->LoadProjTransformation();
+ aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
+ }
}
- else
-#endif
- glLoadIdentity();
-
- glMultMatrixf( (const GLfloat *) myMappingMatrix );
- // Add translation necessary for the environnement mapping
- if (mySurfaceDetail != Visual3d_TOD_NONE)
+ if (!aManager.IsNull())
{
- // 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]);
- }
+ if (!aManager->IsSameView (this))
+ {
+ // Force update camera states
+ myProjectionState = myCamera->ProjectionState();
+ aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
- // Apply matrix
- AWorkspace->SetViewMatrix((const OpenGl_Matrix *)myOrientationMatrix);
+ myModelViewState = myCamera->ModelViewState();
+ aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
+ }
+ }
-/*
-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|
+ // ====================================
+ // Step 2: Redraw background
+ // ====================================
-*/
+ // Render background
+ DrawBackground (*theWorkspace);
- // Apply Fog
- if ( myFog.IsOn )
- {
- 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;
+ // Switch off lighting by default
+ glDisable(GL_LIGHTING);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogf(GL_FOG_START, fog_start);
- glFogf(GL_FOG_END, fog_end);
- glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
- glEnable(GL_FOG);
- }
- else
- glDisable(GL_FOG);
+ // =================================
+ // Step 3: Draw underlayer
+ // =================================
- // Apply Lights
- {
- int i;
+ RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
- // Switch off all lights
- for (i = GL_LIGHT0; i <= GL_LIGHT7; i++)
- glDisable(i);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
+ // =================================
+ // Step 4: Redraw main plane
+ // =================================
- /* set les lights */
- int gl_lid = GL_LIGHT0;
- OpenGl_ListOfLight::Iterator itl(myLights);
- for (; itl.More(); itl.Next())
+ // Setup face culling
+ GLboolean isCullFace = GL_FALSE;
+ if ( myBackfacing )
+ {
+ isCullFace = glIsEnabled( GL_CULL_FACE );
+ if ( myBackfacing < 0 )
{
- const OpenGl_Light &alight = itl.Value();
- bind_light(&alight, &gl_lid);
+ glEnable( GL_CULL_FACE );
+ glCullFace( GL_BACK );
}
-
- if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING);
+ else
+ glDisable( GL_CULL_FACE );
}
- // Apply InteriorShadingMethod
- glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
+ // 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)
+ glEnable(GL_NORMALIZE);
+ else if(glIsEnabled(GL_NORMALIZE))
+ glDisable(GL_NORMALIZE);
- // Apply clipping planes
+ // Apply Fog
+ if ( myFog.IsOn )
{
- // Define starting plane id
- planeid = GL_CLIP_PLANE0;
-
- GLdouble equation[4];
-
- if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
+ Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
+ if (myCamera->ZFar() < aFogFrontConverted)
{
- // Apply front and back clipping planes
- GLfloat mat[4][4];
- glMatrixMode( GL_MODELVIEW );
- glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
- glLoadIdentity();
-
- const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
-
- 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++;
- }
-
- 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++;
- }
-
- glLoadMatrixf( (GLfloat *) mat );
+ aFogFrontConverted = myCamera->ZFar();
+ myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
}
- // Apply user clipping planes
- NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
- for ( ; planeIter.More(); planeIter.Next() )
+ Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
+ if (myCamera->ZFar() < aFogFrontConverted)
{
- glClipPlane( planeid, planeIter.Value().equation );
- glEnable( planeid );
- planeid++;
+ 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, (Standard_ShortReal )aFogFrontConverted);
+ glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
+ glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
+ glEnable(GL_FOG);
}
+ else
+ glDisable(GL_FOG);
+
+ // Apply InteriorShadingMethod
+ glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
// Apply AntiAliasing
+ if (myAntiAliasing)
+ theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
+ else
+ theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
+
+ if (!aManager->IsEmpty())
{
- if (myAntiAliasing)
- AWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
- else
- AWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
+ aManager->UpdateClippingState();
}
- // Clear status bitfields
- AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
-
- // Added PCT for handling of textures
- switch (mySurfaceDetail)
+ // Redraw 3d scene
+ if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
{
- case Visual3d_TOD_NONE:
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- AWorkspace->DisableTexture();
- // Render the view
- RenderStructs(AWorkspace);
- break;
+ // single-pass monographic rendering
+ const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
- case Visual3d_TOD_ENVIRONMENT:
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- AWorkspace->EnableTexture (myTextureEnv);
- // Render the view
- RenderStructs(AWorkspace);
- AWorkspace->DisableTexture();
- break;
-
- case Visual3d_TOD_ALL:
- // First pass
- AWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
- // Render the view
- RenderStructs(AWorkspace);
- AWorkspace->DisableTexture();
-
- // Second pass
- if (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
- {
- AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
- AWorkspace->EnableTexture (myTextureEnv);
-
- /* 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);
+ const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
- AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+ // redraw scene with normal orientation and projection
+ RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
+ }
+ else
+ {
+ // two stereographic passes
+ const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
+ const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
+ const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
- // Render the view
- RenderStructs(AWorkspace);
- AWorkspace->DisableTexture();
+ // safely switch to left Eye buffer
+ aContext->SetDrawBufferLeft();
- /* restauration des parametres OpenGL */
- glBlendFunc(blend_src, blend_dst);
- if (!blend_state) glDisable(GL_BLEND);
+ // redraw left Eye
+ RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
- glDepthFunc(zbuff_f);
- glDepthMask(zbuff_w);
- if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
- }
- break;
+ // reset depth buffer of first rendering pass
+ if (theWorkspace->UseDepthTest())
+ {
+ glClear (GL_DEPTH_BUFFER_BIT);
+ }
+ // safely switch to right Eye buffer
+ aContext->SetDrawBufferRight();
+
+ // redraw right Eye
+ RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
+
+ // switch back to monographic rendering
+ aContext->SetDrawBufferMono();
}
+ // ===============================
+ // 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
- AWorkspace->ResetAppliedAspect();
+ theWorkspace->ResetAppliedAspect();
- // Disable current clipping planes
- for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
- glDisable( planeid );
+ aContext->ChangeClipping().RemoveAll();
+
+ if (!aManager->IsEmpty())
+ {
+ 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)
+ OpenGl_ShaderProgram::Unbind (aContext);
+ }
// display global trihedron
if (myTrihedron != NULL)
{
- myTrihedron->Render (AWorkspace);
+ myTrihedron->Render (theWorkspace);
}
if (myGraduatedTrihedron != NULL)
{
- myGraduatedTrihedron->Render (AWorkspace);
+ myGraduatedTrihedron->Render (theWorkspace);
}
// Restore face culling
glDisable ( GL_CULL_FACE );
}
- /////////////////////////////////////////////////////////////////////////////
- // Step 6: Draw overlayer
+ // ===============================
+ // Step 6: Redraw overlay
+ // ===============================
+
const int aMode = 0;
- AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
+ theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
- RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACOverLayer);
+ RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
- AWorkspace->DisplayCallback (ACView, aMode);
+ theWorkspace->DisplayCallback (theCView, aMode);
+
+ // ===============================
+ // Step 7: Finalize
+ // ===============================
// Restore clipping planes
- for ( ptrPlane = oldPlanes, planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++, ptrPlane++ )
+ aClipPlaneId = GL_CLIP_PLANE0;
+ aPtrPlane = aOldPlanes;
+
+ for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
{
- glClipPlane( planeid, ptrPlane->Equation );
- if ( ptrPlane->isEnabled )
- glEnable( planeid );
+ glClipPlane (aClipPlaneId, aPtrPlane->Equation);
+ if (aPtrPlane->isEnabled)
+ glEnable (aClipPlaneId);
else
- glDisable( planeid );
+ glDisable (aClipPlaneId);
+ }
+
+ delete[] aOldPlanes;
+
+ // ==============================================================
+ // Step 8: Keep shader manager informed about last View
+ // ==============================================================
+
+ if (!aManager.IsNull())
+ {
+ aManager->SetLastView (this);
}
- delete[] oldPlanes;
}
/*----------------------------------------------------------------------*/
//call_togl_redraw_layer2d
void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
- const Handle(OpenGl_Workspace)& AWorkspace,
const Graphic3d_CView& ACView,
const Aspect_CLayer2d& ACLayer)
{
//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 ();
{
aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
Image_ColorRGB& aColor = aDataNew.ChangeValue (aRow, aCol);
- aColor.r() = int(255.0 * aSrcColor.Red());
- aColor.g() = int(255.0 * aSrcColor.Green());
- aColor.b() = int(255.0 * aSrcColor.Blue());
+ aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
+ aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
+ aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
}
}
anImageLoaded.Clear();
myZLayers.AddStructure (theStructure, aZLayer, thePriority);
}
+//=======================================================================
+//function : DisplayImmediateStructure
+//purpose :
+//=======================================================================
+
+void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
+{
+ for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
+ anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == theStructure)
+ {
+ return;
+ }
+ }
+
+ myImmediateList.Append (theStructure);
+}
+
//=======================================================================
//function : EraseStructure
//purpose :
myZLayers.RemoveStructure (theStructure, aZLayer);
}
+//=======================================================================
+//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;
+ }
+ }
+}
+
//=======================================================================
//function : ChangeZLayer
//purpose :
Standard_Integer anOldLayer = theStructure->GetZLayer ();
myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
}
+
+//=======================================================================
+//function : RedrawScene
+//purpose :
+//=======================================================================
+
+void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
+ const Handle(OpenGl_Workspace)& theWorkspace,
+ const OpenGl_Matrix* theProjection,
+ const OpenGl_Matrix* theOrientation)
+{
+ 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);
+ }
+
+ // do some "memory allocation"-wise optimization
+ 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);
+ }
+ }
+
+ // Apply user clipping planes
+ 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())
+ {
+ // add planes at actual matrix state.
+ aContext->ChangeClipping().AddWorld (aUserPlanes);
+ }
+
+ if (!aContext->ShaderManager()->IsEmpty())
+ {
+ aContext->ShaderManager()->UpdateClippingState();
+ }
+ }
+
+ // Setup view projection
+ glMatrixMode (GL_PROJECTION);
+
+#ifdef _WIN32
+ // add printing scale/tiling transformation
+ if (!thePrintContext.IsNull())
+ {
+ thePrintContext->LoadProjTransformation();
+ }
+ else
+#endif
+ glLoadIdentity();
+
+ glMultMatrixf ((const GLfloat*)theProjection);
+
+ if (!thePrintContext.IsNull())
+ {
+ // update shader uniform projection matrix with new data
+ Tmatrix3 aResultProjection;
+ glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
+ aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
+
+ // force shader uniform restore on next frame
+ myProjectionState = 0;
+ }
+
+ // Setup view orientation
+ theWorkspace->SetViewMatrix (theOrientation);
+
+ // Apply Lights
+ {
+ // 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())
+ {
+ bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
+ }
+
+ // 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);
+ }
+ }
+
+ // Clear status bitfields
+ theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
+
+ // Added PCT for handling of textures
+ switch (mySurfaceDetail)
+ {
+ case Visual3d_TOD_NONE:
+ theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+ theWorkspace->DisableTexture();
+ // Render the view
+ RenderStructs (theWorkspace);
+ break;
+
+ case Visual3d_TOD_ENVIRONMENT:
+ theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
+ theWorkspace->EnableTexture (myTextureEnv);
+ // Render the view
+ RenderStructs (theWorkspace);
+ theWorkspace->DisableTexture();
+ break;
+
+ case Visual3d_TOD_ALL:
+ // First pass
+ theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
+ // Render the view
+ RenderStructs (theWorkspace);
+ theWorkspace->DisableTexture();
+
+ // Second pass
+ if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
+ {
+ theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
+ theWorkspace->EnableTexture (myTextureEnv);
+
+ // Remember OpenGl properties
+ GLint aSaveBlendDst, aSaveBlendSrc;
+ GLint aSaveZbuffFunc;
+ GLboolean aSaveZbuffWrite;
+ glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
+ glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
+ glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
+ glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
+ 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);
+ theWorkspace->DisableTexture();
+
+ // Restore properties back
+ glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
+ if (!wasBlendEnabled)
+ glDisable (GL_BLEND);
+
+ glDepthFunc (aSaveZbuffFunc);
+ glDepthMask (aSaveZbuffWrite);
+ if (!wasZbuffEnabled)
+ glDisable (GL_DEPTH_FUNC);
+ }
+ break;
+ }
+}