534 lines
9.9 KiB
C
534 lines
9.9 KiB
C
/* ***************************************
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
|
|
|
|
|
|
raddisplay.c nov/dec 1992
|
|
may 1999
|
|
|
|
- drawing
|
|
- color calculation for display during solving
|
|
|
|
$Id$
|
|
|
|
*************************************** */
|
|
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_view3d_types.h"
|
|
|
|
#include "BKE_global.h"
|
|
#include "BKE_main.h"
|
|
|
|
#include "BIF_gl.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_space.h"
|
|
#include "BIF_mywindow.h"
|
|
|
|
#include "BSE_view.h"
|
|
|
|
#include "radio.h"
|
|
|
|
/* cpack has to be endian-insensitive! (old irisgl function) */
|
|
#define cpack(x) glColor3ub( ((x)&0xFF), (((x)>>8)&0xFF), (((x)>>16)&0xFF) )
|
|
|
|
char calculatecolor(float col)
|
|
{
|
|
int b;
|
|
|
|
if(RG.gamma==1.0) {
|
|
b= RG.radfactor*col;
|
|
}
|
|
else if(RG.gamma==2.0) {
|
|
b= RG.radfactor*sqrt(col);
|
|
}
|
|
else {
|
|
b= RG.radfactor*pow(col, RG.igamma);
|
|
}
|
|
|
|
if(b>255) b=255;
|
|
return b;
|
|
}
|
|
|
|
void make_node_display()
|
|
{
|
|
RNode *rn, **el;
|
|
int a;
|
|
char *charcol;
|
|
|
|
RG.igamma= 1.0/RG.gamma;
|
|
RG.radfactor= RG.radfac*pow(64*64, RG.igamma);
|
|
|
|
el= RG.elem;
|
|
for(a=RG.totelem; a>0; a--, el++) {
|
|
rn= *el;
|
|
charcol= (char *)&( rn->col );
|
|
|
|
charcol[3]= calculatecolor(rn->totrad[0]);
|
|
charcol[2]= calculatecolor(rn->totrad[1]);
|
|
charcol[1]= calculatecolor(rn->totrad[2]);
|
|
|
|
/* gouraudcolor */
|
|
*(rn->v1+3)= 0;
|
|
*(rn->v2+3)= 0;
|
|
*(rn->v3+3)= 0;
|
|
if(rn->v4) *(rn->v4+3)= 0;
|
|
}
|
|
|
|
el= RG.elem;
|
|
for(a=RG.totelem; a>0; a--, el++) {
|
|
rn= *el;
|
|
addaccuweight( (char *)&(rn->col), (char *)(rn->v1+3), 16 );
|
|
addaccuweight( (char *)&(rn->col), (char *)(rn->v2+3), 16 );
|
|
addaccuweight( (char *)&(rn->col), (char *)(rn->v3+3), 16 );
|
|
if(rn->v4) addaccuweight( (char *)&(rn->col), (char *)(rn->v4+3), 16 );
|
|
}
|
|
}
|
|
|
|
void drawnodeWire(RNode *rn)
|
|
{
|
|
|
|
if(rn->down1) {
|
|
drawnodeWire(rn->down1);
|
|
drawnodeWire(rn->down2);
|
|
}
|
|
else {
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(rn->v1);
|
|
glVertex3fv(rn->v2);
|
|
glVertex3fv(rn->v3);
|
|
if(rn->type==4) glVertex3fv(rn->v4);
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
void drawsingnodeWire(RNode *rn)
|
|
{
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(rn->v1);
|
|
glVertex3fv(rn->v2);
|
|
glVertex3fv(rn->v3);
|
|
if(rn->type==4) glVertex3fv(rn->v4);
|
|
glEnd();
|
|
}
|
|
|
|
void drawnodeSolid(RNode *rn)
|
|
{
|
|
char *cp;
|
|
|
|
if(rn->down1) {
|
|
drawnodeSolid(rn->down1);
|
|
drawnodeSolid(rn->down2);
|
|
}
|
|
else {
|
|
cp= (char *)&rn->col;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glBegin(GL_POLYGON);
|
|
glVertex3fv(rn->v1);
|
|
glVertex3fv(rn->v2);
|
|
glVertex3fv(rn->v3);
|
|
if(rn->type==4) glVertex3fv(rn->v4);
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
void drawnodeGour(RNode *rn)
|
|
{
|
|
char *cp;
|
|
|
|
if(rn->down1) {
|
|
drawnodeGour(rn->down1);
|
|
drawnodeGour(rn->down2);
|
|
}
|
|
else {
|
|
glBegin(GL_POLYGON);
|
|
cp= (char *)(rn->v1+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(rn->v1);
|
|
|
|
cp= (char *)(rn->v2+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(rn->v2);
|
|
|
|
cp= (char *)(rn->v3+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(rn->v3);
|
|
|
|
if(rn->type==4) {
|
|
cp= (char *)(rn->v4+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(rn->v4);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
void drawpatch_ext(RPatch *patch, unsigned int col)
|
|
{
|
|
ScrArea *sa, *oldsa;
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
cpack(col);
|
|
|
|
oldsa= curarea;
|
|
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if (sa->spacetype==SPACE_VIEW3D) {
|
|
/* use mywinget() here: otherwise it draws in header */
|
|
if(sa->win != mywinget()) areawinset(sa->win);
|
|
persp(PERSP_VIEW);
|
|
drawnodeWire(patch->first);
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
|
|
if(oldsa && oldsa!=curarea) areawinset(oldsa->win);
|
|
|
|
glFlush();
|
|
glDrawBuffer(GL_BACK);
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
void drawnode_ext(RNode *rn, unsigned int col)
|
|
{
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
cpack(col);
|
|
|
|
drawnodeWire(rn);
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
void drawOverflowElem()
|
|
{
|
|
RNode **el, *rn;
|
|
float *fp;
|
|
int a;
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
cpack(0xFF9900);
|
|
|
|
el= RG.elem;
|
|
fp= RG.formfactors;
|
|
for(a=0; a<RG.totelem; a++, el++, fp++) {
|
|
if(*fp>1.0) {
|
|
rn= *el;
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv( rn->v1);
|
|
glVertex3fv( rn->v2);
|
|
glVertex3fv( rn->v3);
|
|
if(rn->type==4) glVertex3fv( rn->v4);
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
void drawfaceGour(Face *face)
|
|
{
|
|
char *cp;
|
|
|
|
glBegin(GL_POLYGON);
|
|
cp= (char *)(face->v1+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(face->v1);
|
|
|
|
cp= (char *)(face->v2+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(face->v2);
|
|
|
|
cp= (char *)(face->v3+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(face->v3);
|
|
|
|
if(face->v4) {
|
|
cp= (char *)(face->v4+3);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(face->v4);
|
|
}
|
|
glEnd();
|
|
|
|
}
|
|
|
|
void drawfaceSolid(Face *face)
|
|
{
|
|
char *cp;
|
|
|
|
cp= (char *)&face->col;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glBegin(GL_POLYGON);
|
|
glVertex3fv(face->v1);
|
|
glVertex3fv(face->v2);
|
|
glVertex3fv(face->v3);
|
|
if(face->v4) {
|
|
glVertex3fv(face->v4);
|
|
}
|
|
glEnd();
|
|
|
|
}
|
|
|
|
void drawfaceWire(Face *face)
|
|
{
|
|
char *cp;
|
|
|
|
cp= (char *)&face->col;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(face->v1);
|
|
glVertex3fv(face->v2);
|
|
glVertex3fv(face->v3);
|
|
if(face->v4) {
|
|
glVertex3fv(face->v4);
|
|
}
|
|
glEnd();
|
|
|
|
}
|
|
|
|
void drawsquare(float *cent, float size, short cox, short coy)
|
|
{
|
|
float vec[3];
|
|
|
|
vec[0]= cent[0];
|
|
vec[1]= cent[1];
|
|
vec[2]= cent[2];
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
vec[cox]+= .5*size;
|
|
vec[coy]+= .5*size;
|
|
glVertex3fv(vec);
|
|
vec[coy]-= size;
|
|
glVertex3fv(vec);
|
|
vec[cox]-= size;
|
|
glVertex3fv(vec);
|
|
vec[coy]+= size;
|
|
glVertex3fv(vec);
|
|
glEnd();
|
|
}
|
|
|
|
void drawlimits()
|
|
{
|
|
/* centre around cent */
|
|
short cox=0, coy=1;
|
|
|
|
if((RG.flag & 3)==2) coy= 2;
|
|
if((RG.flag & 3)==3) {
|
|
cox= 1;
|
|
coy= 2;
|
|
}
|
|
|
|
cpack(0);
|
|
drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy);
|
|
drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy);
|
|
|
|
drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy);
|
|
drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy);
|
|
|
|
cpack(0xFFFFFF);
|
|
drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy);
|
|
drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy);
|
|
cpack(0xFFFF00);
|
|
drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy);
|
|
drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy);
|
|
|
|
}
|
|
|
|
void setcolNode(RNode *rn, unsigned int *col)
|
|
{
|
|
|
|
if(rn->down1) {
|
|
setcolNode(rn->down1, col);
|
|
setcolNode(rn->down2, col);
|
|
}
|
|
rn->col= *col;
|
|
|
|
*((unsigned int *)rn->v1+3)= *col;
|
|
*((unsigned int *)rn->v2+3)= *col;
|
|
*((unsigned int *)rn->v3+3)= *col;
|
|
if(rn->v4) *((unsigned int *)rn->v4+3)= *col;
|
|
}
|
|
|
|
void pseudoAmb()
|
|
{
|
|
RPatch *rp;
|
|
float fac;
|
|
char col[4];
|
|
|
|
/* sets pseudo ambient color in the nodes */
|
|
|
|
rp= RG.patchbase.first;
|
|
while(rp) {
|
|
|
|
if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) {
|
|
col[1]= col[2]= col[3]= 255;
|
|
}
|
|
else {
|
|
fac= rp->norm[0]+ rp->norm[1]+ rp->norm[2];
|
|
fac= 225.0*(3+fac)/6.0;
|
|
|
|
col[3]= fac*rp->ref[0];
|
|
col[2]= fac*rp->ref[1];
|
|
col[1]= fac*rp->ref[2];
|
|
}
|
|
|
|
setcolNode(rp->first, (unsigned int *)col);
|
|
|
|
rp= rp->next;
|
|
}
|
|
}
|
|
|
|
void RAD_drawall(int depth_is_on)
|
|
{
|
|
/* displays elements or faces */
|
|
Face *face = NULL;
|
|
RNode **el;
|
|
RPatch *rp;
|
|
int a;
|
|
|
|
if(!depth_is_on) {
|
|
glEnable(GL_DEPTH_TEST);
|
|
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
if(RG.totface) {
|
|
if(RG.drawtype==DTGOUR) {
|
|
glShadeModel(GL_SMOOTH);
|
|
for(a=0; a<RG.totface; a++) {
|
|
RAD_NEXTFACE(a);
|
|
|
|
drawfaceGour(face);
|
|
}
|
|
}
|
|
else if(RG.drawtype==DTSOLID) {
|
|
for(a=0; a<RG.totface; a++) {
|
|
RAD_NEXTFACE(a);
|
|
|
|
drawfaceSolid(face);
|
|
}
|
|
}
|
|
else {
|
|
if(!(get_qual()&LR_SHIFTKEY)) {
|
|
|
|
for(a=0; a<RG.totface; a++) {
|
|
RAD_NEXTFACE(a);
|
|
|
|
drawfaceWire(face);
|
|
}
|
|
}
|
|
else {
|
|
cpack(0);
|
|
rp= RG.patchbase.first;
|
|
while(rp) {
|
|
drawsingnodeWire(rp->first);
|
|
rp= rp->next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
el= RG.elem;
|
|
if(RG.drawtype==DTGOUR) {
|
|
glShadeModel(GL_SMOOTH);
|
|
for(a=RG.totelem; a>0; a--, el++) {
|
|
drawnodeGour(*el);
|
|
}
|
|
}
|
|
else if(RG.drawtype==DTSOLID) {
|
|
for(a=RG.totelem; a>0; a--, el++) {
|
|
drawnodeSolid(*el);
|
|
}
|
|
}
|
|
else {
|
|
cpack(0);
|
|
for(a=RG.totelem; a>0; a--, el++) {
|
|
drawnodeWire(*el);
|
|
}
|
|
}
|
|
}
|
|
glShadeModel(GL_FLAT);
|
|
|
|
if(RG.totpatch) {
|
|
if(RG.flag & 3) {
|
|
if(depth_is_on) glDisable(GL_DEPTH_TEST);
|
|
drawlimits();
|
|
if(depth_is_on) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
if(!depth_is_on) {
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
|
|
void rad_forcedraw()
|
|
{
|
|
ScrArea *sa, *oldsa;
|
|
|
|
oldsa= curarea;
|
|
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if (sa->spacetype==SPACE_VIEW3D) {
|
|
/* use mywinget() here: othwerwise it draws in header */
|
|
if(sa->win != mywinget()) areawinset(sa->win);
|
|
scrarea_do_windraw(sa);
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
screen_swapbuffers();
|
|
|
|
if(oldsa && oldsa!=curarea) areawinset(oldsa->win);
|
|
}
|
|
|