Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttessellator.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tregionoutline.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tcolorfunctions.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tcg/tcg_numeric_ops.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef WIN32
Toshihiro Shimizu 890ddd
#define CALLBACK
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
// To avoid linking problems with HP ZX2000
Toshihiro Shimizu 890ddd
#ifdef LINUX
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
#undef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifndef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
#define GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//==================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef checkErrorsByGL
Toshihiro Shimizu 890ddd
#define checkErrorsByGL                      \
Toshihiro Shimizu 890ddd
	{                                        \
Toshihiro Shimizu 890ddd
		GLenum err = glGetError();           \
Toshihiro Shimizu 890ddd
		assert(err != GL_INVALID_ENUM);      \
Toshihiro Shimizu 890ddd
		assert(err != GL_INVALID_VALUE);     \
Toshihiro Shimizu 890ddd
		assert(err != GL_INVALID_OPERATION); \
Toshihiro Shimizu 890ddd
		assert(err != GL_STACK_OVERFLOW);    \
Toshihiro Shimizu 890ddd
		assert(err != GL_STACK_UNDERFLOW);   \
Toshihiro Shimizu 890ddd
		assert(err != GL_OUT_OF_MEMORY);     \
Toshihiro Shimizu 890ddd
		assert(err == GL_NO_ERROR);          \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TglTessellator::GLTess::GLTess()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_tess = gluNewTess();
Toshihiro Shimizu 890ddd
	assert(m_tess);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TglTessellator::GLTess::~GLTess()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	gluDeleteTess(m_tess);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" void CALLBACK tessellateTexture(const GLdouble *tex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double u = tex[0] * 0.01;
Toshihiro Shimizu 890ddd
	double v = tex[1] * 0.01;
Toshihiro Shimizu 890ddd
	glTexCoord2d(u, v);
Toshihiro Shimizu 890ddd
	glVertex2dv(tex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TThread::Mutex CombineDataGuard;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::list<gldouble *=""> Combine_data;</gldouble>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" void CALLBACK myCombine(GLdouble coords[3], GLdouble *d[4],
Toshihiro Shimizu 890ddd
								   GLfloat w[4], GLdouble **dataOut)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	GLdouble *newCoords = new GLdouble[3];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	newCoords[0] = coords[0];
Toshihiro Shimizu 890ddd
	newCoords[1] = coords[1];
Toshihiro Shimizu 890ddd
	newCoords[2] = coords[2];
Toshihiro Shimizu 890ddd
	Combine_data.push_back(newCoords);
Toshihiro Shimizu 890ddd
	*dataOut = newCoords;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//typedef std::vector<t3dpointd>::iterator Vect3D_iter;</t3dpointd>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
typedef GLvoid(CALLBACK *GluCallback)(void);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef GLvoid (*GluCallback)();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TglTessellator::doTessellate(GLTess &glTess, const TColorFunction *cf, const bool antiAliasing, TRegionOutline outline, const TAffine &aff)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&CombineDataGuard);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Combine_data.clear();
Toshihiro Shimizu 890ddd
	assert(glTess.m_tess);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_BEGIN, (GluCallback)glBegin);
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_END, (GluCallback)glEnd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_COMBINE, (GluCallback)myCombine);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
	gluTessBeginPolygon(glTess.m_tess, NULL);
