portfolio/cpp/visage/widget.cpp

320 lines
7.9 KiB
C++
Executable File

/* Copyright (C) 2013 Karl Phillip Buhr <karlphillip@gmail.com>
*
* This work is licensed under the Creative Commons Attribution-ShareAlike License.
* To view a copy of this license, visit:
* https://creativecommons.org/licenses/by-sa/2.5/legalcode
*
* Or to read the human-readable summary of the license:
* https://creativecommons.org/licenses/by-sa/2.5/
*/
#include <GL/glu.h>
#include <iostream>
#include <QKeyEvent>
#include <QTimer>
#include <QDebug>
#include "widget.h"
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent)
{
_width = 0;
_height = 0;
_texture = 0;
_fps = 0;
distance = -5.0;
x=0;x_rot = 0.;
y=0;y_rot = 0.;
z=0; z_rot = .0;
t=0.0; interp=0;
Objet3D* obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_normal.off"));
obj_visage_inter.charger_Off(QString("../outils/visages_off/visage_normal.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_joie.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_degout.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_surprise.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_colere.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_tristesse.off"));
visage.push_back(obj);
obj = new Objet3D;
obj->charger_Off(QString("../outils/visages_off/visage_peur.off"));
visage.push_back(obj);
}
GLWidget::~GLWidget()
{
glDeleteTextures(1, &_texture);
}
void GLWidget::_tick()
{
// triggers paintGL()
update();
//updateGL();
// Set timer according to FPS
QTimer::singleShot(1000/_fps, this, SLOT(_tick()));
}
void GLWidget::initializeGL()
{
distance = -10.0;
x_rot = 0.;
y_rot = 0.;
z_rot = 0.;
// Set clear color as black
qglClearColor(Qt::darkGray);
glEnable(GL_DEPTH_TEST);
// Retrieve FPS from the camera
//_fps = cv_capture.get(CV_CAP_PROP_FPS);
if (!_fps || _fps <= 0) // if the function fails, fps is set to 15
_fps = 25;
qDebug() << "GLWidget::initializeGL: " << _fps << " fps";
/* Start the timer */
_tick();
}
void GLWidget::paintGL()
{
if(interp < (visage.size()-1) )
obj_visage_inter.interpolation(*visage[interp], *visage[interp+1], t= min(1.0, t+.1 ));
if(interp == (visage.size()-1) )
obj_visage_inter.interpolation(*visage[interp], *visage[0], t= min(1.0, t+.1 ));
if(t >= 1.0) {t=0.0; interp = (interp+1) % (visage.size()-1); }
// Clear the screen and depth buffer (with black)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
// Model view matrix
// glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, distance);
glRotatef(x_rot / 16.0f, 1.0f, 0.0f, 0.0f);
glRotatef(y_rot / 16.0f, 0.0f, 1.0f, 0.0f);
glRotatef(z_rot / 16.0f, 0.0f, 0.0f, 1.0f);
if (glGetError() != GL_NO_ERROR)
{
qDebug()<< "GLWidget::paintGL: !!! Failed glTexImage2D" ;
}
repereScene3D(10);
//qglColor(Qt::darkCyan) ;//
obj_visage_inter.affiche();
if( obj_visage_inter.ligth)
_draw_text(12.,0.,0.,"Light : On");
else _draw_text(12.,0.,0.,"Light : Off");
if(obj_visage_inter.smooth )
_draw_text(10.,2.,0.,"DrawNormal : Face");
else _draw_text(12.,2.,0.,"DrawNormal :"
" Vertex");
}
void GLWidget::resizeGL( int w, int h)
{
_width = w;
_height = h;
int side = qMin(_width, _height);
glViewport((_width - side) / 2, (_height - side) / 2, side, side);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef QT_OPENGL_ES_1
glOrthof(-2, +2, -2, +2, 1.0, 15.0);
#else
glOrtho(-15.0, +20, -20, +20.0, 1.0, 50.0);
#endif
glMatrixMode(GL_MODELVIEW);
}
/*************************
*
* Clavier
*
* *********************/
void GLWidget::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Space){
distance = -10.0;
x_rot = 0.;
y_rot = 0.;
z_rot = 0.;
}
if(event->key() == Qt::Key_S){ // active/deactive le calcule normale face
obj_visage_inter.smooth = !obj_visage_inter.smooth;
}
if(event->key() == Qt::Key_L){ //active/déactive la lumiere autour de l'objet
obj_visage_inter.ligth = !obj_visage_inter.ligth;
}
updateGL();// on modifie l'affichage
}
/*************************
*
* Sourie
*
* *********************/
void GLWidget::wheelEvent(QWheelEvent *event)
{
distance += (2.0 * event->delta() / 120.0);
updateGL();
}
void GLWidget::mousePressEvent(QMouseEvent *event)
{
last_pos = event->pos();
// qDebug() <<last_pos;
}
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->x() - last_pos.x();
int dy = event->y() - last_pos.y();
if (event->buttons() & Qt::LeftButton) {
setXRotation(x_rot + 8 * dy);
setYRotation(y_rot + 8 * dx);
} else if (event->buttons() & Qt::RightButton) {
setYRotation(x_rot + 8 * dy);
setZRotation(z_rot + 8 * dx);
} else if (event->buttons() & Qt::MiddleButton) {
distance = -1.0;
x_rot = 0.;
y_rot = 0.;
z_rot = 0.;
}
last_pos = event->pos();
// qDebug()<<last_pos;
}
static void qNormalizeAngle(int &angle)
{
while (angle < 0)
angle += 360 * 16;
while (angle > 360)
angle -= 360 * 16;
}
void GLWidget::setXRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != x_rot) {
x_rot = angle;
//emit xRotationChanged(angle);
updateGL();
}
}
void GLWidget::setYRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != y_rot) {
y_rot = angle;
//emit yRotationChanged(angle);
updateGL();
}
}
void GLWidget::setZRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != z_rot) {
z_rot = angle;
//emit zRotationChanged(angle);
updateGL();
}
}
/*********************
* *
* * Model view
* *
* *********************/
void GLWidget::_view_ortho() // Set Up An Ortho View
{
glMatrixMode(GL_PROJECTION); // Select Projection
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
glOrtho( 0, _width , _height, 0, -1, 1 ); // Select Ortho Mode (640x480)
glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
}
void GLWidget::_view_perspective() // Set Up A Perspective View
{
glMatrixMode( GL_PROJECTION ); // Select Projection
glPopMatrix(); // Pop The Matrix
glMatrixMode( GL_MODELVIEW ); // Select Modelview
glPopMatrix(); // Pop The Matrix
}
/*************************
* *
* * outil de dessin
* *
* *
* ***********************/
// Repere orthonorme
void GLWidget::repereScene3D(float l)
{
glDisable(GL_LIGHTING);
glBegin (GL_LINES);
glColor3d(1.,0.,0.) ; // red axe
glVertex3f (0., 0., 0.);
glVertex3f (l, 0., 0.);
glColor3d(0.,1.,0.) ;// green axe
glVertex3f (0., 0., 0.);
glVertex3f (0., l, 0.);
glColor3d(0.,0.,1.) ;//bleu axe
glVertex3f (0., 0., 0.);
glVertex3f (0., 0., l);
glEnd ();
glEnable(GL_LIGHTING);
}
void GLWidget::_draw_text(double x, double y, double z, QString txt)
{
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
qglColor(Qt::white);
renderText(x, y, z, txt, QFont("Arial", 12, QFont::Bold, false) );
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}