mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
1128 lines
27 KiB
C++
Executable File
1128 lines
27 KiB
C++
Executable File
/***********************************************************************
|
|
|
|
FONCTION :
|
|
----------
|
|
File OpenGl_telem_util :
|
|
|
|
|
|
REMARQUES:
|
|
----------
|
|
|
|
|
|
HISTORIQUE DES MODIFICATIONS :
|
|
--------------------------------
|
|
xx-xx-xx : xxx ; Creation.
|
|
07-02-96 : FMN ; - Ajout trace
|
|
- Suppression code inutile
|
|
08-03-96 : FMN ; - Ajout include manquant
|
|
01-04-96 : CAL ; Integration MINSK portage WNT
|
|
15-04-96 : CAL ; Integration travail PIXMAP de Jim ROTH
|
|
22-04-96 : FMN ; Ajout TelReadImage TelDrawImage
|
|
10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies
|
|
de pixels (voir CALL_DEF_DELTA)
|
|
25-06-96 : FMN ; Suppression utilisation de glScissor.
|
|
02-07-96 : FMN ; Suppression WSWSHeight et WSWSWidth
|
|
Suppression glViewport inutile.
|
|
18-07-96 : FMN ; Suppression TelFlush inutile.
|
|
08-07-96 : FMN ; Suppression de OPENGL_DEBUG inutile avec la nouvelle
|
|
version de ogldebug.
|
|
24-10-96 : CAL ; Portage WNT
|
|
23-01-97 : CAL ; Suppression de TelClearViews dans TelCopyBuffers
|
|
30-01-97 : FMN ; Ajout commentaires + WNT.
|
|
12-02-97 : FMN ; Suppression TelEnquireFacilities()
|
|
22-04-97 : FMN ; Ajout affichage du cadre pour la copie de buffer
|
|
30-06-97 : FMN ; Suppression OpenGl_telem_light.h
|
|
18-07-97 : FMN ; Utilisation de la toolkit sur les lights
|
|
07-10-97 : FMN ; Simplification WNT + correction Transient
|
|
05-12-97 : FMN ; PRO11168: Suppression TglActiveWs pour project/unproject
|
|
23-12-97 : FMN ; Suppression TelSetFrontFaceAttri et TelSetBackFaceAttri
|
|
30-12-97 : FMN ; CTS18312: Correction back material
|
|
04-05-98 : CAL ; Contournement bug SGI octane bavure de pixels (PRO12899)
|
|
30-09-98 : CAL ; Optimisation pour eviter de charger inutilement
|
|
les matrices de la vue.
|
|
19-10-98 : FMN ; Suppression de glPixelTransferi dans TelEnable() car cela
|
|
rentre en conflit avec l'utilisation d'une image de fond.
|
|
02.14.100 : JR : Warnings on WNT truncations from double to float
|
|
08-03-01 : GG ; BUC60823 Avoid crash in the normal computation method
|
|
when a face has confused or aligned points.
|
|
|
|
************************************************************************/
|
|
|
|
#define IMP190100 /*GG To avoid too many REDRAW in immediat mode,
|
|
// Add TelMakeFrontAndBackBufCurrent() function
|
|
*/
|
|
#define QTOCC_PATCH
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/*
|
|
* Includes
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifndef WNT
|
|
# include <X11/Xlib.h>
|
|
#else
|
|
# define STRICT
|
|
# include <windows.h>
|
|
#endif /* WNT */
|
|
|
|
|
|
#include <GL/gl.h>
|
|
#include <GL/glu.h>
|
|
#ifndef WNT
|
|
#include <GL/glx.h>
|
|
#endif /* WNT */
|
|
|
|
#include <InterfaceGraphic_Graphic3d.hxx>
|
|
#include <InterfaceGraphic_Visual3d.hxx>
|
|
|
|
#include <OpenGl_tgl_all.hxx>
|
|
#include <OpenGl_tsm.hxx>
|
|
#include <OpenGl_tsm_ws.hxx>
|
|
#include <OpenGl_telem.hxx>
|
|
#include <OpenGl_telem_attri.hxx>
|
|
#include <OpenGl_telem_util.hxx>
|
|
#include <OpenGl_telem_view.hxx>
|
|
#include <OpenGl_tgl_tox.hxx>
|
|
#include <OpenGl_tgl_subrvis.hxx>
|
|
#include <OpenGl_txgl.hxx>
|
|
#include <OpenGl_LightBox.hxx>
|
|
#include <OpenGl_Memory.hxx>
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/*
|
|
* Constantes
|
|
*/
|
|
|
|
#define NO_TRACE
|
|
#define CALL_DEF_DELTA 10
|
|
#define NO_COPYBUFFER
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/*
|
|
* Variables statiques
|
|
*/
|
|
|
|
static Tint call_back_buffer_restored = TOff;
|
|
|
|
#ifndef WNT
|
|
|
|
/*
|
|
* Wrappers and utilities used to select between pixmap and gl double buffering
|
|
*/
|
|
|
|
/* Cache some pixmap info for pixmap double buffering */
|
|
|
|
static Display *window_display; /* the display in use */
|
|
static Window window_id; /* the window to copy the pixmap to */
|
|
static Pixmap pixmap_id; /* the pixmap id */
|
|
static GLXPixmap glx_pixmap; /* the glx pixmap */
|
|
static int
|
|
window_width, /* window width and height for XCopyArea */
|
|
window_height,
|
|
window_depth;
|
|
|
|
static GC window_gc; /* GC for XCopyArea */
|
|
|
|
static GLXContext glx_context; /* GL Context */
|
|
|
|
static int usePixmapDB = 0; /* True if doing pixmap double buffering */
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void TelSetPixmapDBParams(Display *dpy,
|
|
Window window,
|
|
int width, int height, int depth, GC gc,
|
|
Pixmap pixmap,
|
|
GLXPixmap glxpixmap,
|
|
GLXContext ctx)
|
|
|
|
{
|
|
window_display = dpy;
|
|
window_id = window;
|
|
window_width = width;
|
|
window_height = height;
|
|
window_depth = depth;
|
|
window_gc = gc;
|
|
|
|
pixmap_id = pixmap;
|
|
|
|
glx_pixmap = glxpixmap;
|
|
|
|
glx_context = ctx;
|
|
}
|
|
|
|
GLXPixmap TelGetGLXPixmap()
|
|
{
|
|
return glx_pixmap;
|
|
}
|
|
|
|
void TelSetPixmapDB(int flag)
|
|
{
|
|
usePixmapDB = flag;
|
|
}
|
|
|
|
int TelTestPixmapDB()
|
|
{
|
|
return usePixmapDB;
|
|
}
|
|
|
|
void TelDrawBuffer(GLenum buf)
|
|
{
|
|
if (usePixmapDB)
|
|
glDrawBuffer(GL_FRONT);
|
|
else
|
|
glDrawBuffer(buf);
|
|
}
|
|
|
|
#endif /* WNT */
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void TelMakeFrontBufCurrent(Tint WsId)
|
|
{
|
|
#ifndef WNT
|
|
if (usePixmapDB)
|
|
{
|
|
glXMakeCurrent(window_display,window_id, glx_context);
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
#endif /* WNT */
|
|
{
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
}
|
|
|
|
void TelMakeBackBufCurrent(Tint WsId)
|
|
{
|
|
#ifndef WNT
|
|
if (usePixmapDB)
|
|
{
|
|
glXMakeCurrent(window_display,glx_pixmap, glx_context);
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
else
|
|
#endif /* WNT */
|
|
{
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
}
|
|
|
|
#ifdef IMP190100
|
|
void TelMakeFrontAndBackBufCurrent(Tint WsId)
|
|
{
|
|
#ifndef WNT
|
|
if (usePixmapDB)
|
|
{
|
|
glXMakeCurrent(window_display,window_id, glx_context);
|
|
glDrawBuffer(GL_FRONT_AND_BACK);
|
|
}
|
|
else
|
|
#endif /* WNT */
|
|
{
|
|
glDrawBuffer(GL_FRONT_AND_BACK);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
Tint
|
|
TelRemdupnames(Tint *ls, Tint num )
|
|
{
|
|
register Tint *ap, *bp, n;
|
|
|
|
if( num < 2 )
|
|
return num;
|
|
|
|
ap = bp = ls+1;
|
|
n = num-1;
|
|
while( n-- )
|
|
{
|
|
if( ap[-1] != *bp )
|
|
*ap++ = *bp++;
|
|
else
|
|
bp++;
|
|
}
|
|
|
|
return ap-ls;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
#ifdef BUC60823
|
|
#define GPRECIS 0.000001
|
|
Tint TelGetPolygonNormal(tel_point pnts, Tint* indexs, Tint npnt, Tfloat *norm ) {
|
|
Tint status=0;
|
|
|
|
norm[0] = norm[1] = norm[2] = 0.;
|
|
if( npnt > 2 ) {
|
|
Tfloat a[3], b[3], c[3];
|
|
Tint i,j,i0,ii=0,jj;
|
|
|
|
i0 = 0; if( indexs ) i0 = indexs[0];
|
|
for( i=1 ; i<npnt ; i++ ) {
|
|
ii = i; if( indexs ) ii = indexs[i];
|
|
vecsub( a, pnts[ii].xyz, pnts[i0].xyz );
|
|
if( vecmg2(a) > GPRECIS ) break;
|
|
}
|
|
if( i < npnt-1 ) {
|
|
for( j=i+1 ; j<npnt ; j++ ) {
|
|
jj = j; if( indexs ) jj = indexs[j];
|
|
vecsub( b, pnts[jj].xyz, pnts[i0].xyz );
|
|
vecsub( c, pnts[jj].xyz, pnts[ii].xyz );
|
|
if( (vecmg2(b) > GPRECIS) && (vecmg2(c) > GPRECIS) ) break;
|
|
}
|
|
if( j < npnt ) {
|
|
Tfloat d;
|
|
veccrs( norm, a, b );
|
|
d = vecnrmd( norm, d );
|
|
status = (d > 0.) ? 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
#ifdef DEB
|
|
if( !status )
|
|
printf(" *** OpenGl_TelGetPolygonNormal.has found confused or aligned points\n");
|
|
#endif
|
|
|
|
return status;
|
|
}
|
|
|
|
Tint TelGetNormal(Tfloat *data1, Tfloat *data2, Tfloat *data3, Tfloat *norm ) {
|
|
Tfloat a[3], b[3];
|
|
Tint status=0;
|
|
|
|
norm[0] = norm[1] = norm[2] = 0.;
|
|
vecsub( a, data2, data1 );
|
|
vecsub( b, data3, data2 );
|
|
if( (vecmg2(a) > GPRECIS) && (vecmg2(b) > GPRECIS) ) {
|
|
Tfloat d;
|
|
veccrs( norm, a, b );
|
|
d = vecnrmd( norm, d );
|
|
status = (d > 0.) ? 1 : 0;
|
|
}
|
|
#ifdef DEB
|
|
if( !status )
|
|
printf(" *** OpenGl_TelGetNormal.has found confused or aligned points\n");
|
|
#endif
|
|
|
|
return status;
|
|
}
|
|
#else
|
|
void
|
|
TelGetNormal(Tfloat *data1, Tfloat *data2, Tfloat *data3, Tfloat *norm ) {
|
|
Tfloat a[3], b[3];
|
|
|
|
vecsub( a, data2, data1 );
|
|
vecsub( b, data3, data2 );
|
|
veccrs( norm, a, b );
|
|
}
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
Tint
|
|
TelIsBackFace(Tmatrix3 n, Tfloat *nrm )
|
|
{
|
|
Tfloat r[4], m[4];
|
|
|
|
veccpy(m,nrm);
|
|
m[3] = ( float )1.0;
|
|
|
|
TelTranpt3( r, m, n );
|
|
|
|
return r[2] < 0.0;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelTransposemat3 (Tmatrix3 a)
|
|
{
|
|
Tint row, col;
|
|
Tmatrix3 res;
|
|
Tint dim = 4;
|
|
|
|
/* transposition de la sous-matrice dim x dim */
|
|
for (row = 0; row < dim; row++)
|
|
for (col = 0; col < dim; col++)
|
|
res[row][col] = a[col][row];
|
|
|
|
/* copie du resultat */
|
|
matcpy (a, res);
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelMultiplymat3 (Tmatrix3 c, Tmatrix3 a, Tmatrix3 b)
|
|
{
|
|
Tint row, col, i;
|
|
Tmatrix3 res;
|
|
Tint dim = 4;
|
|
|
|
/* on multiplie d'abord les 2 matrices dim x dim */
|
|
for (row = 0; row < dim; row++) {
|
|
for (col = 0; col < dim; col++) {
|
|
Tfloat sum = ( float )0.0;
|
|
for (i = 0; i < dim; i++)
|
|
sum += a[row][i] * b[i][col];
|
|
res[row][col] = sum;
|
|
}
|
|
}
|
|
|
|
/* on copie ensuite le resultat */
|
|
matcpy (c, res);
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelTranpt3(Tfloat tpt[4], Tfloat pt[4], Tmatrix3 mat )
|
|
{
|
|
register long i, j;
|
|
Tfloat sum;
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
for( j = 0, sum = ( float )0.0; j < 4; j++ )
|
|
{
|
|
sum += pt[j] * mat[j][i];
|
|
}
|
|
tpt[i] = sum;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelInitWS(Tint ws, Tint w, Tint h, Tfloat bgcolr, Tfloat bgcolg, Tfloat bgcolb )
|
|
{
|
|
CMN_KEY_DATA data;
|
|
|
|
TsmGetWSAttri( ws, WSDbuff, &data );
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glViewport( 0, 0, w, h);
|
|
|
|
/*
|
|
* CAL mai 1998
|
|
* Contournement bug SGI sur Octane (PRO12899)
|
|
* Bavures de pixels lors de la copie de vue 3d
|
|
*/
|
|
glDisable (GL_SCISSOR_TEST);
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelInitWS: glClearColor %d \n", ws);
|
|
#endif
|
|
if( data.ldata == TOn )
|
|
{
|
|
#ifndef WNT
|
|
if (TelTestPixmapDB())
|
|
{
|
|
glDrawBuffer(GL_FRONT);
|
|
glClearColor(bgcolr, bgcolg, bgcolb, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
else
|
|
{
|
|
/* QTOCC_PATCH by PCD: the frame buffer should not be cleared here
|
|
to avoid flicker. It is cleared properly in TelClearViews()
|
|
called by call_func_redraw_all_structs_begin() */
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
#else
|
|
/* QTOCC_PATCH by PCD: the frame buffer should not be cleared here
|
|
to avoid flicker. It is cleared properly in TelClearViews()
|
|
called by call_func_redraw_all_structs_begin() */
|
|
glDrawBuffer(GL_BACK);
|
|
#endif /* WNT */
|
|
}
|
|
else
|
|
{
|
|
glClearColor(bgcolr, bgcolg, bgcolb, ( float )1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void TelSwapBuffers ( Tint ws ) {
|
|
|
|
#ifndef WNT
|
|
|
|
CMN_KEY_DATA data;
|
|
|
|
if (TelTestPixmapDB())
|
|
{
|
|
glFlush();
|
|
XCopyArea(call_thedisplay, pixmap_id, window_id,
|
|
window_gc, 0, 0,
|
|
window_width, window_height, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
TsmGetWSAttri( ws, WSWindow, &data );
|
|
glXSwapBuffers ( call_thedisplay, data.ldata );
|
|
}
|
|
|
|
#else
|
|
|
|
SwapBuffers ( wglGetCurrentDC () );
|
|
TelFlush(0);
|
|
|
|
#endif /* WNT */
|
|
|
|
TelSetBackBufferRestored (TOff);
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelSwapBuffers: glXSwapBuffers %d \n", ws);
|
|
#endif
|
|
|
|
return;
|
|
|
|
} /* end TelSwapBuffers */
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
Tint
|
|
TelBackBufferRestored ()
|
|
{
|
|
return call_back_buffer_restored;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelSetBackBufferRestored (Tint flag)
|
|
{
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelSetBackBufferRestored(%d): \n",flag);
|
|
#endif
|
|
call_back_buffer_restored = flag;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelCopyBuffers(Tint ws, GLenum from, GLenum to,
|
|
Tfloat xm, Tfloat ym, Tfloat zm, Tfloat XM, Tfloat YM, Tfloat ZM, Tint flag)
|
|
{
|
|
CMN_KEY_DATA key;
|
|
Tint w, h;
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelCopyBuffers: \n");
|
|
#endif
|
|
|
|
if (to == GL_BACK) TelSetBackBufferRestored (TOff);
|
|
|
|
#ifndef WNT
|
|
if (TelTestPixmapDB())
|
|
{
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelSwapBuffers: glFlush \n");
|
|
#endif
|
|
glFlush();
|
|
XCopyArea(window_display, pixmap_id, window_id,
|
|
window_gc, 0, 0,
|
|
window_width, window_height, 0, 0);
|
|
return;
|
|
}
|
|
#endif /* WNT */
|
|
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glPushMatrix ();
|
|
glLoadIdentity ();
|
|
gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glPushMatrix ();
|
|
glLoadIdentity ();
|
|
|
|
TelDisable (ws);
|
|
if (flag)
|
|
{
|
|
/*
|
|
* calcul de la projection de la boite
|
|
* et copie du rectangle projete
|
|
*/
|
|
Tint i;
|
|
GLsizei width, height;
|
|
Tfloat xmr, ymr, XMR, YMR;
|
|
Tfloat xr[8], yr[8];
|
|
/*
|
|
* Projection de la boite englobante
|
|
*/
|
|
if ((TelProjectionRaster (ws, xm, ym, zm, &xr[0], &yr[0]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, xm, YM, zm, &xr[1], &yr[1]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, XM, YM, zm, &xr[2], &yr[2]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, XM, ym, zm, &xr[3], &yr[3]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, xm, ym, ZM, &xr[4], &yr[4]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, xm, YM, ZM, &xr[5], &yr[5]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, XM, YM, ZM, &xr[6], &yr[6]) == TSuccess)
|
|
&& (TelProjectionRaster (ws, XM, ym, ZM, &xr[7], &yr[7]) == TSuccess))
|
|
{
|
|
xmr = ymr = (float ) shortreallast ();
|
|
XMR = YMR = (float ) shortrealfirst ();
|
|
/*
|
|
* Recherche du rectangle projete
|
|
*/
|
|
for (i=0; i<8; i++) {
|
|
if (xmr > xr[i]) xmr = xr[i];
|
|
if (ymr > yr[i]) ymr = yr[i];
|
|
if (XMR < xr[i]) XMR = xr[i];
|
|
if (YMR < yr[i]) YMR = yr[i];
|
|
}
|
|
/* pour eviter les bavures de pixels ! */
|
|
xmr--;ymr--;
|
|
XMR++;YMR++;
|
|
|
|
/*
|
|
* Ajout CAL : 10/05/96
|
|
* Si les MinMax viennent d'un ensemble de markers
|
|
* on ne tient pas compte du scale factor de ceux-ci
|
|
* dans les valeurs de MinMax. En effet, ce facteur
|
|
* est dans l'espace pixel et les MinMax dans l'espace
|
|
* du modele. Donc ajout d'un delta de pixels
|
|
* en esperant que les applis n'utilisent pas des
|
|
* markers tres gros !
|
|
*/
|
|
xmr -= CALL_DEF_DELTA; ymr -= CALL_DEF_DELTA;
|
|
XMR += CALL_DEF_DELTA; YMR += CALL_DEF_DELTA;
|
|
|
|
/*
|
|
* Le rectangle projete peut-etre clippe
|
|
*/
|
|
width = (GLsizei) (XMR-xmr+1);
|
|
height = (GLsizei) (YMR-ymr+1);
|
|
#ifdef COPYBUFFER
|
|
printf ("avant clipping\n");
|
|
printf ("xm, ym, zm : %f, %f, %f\n", xm, ym, zm);
|
|
printf ("XM, YM, ZM : %f, %f, %f\n", XM, YM, ZM);
|
|
printf ("taille fenetre : %d, %d\n", w, h);
|
|
printf ("xmr, ymr by GLU : %f, %f\n", xmr, ymr);
|
|
printf ("YMR, YMR by GLU : %f, %f\n", XMR, YMR);
|
|
printf ("copie x, y, dx, dy : %d, %d, %d, %d\n\n",
|
|
(int) xmr, (int) ymr, (int) width, (int) height);
|
|
#endif
|
|
/*
|
|
* (xmr,ymr) coin inferieur gauche
|
|
* (XMR,YMR) coin superieur droit
|
|
*/
|
|
/* cas ou 1 coin est en dehors de la fenetre */
|
|
if (xmr < 0) { width = (GLsizei) (XMR+1); xmr = 0; }
|
|
if (ymr < 0) { height = (GLsizei) (YMR+1); ymr = 0; }
|
|
if (XMR > w) { width = (GLsizei) (w-xmr+1); }
|
|
if (YMR > h) { height = (GLsizei) (h-ymr+1); }
|
|
|
|
/* cas ou les 2 coins sont en dehors de la fenetre */
|
|
if (XMR < 0) { xmr = 0; width = height = 1; }
|
|
if (YMR < 0) { ymr = 0; width = height = 1; }
|
|
if (xmr > w) { xmr = 0; width = height = 1; }
|
|
if (ymr > h) { ymr = 0; width = height = 1; }
|
|
#ifdef COPYBUFFER
|
|
printf ("apres clipping\n");
|
|
printf ("xmr, ymr by GLU : %f, %f\n", xmr, ymr);
|
|
printf ("YMR, YMR by GLU : %f, %f\n", XMR, YMR);
|
|
printf ("copie x, y, dx, dy : %d, %d, %d, %d\n\n",
|
|
(int) xmr, (int) ymr, (int) width, (int) height);
|
|
#endif
|
|
glDrawBuffer (to);
|
|
glReadBuffer (from);
|
|
/* copie partielle */
|
|
glRasterPos2i ((GLint) xmr, (GLint) ymr);
|
|
glCopyPixels ((GLint) xmr, (GLint) ymr, width, height, GL_COLOR);
|
|
/* TelFlush (1); */
|
|
}
|
|
else
|
|
{
|
|
glDrawBuffer (to);
|
|
/* TelClearViews (ws); */
|
|
glReadBuffer (from);
|
|
/* copie complete */
|
|
glRasterPos2i (0, 0);
|
|
glCopyPixels (0, 0, w+1, h+1, GL_COLOR);
|
|
/* TelFlush (1); */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
glDrawBuffer (to);
|
|
/* TelClearViews (ws); */
|
|
glReadBuffer (from);
|
|
/* copie complete */
|
|
glRasterPos2i (0, 0);
|
|
glCopyPixels (0, 0, w+1, h+1, GL_COLOR);
|
|
/* TelFlush (1); */
|
|
}
|
|
TelEnable (ws);
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glPopMatrix ();
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glPopMatrix ();
|
|
|
|
glDrawBuffer (GL_BACK);
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelReadImage(Tint ws, GLenum from, Tint posx, Tint posy, Tint width, Tint height, unsigned int *image)
|
|
{
|
|
CMN_KEY_DATA key;
|
|
Tint w, h;
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelReadImage: %d %d %d %d \n", posx, posy, width, height);
|
|
#endif
|
|
|
|
if (image !=NULL)
|
|
{
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glLoadIdentity ();
|
|
gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glLoadIdentity ();
|
|
|
|
glReadBuffer(from);
|
|
|
|
glRasterPos2i (posx, posy);
|
|
TelDisable (ws);
|
|
glReadPixels (posx, posy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
|
TelEnable (ws);
|
|
|
|
glReadBuffer(GL_BACK);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelDrawImage(Tint ws, GLenum to, Tint posx, Tint posy, Tint width, Tint height, unsigned int *image)
|
|
{
|
|
CMN_KEY_DATA key;
|
|
Tint w, h;
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelDrawImage: %d %d %d %d \n", posx, posy, width, height);
|
|
#endif
|
|
|
|
if (image !=NULL)
|
|
{
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glLoadIdentity ();
|
|
gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glLoadIdentity ();
|
|
|
|
glDrawBuffer(to);
|
|
|
|
glRasterPos2i (posx, posy);
|
|
TelDisable (ws);
|
|
glDrawPixels (width, height, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
|
TelEnable (ws);
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelReadDepths(Tint ws, Tint posx, Tint posy, Tint width, Tint height, float *depths)
|
|
{
|
|
CMN_KEY_DATA key;
|
|
Tint w, h;
|
|
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelReadDepths: %d %d %d %d \n", posx, posy, width, height);
|
|
#endif
|
|
|
|
if ( TsmGetWSAttri (ws, WSWindow, &key) != TSuccess ) return;
|
|
|
|
if (depths != NULL && TxglWinset (call_thedisplay, (WINDOW) key.ldata) == TSuccess)
|
|
{
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glLoadIdentity ();
|
|
gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glLoadIdentity ();
|
|
|
|
glRasterPos2i (posx, posy);
|
|
TelDisable (ws);
|
|
glReadPixels (posx, posy, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
|
|
TelEnable (ws);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelEnable (Tint ws)
|
|
{
|
|
/*glPixelTransferi (GL_MAP_COLOR, GL_TRUE);*/
|
|
|
|
/* GL_DITHER on/off pour le trace */
|
|
if (TxglGetDither())
|
|
glEnable (GL_DITHER);
|
|
else
|
|
glDisable (GL_DITHER);
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelDisable (Tint ws)
|
|
{
|
|
glDisable (GL_DITHER);
|
|
glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
|
|
|
|
/*
|
|
* Disable stuff that's likely to slow down glDrawPixels.
|
|
* (Omit as much of this as possible, when you know in advance
|
|
* that the OpenGL state will already be set correctly.)
|
|
*/
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_FOG);
|
|
LightOff();
|
|
|
|
glDisable(GL_LOGIC_OP);
|
|
glDisable(GL_STENCIL_TEST);
|
|
glDisable(GL_TEXTURE_1D);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
|
|
glPixelTransferi(GL_RED_SCALE, 1);
|
|
glPixelTransferi(GL_RED_BIAS, 0);
|
|
glPixelTransferi(GL_GREEN_SCALE, 1);
|
|
glPixelTransferi(GL_GREEN_BIAS, 0);
|
|
glPixelTransferi(GL_BLUE_SCALE, 1);
|
|
glPixelTransferi(GL_BLUE_BIAS, 0);
|
|
glPixelTransferi(GL_ALPHA_SCALE, 1);
|
|
glPixelTransferi(GL_ALPHA_BIAS, 0);
|
|
|
|
/*
|
|
* Disable extensions that could slow down glDrawPixels.
|
|
* (Actually, you should check for the presence of the proper
|
|
* extension before making these calls. I've omitted that
|
|
* code for simplicity.)
|
|
*/
|
|
|
|
#ifdef GL_EXT_convolution
|
|
glDisable(GL_CONVOLUTION_1D_EXT);
|
|
glDisable(GL_CONVOLUTION_2D_EXT);
|
|
glDisable(GL_SEPARABLE_2D_EXT);
|
|
#endif
|
|
|
|
#ifdef GL_EXT_histogram
|
|
glDisable(GL_HISTOGRAM_EXT);
|
|
glDisable(GL_MINMAX_EXT);
|
|
#endif
|
|
|
|
#ifdef GL_EXT_texture3D
|
|
glDisable(GL_TEXTURE_3D_EXT);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
TStatus
|
|
TelProjectionRaster(Tint ws, Tfloat x, Tfloat y, Tfloat z, Tfloat *xr, Tfloat *yr)
|
|
{
|
|
Tint w, h;
|
|
CMN_KEY_DATA key;
|
|
Tint vid; /* View index */
|
|
TEL_VIEW_REP vrep; /* View definition */
|
|
|
|
GLint status;
|
|
|
|
int i, j, k;
|
|
GLdouble objx, objy, objz;
|
|
GLdouble modelMatrix[16], projMatrix[16];
|
|
GLint viewport[4];
|
|
GLdouble winx, winy, winz;
|
|
|
|
vid = ws;
|
|
|
|
if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
|
|
return TFailure;
|
|
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
objx = ( GLdouble )x; objy = ( GLdouble )y; objz = ( GLdouble )z;
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
|
|
|
|
viewport[0] = 0;
|
|
viewport[1] = 0;
|
|
viewport[2] = w;
|
|
viewport[3] = h;
|
|
|
|
/*
|
|
* glGetIntegerv (GL_VIEWPORT, viewport);
|
|
* glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
|
|
* glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
|
|
*/
|
|
|
|
status = gluProject (objx, objy, objz,
|
|
modelMatrix, projMatrix, viewport,
|
|
&winx, &winy, &winz);
|
|
|
|
if (status == GL_TRUE) {
|
|
*xr = ( Tfloat )winx;
|
|
*yr = ( Tfloat )winy;
|
|
return TSuccess;
|
|
}
|
|
else
|
|
{
|
|
*xr = 0.0F;
|
|
*yr = 0.0F;
|
|
return TFailure;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
TStatus
|
|
TelUnProjectionRaster(Tint ws, Tint xr, Tint yr, Tfloat *x, Tfloat *y, Tfloat *z)
|
|
{
|
|
Tint w, h;
|
|
CMN_KEY_DATA key;
|
|
Tint vid; /* View index */
|
|
TEL_VIEW_REP vrep; /* View definition */
|
|
|
|
int i, j, k;
|
|
GLdouble objx, objy, objz;
|
|
GLdouble modelMatrix[16], projMatrix[16];
|
|
GLint viewport[4];
|
|
GLdouble winx, winy, winz;
|
|
GLint status;
|
|
|
|
vid = ws;
|
|
|
|
if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
|
|
return TFailure;
|
|
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
winx = ( GLdouble )xr; winy = ( GLdouble )yr; winz = ( GLdouble )0.0;
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
|
|
|
|
viewport[0] = 0;
|
|
viewport[1] = 0;
|
|
viewport[2] = w;
|
|
viewport[3] = h;
|
|
|
|
/*
|
|
* glGetIntegerv (GL_VIEWPORT, viewport);
|
|
* glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
|
|
* glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
|
|
*/
|
|
|
|
status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
|
|
&objx, &objy, &objz);
|
|
|
|
if (status == GL_TRUE) {
|
|
*x = ( Tfloat )objx;
|
|
*y = ( Tfloat )objy;
|
|
*z = ( Tfloat )objz;
|
|
|
|
return TSuccess;
|
|
}
|
|
else {
|
|
*x = 0.0F;
|
|
*y = 0.0F;
|
|
*z = 0.0F;
|
|
|
|
return TFailure;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
TStatus
|
|
TelUnProjectionRasterWithRay(Tint ws, Tint xr, Tint yr, Tfloat *x, Tfloat *y, Tfloat *z,
|
|
Tfloat *dx, Tfloat *dy, Tfloat *dz)
|
|
{
|
|
Tint w, h;
|
|
CMN_KEY_DATA key;
|
|
Tint vid; /* View index */
|
|
TEL_VIEW_REP vrep; /* View definition */
|
|
|
|
int i, j, k;
|
|
GLdouble objx, objy, objz;
|
|
GLdouble objx1, objy1, objz1;
|
|
GLdouble modelMatrix[16], projMatrix[16];
|
|
GLint viewport[4];
|
|
GLdouble winx, winy, winz;
|
|
GLint status;
|
|
|
|
vid = ws;
|
|
|
|
if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
|
|
return TFailure;
|
|
|
|
TsmGetWSAttri (ws, WSWidth, &key);
|
|
w = key.ldata;
|
|
TsmGetWSAttri (ws, WSHeight, &key);
|
|
h = key.ldata;
|
|
|
|
winx = ( GLdouble )xr; winy = ( GLdouble )yr; winz = ( GLdouble )0.0;
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
|
|
|
|
for (k = 0, i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++, k++)
|
|
projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
|
|
|
|
viewport[0] = 0;
|
|
viewport[1] = 0;
|
|
viewport[2] = w;
|
|
viewport[3] = h;
|
|
|
|
/*
|
|
* glGetIntegerv (GL_VIEWPORT, viewport);
|
|
* glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
|
|
* glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
|
|
*/
|
|
|
|
status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
|
|
&objx, &objy, &objz);
|
|
|
|
if (status == GL_TRUE) {
|
|
*x = ( Tfloat )objx;
|
|
*y = ( Tfloat )objy;
|
|
*z = ( Tfloat )objz;
|
|
|
|
winz = ( GLdouble ) -10.0;
|
|
status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
|
|
&objx1, &objy1, &objz1);
|
|
|
|
if (status == GL_TRUE) {
|
|
*dx = ( Tfloat )(objx-objx1);
|
|
*dy = ( Tfloat )(objy-objy1);
|
|
*dz = ( Tfloat )(objz-objz1);
|
|
|
|
return TSuccess;
|
|
}
|
|
else {
|
|
*dx = 0.0F;
|
|
*dy = 0.0F;
|
|
*dz = 0.0F;
|
|
|
|
return TFailure;
|
|
}
|
|
}
|
|
else {
|
|
*x = 0.0F;
|
|
*y = 0.0F;
|
|
*z = 0.0F;
|
|
*dx = 0.0F;
|
|
*dy = 0.0F;
|
|
*dz = 0.0F;
|
|
|
|
return TFailure;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
TelFlush(Tint wait)
|
|
{
|
|
if (wait)
|
|
{
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelFlush: glFinish \n");
|
|
#endif
|
|
glFinish ();
|
|
}
|
|
else
|
|
{
|
|
#ifdef TRACE
|
|
printf("OPENGL: TelFlush: glFlush \n");
|
|
#endif
|
|
glFlush();
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
Tint
|
|
TelIsBackFacePerspective(Tmatrix3 n, Tfloat *p1, Tfloat *p2, Tfloat *p3 )
|
|
{
|
|
Tfloat r1[4], r2[4], r3[4], m[4], norm[4];
|
|
|
|
veccpy( m, p1 );
|
|
m[3] = ( float )1.0;
|
|
TelTranpt3( r1, m, n );
|
|
r1[0] /= r1[3];
|
|
r1[1] /= r1[3];
|
|
r1[2] /= r1[3];
|
|
|
|
veccpy( m, p2 );
|
|
m[3] = ( float )1.0;
|
|
TelTranpt3( r2, m, n );
|
|
r2[0] /= r2[3];
|
|
r2[1] /= r2[3];
|
|
r2[2] /= r2[3];
|
|
|
|
veccpy( m, p3 );
|
|
m[3] = ( float )1.0;
|
|
TelTranpt3( r3, m, n );
|
|
r3[0] /= r3[3];
|
|
r3[1] /= r3[3];
|
|
r3[2] /= r3[3];
|
|
TelGetNormal( r1, r2, r3, norm );
|
|
|
|
return norm[2] < 0.0;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|