diff --git a/src/field3d.cpp b/src/field3d.cpp new file mode 100644 index 0000000..5146b13 --- /dev/null +++ b/src/field3d.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * 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); + } + } + } + + +} diff --git a/src/field3d.h b/src/field3d.h new file mode 100644 index 0000000..28ea9ee --- /dev/null +++ b/src/field3d.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef TORUSCHESSFIELD3D_H +#define TORUSCHESSFIELD3D_H + +#include + +#include "toruschess.h" +#include "piecelibrary.h" + +/** + @author Stefan Bühler +*/ +namespace toruschess { + + class Field3D : public QGLWidget { + Q_OBJECT + public: + Field3D(Game *game, QWidget *parent = 0); + virtual ~Field3D(); + + void markMoves(const QList &moves); + + virtual QSize sizeHint() const; + + protected: + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + virtual void paintGL(); + + private: + void updateCam(); + + void createTexture(); + void freeTexture(); + void updateTexture(); + + void createTorus(); + void freeTorus(); + + Game *m_game; + PieceLibrary *m_lib; + + bool m_marked[8][8]; + QList m_markedMoves; + + /* Texture data */ + QImage *m_textureBuffer; + GLuint m_textureID; + + /* Cam data */ + double m_camDist, m_camRotX, m_camRotY, m_camRotZ; + + static const int m_textureSize = 1024; + }; + +} + +#endif diff --git a/src/src.pro b/src/src.pro index 2f0fa58..9c9b466 100644 --- a/src/src.pro +++ b/src/src.pro @@ -2,7 +2,8 @@ SOURCES += main.cpp \ testgame.cpp \ toruschess.cpp \ field2d.cpp \ - piecelibrary.cpp + piecelibrary.cpp \ + field3d.cpp TEMPLATE = app CONFIG += warn_on \ thread \ @@ -18,6 +19,7 @@ opengl HEADERS += testgame.h \ toruschess.h \ field2d.h \ - piecelibrary.h + piecelibrary.h \ + field3d.h CONFIG -= release diff --git a/src/testgame.cpp b/src/testgame.cpp index 88b9d2f..2b10395 100644 --- a/src/testgame.cpp +++ b/src/testgame.cpp @@ -25,6 +25,7 @@ #include #include "field2d.h" +#include "field3d.h" namespace toruschess { @@ -114,7 +115,7 @@ namespace toruschess { setWindowTitle("Torus Chess"); // PieceLibrary *lib = new PieceLibrary(this); // setCentralWidget(new TestField(this, lib, m_game)); - setCentralWidget(new Field2D(m_game, this)); + setCentralWidget(new Field3D(m_game, this)); } }