class DPoly | .h |
constructor | DPoly() |
destructor | ~DPoly() |
Define | void Define(int nPoints,DPolyPoint *pts) |
DefinePoint | void DefinePoint(int n,DPolyPoint *p) |
MoveRelative | void MoveRelative(dfloat x,dfloat y,dfloat z) Move all points relative to current position |
GetWidth | dfloat GetWidth() |
GetHeight | dfloat GetHeight() |
Disable | void Disable(int _flags) |
Enable | void Enable(int _flags) |
SetBlendMode | void SetBlendMode(int mode) |
SetOpacity | void SetOpacity(dfloat opa) Set opacity (0..1?) |
Paint | void Paint() Assumptions: - Modelview/projection is set up - OpenGL context is valid and set up |
DefineTexture | void DefineTexture(DTexture *t,QRect *r,int rotateCount,int mirrorFlags) Define a portion of the texture as this poly's texturemap 'rotateCount' indicates the number of 90 degree rotations you want to apply before applying the texture map to the polygon. This way you can specify the orientation of the tmap on the polygon. 'mirrorFlags' specifies X and Y reversal; &1 = mirror X, &2=mirror Y Mirroring is done BEFORE rotateCount is applied (!). Works for 3 and 4-point polygons. FUTURE: mirror tmap X/Y |
SetWidth | void SetWidth(dfloat w) Modifies a polygon that has a shape such that every point to the right of the leftmost point will be set to 'w' X-distance of that leftmost point. Practical use: rectangular polygons width setting. |
SetHeight | void SetHeight(dfloat h) OLD Modifies a polygon that has a shape such that every point to the right of the leftmost point will be set to 'w' X-distance of that leftmost point. Practical use: rectangular polygons width setting. |
/*
* DPoly - definition/implementation
* 19-02-99: Created!
* 02-12-99: Opacity support.
* NOTES:
* - Generated by mkclass
* (C) 19-02-1999 (17:36) MarketGraph/RVG
*/
#include <d3/poly.h>
#include <GL/gl.h>
#include <qlib/debug.h>
DEBUG_ENABLE
DPoly::DPoly()
{
texture=0;
point=0;
points=0;
// Default is no blending, no culling
flags=0;
blendMode=BLEND_OFF;
opacity=1.0;
}
DPoly::~DPoly()
{
if(point)qfree(point);
}
/***********
* GEOMETRY *
***********/
void DPoly::Define(int nPoints,DPolyPoint *pts)
{
points=nPoints;
point=(DPolyPoint*)qcalloc(nPoints*sizeof(DPolyPoint));
if(!point)qwarn("DPoly::Define(); out of memory");
}
void DPoly::DefinePoint(int n,DPolyPoint *p)
{
point[n]=*p;
}
void DPoly::MoveRelative(dfloat x,dfloat y,dfloat z)
// Move all points relative to current position
{
int i;
for(i=0;i<points;i++)
{ point[i].x+=x;
point[i].y+=y;
point[i].z+=z;
}
}
dfloat DPoly::GetWidth()
{
int minX,maxX;
int i;
if(!points)return 0;
minX=maxX=point[0].x;
for(i=0;i<points;i++)
{ if(point[i].x<minX)minX=point[i].x;
if(point[i].x>maxX)maxX=point[i].x;
}
return maxX-minX;
}
dfloat DPoly::GetHeight()
{
int minY,maxY;
int i;
if(!points)return 0;
minY=maxY=point[0].y;
for(i=0;i<points;i++)
{ if(point[i].y<minY)minY=point[i].y;
if(point[i].y>maxY)maxY=point[i].y;
}
return maxY-minY;
}
void DPoly::Disable(int _flags)
{
flags&=~_flags;
}
void DPoly::Enable(int _flags)
{
// Test for obsolete blend setting
if(_flags&1 /*BLEND*/ )
{ qwarn("DPoly:Enable: obsolete attempt to set blend mode using Enable");
}
flags|=_flags;
}
/********
* LOOKS *
********/
void DPoly::SetBlendMode(int mode)
{
blendMode=mode;
/*if(blendMode==BLEND_OFF)
flags&=~BLEND;*/
}
void DPoly::SetOpacity(dfloat opa)
// Set opacity (0..1?)
{ opacity=opa;
}
/********
* PAINT *
********/
void DPoly::Paint()
// Assumptions:
// - Modelview/projection is set up
// - OpenGL context is valid and set up
{
DPolyPoint *p;
int i;
//qdbg("DPoly:Paint; texture=%p %fx%f\n",texture,GetWidth(),GetHeight());
if(texture)
{ texture->Select();
glEnable(GL_TEXTURE_2D);
} else
{ glDisable(GL_TEXTURE_2D);
}
//qdbg("DPoly:Paint: flags=%d\n",flags);
if(blendMode==BLEND_SRC_ALPHA)
{ glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// Tests to mix texture with color fragments AND alpha from texture
// To modify the coloring AND alpha of the drawn polygon,
// use texture env mode GL_MODULATE and give the polygon
// a color (glColor4f).
// This will enable you to colorize the polygon, and to
// do an opacity effect by specifying a polygon color
// of black and alpha<1
#ifdef ND
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
#endif
// No idea yet how to use the texture env color practically
#ifdef ND
//GLfloat envColor[4]={ 1,1,1,1 /*.1,.4,.6,.5*/ };
//glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,envColor);
//glDisable(GL_TEXTURE_2D);
#endif
// To affect the coloring, but NOT the alpha (no opacity)
// use glBlendColorEXT() with alpha<1, and
// glBlendFunc(GL_CONSTANT_ALPHA_EXT,GL_ONE_MINUS_SRC_ALPHA)
// This will pull the colors to the constant blend color by alpha.
#ifdef ND
glBlendColorEXT(.1,.3,.5,.6);
glBlendColorEXT(1,1,1,.5);
//glBlendFunc(GL_CONSTANT_COLOR_EXT,GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_CONSTANT_ALPHA_EXT,GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_CONSTANT_ALPHA_EXT);
#endif
} else glDisable(GL_BLEND);
if(opacity!=1.0)
{
// Opacity can be reached in numerous ways; blending, texture modulation...
// A lot can be done with the blending/texturing hardware
// Here I modulate the texture color with a color with alpha<1
// Opacity works on blended and non-blended polygons (!)
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glColor4f(1,1,1,opacity);
} else
{
glColor4f(1,1,1,opacity);
}
if(flags&CULL)
{ glEnable(GL_CULL_FACE);
} else
{ glDisable(GL_CULL_FACE);
}
if(points==4)
{
glBegin(GL_QUADS);
for(i=0;i<points;i++)
{ p=&point[i];
if(texture)glTexCoord2f(p->tx,p->ty);
//glTexCoord2f(p->tx,p->ty);
//qdbg("pt %f,%f,%f tex %f,%f\n",p->x,p->y,p->z,p->tx,p->ty);
#ifdef ND_TEST_COLORING
switch(i)
{ case 0: glColor4f(1,0,0,.1); break;
case 1: glColor4f(0,1,0,.3); break;
case 2: glColor4f(0,0,1,.7); break;
case 3: glColor4f(1,1,1,1); break;
}
#endif
//glColor3f(1,0,0);
glVertex3f(p->x,p->y,p->z);
}
glEnd();
}
}
/************
* TEXTURING *
************/
void DPoly::DefineTexture(DTexture *t,QRect *r,int rotateCount,int mirrorFlags)
// Define a portion of the texture as this poly's texturemap
// 'rotateCount' indicates the number of 90 degree rotations you want
// to apply before applying the texture map to the polygon. This way you
// can specify the orientation of the tmap on the polygon.
// 'mirrorFlags' specifies X and Y reversal; &1 = mirror X, &2=mirror Y
// Mirroring is done BEFORE rotateCount is applied (!).
// Works for 3 and 4-point polygons.
// FUTURE: mirror tmap X/Y
{
dfloat left,right,top,bottom,temp; //sx,sy,ex,ey;
dfloat twid,thgt;
texture=t;
twid=texture->GetWidth();
thgt=texture->GetHeight();
// Calculate fraction location of rectangle
left=((dfloat)r->x)/twid;
right=((dfloat)(r->x+r->wid))/twid;
top=((dfloat)r->y)/thgt;
bottom=((dfloat)(r->y+r->hgt))/thgt;
//qdbg("DPoly::DefineTexture: r to float: l%f,r%f,t%f,b%f (r=%d,%d %dx%d t=%fx%f)\n",
//left,right,top,bottom,r->x,r->y,r->wid,r->hgt,twid,thgt);
// Mirroring
if(mirrorFlags&1)
{ // X mirroring
temp=left; left=right; right=temp;
}
if(mirrorFlags&2)
{ // Y mirroring
temp=top; top=bottom; bottom=temp;
}
// Picture reversal (coordinate system)
temp=bottom; bottom=1-top; top=1-temp;
// Redefine texture coordinates at each vertex
int p=rotateCount%points;
point[p].tx=left; point[p].ty=top;
p=(p+1)%points;
point[p].tx=right; point[p].ty=top;
p=(p+1)%points;
point[p].tx=right; point[p].ty=bottom;
if(points>3)
{ p=(p+1)%points;
point[p].tx=left; point[p].ty=bottom;
}
}
/*******************
* DYNAMIC GEOMETRY *
*******************/
void DPoly::SetWidth(dfloat w)
// Modifies a polygon that has a shape such that every point
// to the right of the leftmost point will be set to 'w' X-distance
// of that leftmost point.
// Practical use: rectangular polygons width setting.
{
dfloat minX;
int i;
if(!points)return;
// Find leftmost X value
for(i=0;i<points;i++)
{ if(point[i].x<minX)minX=point[i].x;
}
// For every point to the right of that value, set the width
for(i=0;i<points;i++)
{ if(point[i].x>minX)
{ point[i].x=minX+w;
}
}
}
void DPoly::SetHeight(dfloat h)
// OLD Modifies a polygon that has a shape such that every point
// to the right of the leftmost point will be set to 'w' X-distance
// of that leftmost point.
// Practical use: rectangular polygons width setting.
{
dfloat minY;
int i;
if(!points)return;
// Find lowest Y value
for(i=0;i<points;i++)
{ if(point[i].y<minY)minY=point[i].y;
}
// For every point to the right of that value, set the width
for(i=0;i<points;i++)
{ if(point[i].y>minY)
{ point[i].y=minY+h;
}
}
}