/*************************************************************************** * Copyright (C) 2009 by Stefan Bühler * * stbuehler@web.de * * * * 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. * * * * 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. * ***************************************************************************/ #include "field3d.h" #include #include namespace toruschess { Field3D::Field3D(Game *game, QWidget *parent) : QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba), parent), m_game(game), m_lib(new PieceLibrary(this)), m_textureBuffer(0), m_textureID(0), m_camDist(10) ,m_camRotX(90), m_camRotY(0), m_camRotZ(0) { qDebug("Field3d::Field3D"); for (int x = 0; x < 8; x++) for (int y = 0; y < 8; y++) m_marked[x][y] = false; m_lib->setSize(m_textureSize / 8, m_textureSize / 8); } Field3D::~Field3D() { qDebug("Field3d::~Field3D"); freeTexture(); } void Field3D::markMoves(const QList &moves) { foreach(Move m, m_markedMoves) m_marked[m.to().x()][m.to().y()] = false; m_markedMoves = moves; foreach(Move m, m_markedMoves) m_marked[m.to().x()][m.to().y()] = true; updateTexture(); updateGL(); } QSize Field3D::sizeHint() const { return QSize(640, 480); } void Field3D::initializeGL() { glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); createTexture(); createTorus(); } void Field3D::resizeGL(int w, int h) { glViewport(0, 0, (GLint)w, (GLint)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, double(w)/h, 1, 1000); updateCam(); } void Field3D::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, m_textureID); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0, 1); glVertex3f(-10, 0, -10); glTexCoord2f(0, 0); glVertex3f(-10, 0, 10); glTexCoord2f(1, 0); glVertex3f( 10, 0, 10); glTexCoord2f(1, 1); glVertex3f( 10, 0, -10); glEnd(); glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } void Field3D::updateCam() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -m_camDist); glRotatef(m_camRotX,1,0,0); glRotatef(m_camRotY,0,1,0); glRotatef(m_camRotZ,0,0,1); updateGL(); } void Field3D::createTexture() { freeTexture(); m_textureBuffer = new QImage(QSize(m_textureSize, m_textureSize), QImage::Format_ARGB32_Premultiplied); m_textureBuffer->fill(Qt::black); glBindTexture(GL_TEXTURE_2D, m_textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); updateTexture(); m_textureID = bindTexture(*m_textureBuffer); } void Field3D::freeTexture() { if (m_textureID != 0) { deleteTexture(m_textureID); m_textureID = 0; } if (m_textureBuffer) { delete m_textureBuffer; m_textureBuffer = 0; } } void Field3D::updateTexture() { QPainter pt(m_textureBuffer); int pieceSize = m_textureSize / 8; for (int x = 0; x < 8; x++) for (int y = 0; y < 8; y++) { bool marked = m_marked[x][y]; int place = m_game->field()->place(Pos(x, y)); /* #D18B47 for dark, #FFCE9E for white */ QBrush fieldBG = ((x+y) % 2 == 1) ? QBrush(QColor(0xD1, 0x8B, 0x47)) : QBrush(QColor(0xFF, 0xCE, 0x9E)); QRect prect(x * pieceSize, y * pieceSize, pieceSize - 1, pieceSize - 1); pt.fillRect(prect, fieldBG); m_lib->paint(pt, place, prect); if (marked) { int r = qMax(1, (pieceSize + pieceSize) / 36); pt.setBrush(place != 0 ? Qt::green : Qt::white); pt.setPen(Qt::red); pt.drawEllipse(QPoint(prect.x() + pieceSize / 2, prect.y() + pieceSize / 2), r, r); } } } }