warzone2100/tools/pietoaster/texture_mapper.cpp

228 lines
5.7 KiB
C++

/*
* PieToaster is an OpenGL application to edit 3D models in
* Warzone 2100's (an RTS game) PIE 3D model format, which is heavily
* inspired by PieSlicer created by stratadrake.
* Copyright (C) 2007 Carl Hee
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "texture_mapper.h"
#include "texture.h"
#include "screen.h"
void CTextureMapper::addTargets(Uint16 width, Uint16 height, Uint16 textureId, iIMDPoly *target, Uint16 quantity) {
Uint16 i;
if (this->m_Up)
{
return;
}
m_width = width;
m_height = height;
m_textureId = textureId;
m_quantity = quantity;
for (i = 0;i < m_quantity;i++)
{
m_targets[i] = &target[i];
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, g_Screen.m_width, 0, g_Screen.m_height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//assert(g_screen.m_width >= m_width && g_screen.m_height >= m_height);
// Work out the rasterization position
m_rasterX0 = m_rasterX3 = - m_width/2;
m_rasterX1 = m_rasterX2 = m_rasterX0 + m_width;
m_rasterY0 = m_rasterY1 = -m_height/2;
m_rasterY2 = m_rasterY3 = m_rasterY0 + m_height;
this->addGUI();
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
m_Up = true;
}
void CTextureMapper::removeTargets() {
Uint16 i;
if (!this->m_Up)
{
return;
}
TwDeleteBar(m_GUI);
for (i = 0;i < m_quantity;i++)
{
m_targets[i] = NULL;
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glTranslatef(0.0f, 0.0f, 0.0f);
m_Up = false;
}
void CTextureMapper::draw(void) {
glBindTexture(GL_TEXTURE_2D, _TEX_PAGE[m_textureId].id);
GLint x0 = m_rasterX0, x1 = m_rasterX1, x2 = m_rasterX2, x3 = m_rasterX3;
GLint y0 = m_rasterY0, y1 = m_rasterY1, y2 = m_rasterY2, y3 = m_rasterY3;
glScalef(0.25f, 0.25f, 0.25f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex2i(x0, y0);
glTexCoord2f(1.0f, 1.0f);
glVertex2i(x1, y1);
glTexCoord2f(1.0f, 0.0f);
glVertex2i(x2, y2);
glTexCoord2f(0.0f, 0.0f);
glVertex2i(x3, y3);
glEnd();
//glBindTexture(GL_TEXTURE_2D, -1);
glDisable(GL_TEXTURE_2D);
//Draw polygon vertices/points
Sint32 i, x, y;
glColor4ub(255, 192, 255, 255);
for (i = 0;i < m_targets[0]->npnts;i++)
{
#ifdef PROPER_TEXTURE_COORDS
x = this->translateX(m_targets[0]->texCoord[i].x/m_width);
y = this->translateY(m_targets[0]->texCoord[i].y/m_height);
#else
x = this->translateX(m_targets[0]->texCoord[i].x/256.0f);
y = this->translateY(m_targets[0]->texCoord[i].y/256.0f);
#endif
glBegin(GL_LINES);
glVertex2i(x + 2 + x0, -(y + 2 + y0));
glVertex2i(x - 2 + x0, -(y - 2 + y0));
glVertex2i(x + 2 + x0, -(y - 2 + y0));
glVertex2i(x - 2 + x0, -(y + 2 + y0));
glEnd();
}
glBegin(GL_LINE_LOOP);
for (i = 1;i < m_targets[0]->npnts + 1;i++)
{
//links to point 0 when reaching last point
if (i == m_targets[0]->npnts)
{
#ifdef PROPER_TEXTURE_COORDS
x = this->translateX(m_targets[0]->texCoord[i-1].x/m_width);
y = this->translateY(m_targets[0]->texCoord[i-1].y/m_height);
#else
x = this->translateX(m_targets[0]->texCoord[i-1].x/256.0f);
y = this->translateY(m_targets[0]->texCoord[i-1].y/256.0f);
#endif
glVertex2i(x + x0, -(y + y0));
#ifdef PROPER_TEXTURE_COORDS
x = this->translateX(m_targets[0]->texCoord[0].x/m_width);
y = this->translateY(m_targets[0]->texCoord[0].y/m_height);
#else
x = this->translateX(m_targets[0]->texCoord[0].x/256.0f);
y = this->translateY(m_targets[0]->texCoord[0].y/256.0f);
#endif
glVertex2i(x + x0, -(y + y0));
}
else
{
#ifdef PROPER_TEXTURE_COORDS
x = this->translateX(m_targets[0]->texCoord[i-1].x/m_width);
y = this->translateY(m_targets[0]->texCoord[i-1].y/m_height);
#else
x = this->translateX(m_targets[0]->texCoord[i-1].x/256.0f);
y = this->translateY(m_targets[0]->texCoord[i-1].y/256.0f);
#endif
glVertex2i(x + x0, -(y + y0));
#ifdef PROPER_TEXTURE_COORDS
x = this->translateX(m_targets[0]->texCoord[i].x/m_width);
y = this->translateY(m_targets[0]->texCoord[i].y/m_height);
#else
x = this->translateX(m_targets[0]->texCoord[i].x/256.0f);
y = this->translateY(m_targets[0]->texCoord[i].y/256.0f);
#endif
glVertex2i(x + x0, -(y + y0));
}
}
glEnd();
glColor4ub(255, 255, 255, 255);
glEnable(GL_TEXTURE_2D);
}
///Translate texture coord X in float into screen coords in int
Sint32 CTextureMapper::translateX(float texCoord) {
return (Sint32)(texCoord * m_width);
}
///Translate texture coord Y in float into screen coords in int
Sint32 CTextureMapper::translateY(float texCoord) {
return (Sint32)(texCoord * m_height);
}
void CTextureMapper::addGUI(void) {
m_GUI = TwNewBar("TextureMapper");
char tmDefine[255];
snprintf(tmDefine, 255, "TextureMapper ");
Uint16 i, j;
//assert(m_quantity < 10 && m_targets[i]->npnts < 10)
for (i = 0;i < m_quantity;i++)
{
for (j = 0;j < m_targets[i]->npnts;j++)
{
char varName[255];
char varDefine[255];
snprintf(varName, 255, "target%uN%u", i, j);
//TODO:non-power-of-two support?
snprintf(varDefine, 255, "label = 'vertice%u'", j);
TwAddVarRW(m_GUI, varName, g_tw_pieVector2fType, &m_targets[i]->texCoord[j], varDefine);
}
}
}