This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/radiosity/intern/source/raddisplay.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);
}