Toshihiro Shimizu 890ddd
	gluTessProperty(glTess.m_tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
	gluBeginPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (TRegionOutline::Boundary::iterator poly_it = outline.m_exterior.begin(); poly_it != outline.m_exterior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
		gluTessBeginContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
		gluNextContour(glTess.m_tess, GLU_EXTERIOR);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it) {
Toshihiro Shimizu 890ddd
			//T3DPointD p = *it;
Toshihiro Shimizu 890ddd
			it->x = aff.a11 * it->x + aff.a12 * it->y;
Toshihiro Shimizu 890ddd
			it->y = aff.a21 * it->x + aff.a22 * it->y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gluTessVertex(glTess.m_tess, &(it->x), &(it->x));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
		gluTessEndContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int subRegionNumber = outline.m_interior.size();
Toshihiro Shimizu 890ddd
	if (subRegionNumber > 0) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::Boundary::iterator poly_it = outline.m_interior.begin(); poly_it != outline.m_interior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
			gluTessBeginContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
			gluNextContour(glTess.m_tess, GLU_INTERIOR);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
			assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (TRegionOutline::PointVector::reverse_iterator rit = poly_it->rbegin(); rit != poly_it->rend(); ++rit) {
Toshihiro Shimizu 890ddd
				//T3DPointD p = *rit;
Toshihiro Shimizu 890ddd
				rit->x = aff.a11 * rit->x + aff.a12 * rit->y;
Toshihiro Shimizu 890ddd
				rit->y = aff.a21 * rit->x + aff.a22 * rit->y;
Toshihiro Shimizu 890ddd
				gluTessVertex(glTess.m_tess, &(rit->x), &(rit->x));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
			gluTessEndContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
	gluTessEndPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
	gluEndPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::list<gldouble *="">::iterator beginIt, endIt;</gldouble>
Toshihiro Shimizu 890ddd
	endIt = Combine_data.end();
Toshihiro Shimizu 890ddd
	beginIt = Combine_data.begin();
Toshihiro Shimizu 890ddd
	for (; beginIt != endIt; ++beginIt)
Toshihiro Shimizu 890ddd
		delete[](*beginIt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TglTessellator::doTessellate(GLTess &glTess, const TColorFunction *cf, const bool antiAliasing, TRegionOutline &outline)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&CombineDataGuard);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Combine_data.clear();
Toshihiro Shimizu 890ddd
	assert(glTess.m_tess);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_BEGIN, (GluCallback)glBegin);
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_END, (GluCallback)glEnd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_COMBINE, (GluCallback)myCombine);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
	gluTessBeginPolygon(glTess.m_tess, NULL);
Toshihiro Shimizu 890ddd
	gluTessProperty(glTess.m_tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
	gluBeginPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (TRegionOutline::Boundary::iterator poly_it = outline.m_exterior.begin(); poly_it != outline.m_exterior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
		gluTessBeginContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
		gluNextContour(glTess.m_tess, GLU_EXTERIOR);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it)
Toshihiro Shimizu 890ddd
			gluTessVertex(glTess.m_tess, &(it->x), &(it->x));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
		gluTessEndContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int subRegionNumber = outline.m_interior.size();
Toshihiro Shimizu 890ddd
	if (subRegionNumber > 0) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::Boundary::iterator poly_it = outline.m_interior.begin(); poly_it != outline.m_interior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
			gluTessBeginContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
			gluNextContour(glTess.m_tess, GLU_INTERIOR);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
			assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (TRegionOutline::PointVector::reverse_iterator rit = poly_it->rbegin(); rit != poly_it->rend(); ++rit)
Toshihiro Shimizu 890ddd
				gluTessVertex(glTess.m_tess, &(rit->x), &(rit->x));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
			gluTessEndContour(glTess.m_tess);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_2
Toshihiro Shimizu 890ddd
	gluTessEndPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#ifdef GLU_VERSION_1_1
Toshihiro Shimizu 890ddd
	gluEndPolygon(glTess.m_tess);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	assert(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::list<gldouble *="">::iterator beginIt, endIt;</gldouble>
Toshihiro Shimizu 890ddd
	endIt = Combine_data.end();
Toshihiro Shimizu 890ddd
	beginIt = Combine_data.begin();
Toshihiro Shimizu 890ddd
	for (; beginIt != endIt; ++beginIt)
Toshihiro Shimizu 890ddd
		delete[](*beginIt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TglTessellator::tessellate(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &outline, TPixel32 color)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (cf)
Toshihiro Shimizu 890ddd
		color = (*(cf))(color);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (color.m == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool transparencyFlag = color.m < 255;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tglColor(color);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (transparencyFlag) {
Toshihiro Shimizu 890ddd
		tglEnableLineSmooth();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TglTessellator::GLTess glTess;
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_VERTEX, (GluCallback)glVertex3dv);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//------------------------//
Toshihiro Shimizu 890ddd
	doTessellate(glTess, cf, antiAliasing, outline);
Toshihiro Shimizu 890ddd
	//------------------------//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (antiAliasing && outline.m_doAntialiasing) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		tglEnableLineSmooth();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::Boundary::iterator poly_it = outline.m_exterior.begin(); poly_it != outline.m_exterior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
			vector<gldouble> v;</gldouble>
Toshihiro Shimizu 890ddd
			if (poly_it->size() == 0)
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			v.resize(poly_it->size() * 2);
Toshihiro Shimizu 890ddd
			int i = 0;
Toshihiro Shimizu 890ddd
			for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it) {
Toshihiro Shimizu 890ddd
				v[i++] = it->x;
Toshihiro Shimizu 890ddd
				v[i++] = it->y;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glEnableClientState(GL_VERTEX_ARRAY);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glVertexPointer(2, GL_DOUBLE, sizeof(GLdouble) * 2, &v[0]);
Toshihiro Shimizu 890ddd
			glDrawArrays(GL_LINE_LOOP, 0, v.size() / 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glDisableClientState(GL_VERTEX_ARRAY);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (TRegionOutline::Boundary::iterator poly_it = outline.m_interior.begin(); poly_it != outline.m_interior.end(); ++poly_it) {
Toshihiro Shimizu 890ddd
			vector<gldouble> v;</gldouble>
Toshihiro Shimizu 890ddd
			v.resize(poly_it->size() * 2);
Toshihiro Shimizu 890ddd
			int i = 0;
Toshihiro Shimizu 890ddd
			for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it) {
Toshihiro Shimizu 890ddd
				v[i++] = it->x;
Toshihiro Shimizu 890ddd
				v[i++] = it->y;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (v.empty())
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			glEnableClientState(GL_VERTEX_ARRAY);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glVertexPointer(2, GL_DOUBLE, sizeof(GLdouble) * 2, &v[0]);
Toshihiro Shimizu 890ddd
			glDrawArrays(GL_LINE_LOOP, 0, v.size() / 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glDisableClientState(GL_VERTEX_ARRAY);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TglTessellator::tessellate(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &outline, TRaster32P texture)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//QMutexLocker sl(m_mutex);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glEnable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
	glColor4d(1, 1, 1, 1);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	TextureInfoForGL texInfo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int pow2Lx = tcg::numeric_ops::GE_2Power((unsigned int)texture->getLx());
Toshihiro Shimizu 890ddd
	int pow2Ly = tcg::numeric_ops::GE_2Power((unsigned int)texture->getLy());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TAffine aff;
Toshihiro Shimizu 890ddd
	if (texture->getLx() != pow2Lx || texture->getLy() != pow2Ly) {
Toshihiro Shimizu 890ddd
		TRaster32P r(pow2Lx, pow2Ly);
Toshihiro Shimizu 890ddd
		aff = TScale((double)pow2Lx / texture->getLx(), (double)pow2Ly / texture->getLy());
Toshihiro Shimizu 890ddd
		TRop::resample(r, texture, aff.place(texture->getCenterD(), r->getCenterD()));
Toshihiro Shimizu 890ddd
		texture = r;
Toshihiro Shimizu 890ddd
		glPushMatrix();
Toshihiro Shimizu 890ddd
		tglMultMatrix(aff.inv());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// If GL_BRGA isn't present make a proper texture to use (... obsolete?)
Toshihiro Shimizu 890ddd
	texture->lock();
Toshihiro Shimizu 890ddd
	TRasterP texImage = prepareTexture(texture, texInfo);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	if (texImage != texture)
Toshihiro Shimizu 890ddd
		texImage->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(texImage->getLx() == texImage->getWrap());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	GLuint texId;
Toshihiro Shimizu 890ddd
	glGenTextures(1, &texId); // Generate a texture name
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glBindTexture(GL_TEXTURE_2D, texId); // Bind it 'active'
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	 // These must be invoked
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	 // on a bound texture
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glTexEnvf(GL_TEXTURE_ENV,	  // This too ?
Toshihiro Shimizu 890ddd
			  GL_TEXTURE_ENV_MODE, // Better here anyway
Toshihiro Shimizu 890ddd
			  GL_MODULATE);		   //
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glTexImage2D(GL_TEXTURE_2D,
Toshihiro Shimizu 890ddd
				 0,						 // one level only
Toshihiro Shimizu 890ddd
				 texInfo.internalformat, // pixel channels count
Toshihiro Shimizu 890ddd
				 texInfo.width,			 // width
Toshihiro Shimizu 890ddd
				 texInfo.height,		 // height
Toshihiro Shimizu 890ddd
				 0,						 // border size
Toshihiro Shimizu 890ddd
				 texInfo.type,			 // pixel format           // crappy names
Toshihiro Shimizu 890ddd
				 texInfo.format,		 // pixel data type        // oh, SO much
Toshihiro Shimizu 890ddd
				 texImage->getRawData());
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	texture->unlock();
Toshihiro Shimizu 890ddd
	if (texImage != texture)
Toshihiro Shimizu 890ddd
		texImage->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TglTessellator::GLTess glTess;
Toshihiro Shimizu 890ddd
	gluTessCallback(glTess.m_tess, GLU_TESS_VERTEX, (GluCallback)tessellateTexture);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//------------------------//
Toshihiro Shimizu 890ddd
	if (aff != TAffine())
Toshihiro Shimizu 890ddd
		doTessellate(glTess, cf, antiAliasing, outline, aff); // Tessellate & render
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		doTessellate(glTess, cf, antiAliasing, outline); // Tessellate & render
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	//------------------------//
Toshihiro Shimizu 890ddd
	if (aff != TAffine())
Toshihiro Shimizu 890ddd
		glPopMatrix();
Toshihiro Shimizu 890ddd
	glDeleteTextures(1, &texId); // Delete & unbind texture
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
	glDisable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
	checkErrorsByGL;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//TglTessellator::GLTess TglTessellator::m_glTess;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================