414 lines
11 KiB
C++
Executable File
414 lines
11 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 "widget.h"
|
||
#include <GL/glu.h>
|
||
#include <iostream>
|
||
#include <QKeyEvent>
|
||
#include <QTimer>
|
||
|
||
|
||
GLWidget::GLWidget(QWidget *parent)
|
||
: QGLWidget(parent)
|
||
{
|
||
|
||
_width = 0;
|
||
_height = 0;
|
||
_texture = 0;
|
||
_fps = 30;
|
||
distance = -5.0;
|
||
activeZrotate = false;
|
||
x_trans = 0.0 ; x_rot = 0.;
|
||
y_trans = 0.0; y_rot = 0.;
|
||
z_trans = 0.0; z_rot = .0;
|
||
x_cam_eye=0.; y_cam_eye=0.; z_cam_eye=0.;
|
||
x_cam_center=100.; y_cam_center=0.; z_cam_center=100.;
|
||
x_cam_up=0.; y_cam_up=0.; z_cam_up=0.;
|
||
spectredir = QString("../outils/Spectre/spectrum.txt");
|
||
framedir = QString("../outils/Textures/ocean.png");
|
||
o1 = Ocean(spectredir,8,40,40); //evolution future vers un chargement via le gui
|
||
|
||
}
|
||
|
||
GLWidget::~GLWidget()
|
||
{
|
||
glDeleteTextures(1, &_texture);
|
||
}
|
||
|
||
void GLWidget::_tick()
|
||
{
|
||
|
||
// triggers paintGL()
|
||
update();
|
||
|
||
// Set timer according to FPS
|
||
QTimer::singleShot(1000/_fps, this, SLOT(_tick()));
|
||
|
||
//updateOverlayGL();
|
||
//updateGL();
|
||
}
|
||
|
||
void GLWidget::initializeGL()
|
||
{
|
||
|
||
distance = -10.0;
|
||
x_rot = -180.;
|
||
y_rot = -190.;
|
||
z_rot = -200.;
|
||
now.start();
|
||
// Create the texture
|
||
glGenTextures(1, &_texture);
|
||
// Set clear color as black
|
||
qglClearColor(Qt::darkGray);
|
||
glEnable(GL_DEPTH_TEST);
|
||
//load bit map
|
||
qt_frame.load(framedir);
|
||
// Typical texture generation using data from the bitmap
|
||
_texture = bindTexture(qt_frame,GL_TEXTURE_2D,GL_RGBA);
|
||
// Transfer image data to the GPU
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||
|
||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||
|
||
if (!_fps || _fps <= 0) // if the function fails, fps is set to 15
|
||
_fps = 60;
|
||
|
||
std::cout << "GLWidget::initializeGL: " << _fps << " fps" << std::endl;
|
||
glShadeModel(GL_SMOOTH); // Mod<6F>le d'ombrage : lissage de Gouraud
|
||
glEnable(GL_CULL_FACE); // Ne traite pas les faces cach<63>es
|
||
// Enable lighting
|
||
|
||
glEnable(GL_DEPTH_TEST); // Active le Z-Buffer
|
||
glDepthFunc(GL_LEQUAL); // Mode de fonctionnement du Z-Buffer
|
||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Active la correction de perspective (pour ombrage, texture, ...)
|
||
|
||
/* Start the timer */
|
||
_tick();
|
||
}
|
||
|
||
void GLWidget::paintGL()
|
||
{
|
||
gluLookAt(x_cam_eye, y_cam_eye, z_cam_eye,
|
||
x_cam_center, y_cam_center, z_cam_center,
|
||
x_cam_up, y_cam_up, z_cam_up);
|
||
o1.anime();
|
||
|
||
// 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(x_trans, y_trans, z_trans);
|
||
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)
|
||
{
|
||
std::cout << "GLWidget::paintGL: !!! Failed glTexImage2D" << std::endl;
|
||
}
|
||
|
||
// _view_ortho();
|
||
repereScene3D(200.);
|
||
//qglColor(Qt::darkCyan);
|
||
o1.affiche();
|
||
if(o1.smooth)
|
||
_draw_text(0.,30., 0., "K: Lissage de phong Acitf");
|
||
else
|
||
_draw_text(0.,30., 0., "K: Lissage de phong Inacitf");
|
||
_draw_text(0.,20., 0., "F/C: bouger la light");
|
||
|
||
// _view_perspective();
|
||
|
||
|
||
}
|
||
|
||
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(-200, 200, -200, +200, -1.0, 100000.0);
|
||
#endif
|
||
glMatrixMode(GL_MODELVIEW);
|
||
}
|
||
/*************************
|
||
*
|
||
* Clavier
|
||
*
|
||
* *********************/
|
||
void GLWidget::keyPressEvent(QKeyEvent *event)
|
||
{
|
||
if(event->key() == Qt::Key_Space){
|
||
distance = -10.0;
|
||
x_trans = 0.;
|
||
y_trans = 0;
|
||
z_trans =distance;
|
||
|
||
x_rot = 0.;
|
||
y_rot = 0.;
|
||
z_rot = 0.;
|
||
}
|
||
//-------------------------
|
||
if(event->key() == Qt::Key_Up){
|
||
y_trans += 3.0;
|
||
}
|
||
if(event->key() == Qt::Key_Down){
|
||
y_trans -= 3.0;
|
||
}
|
||
if(event->key() == Qt::Key_Left){
|
||
x_trans += 3.0;
|
||
}
|
||
if(event->key() == Qt::Key_Right){
|
||
x_trans -= 3.0;
|
||
}
|
||
|
||
//-------------------------
|
||
if(event->key() == Qt::Key_A){
|
||
activeZrotate = !activeZrotate;
|
||
}
|
||
//-------------------------
|
||
/* if(event->key() == Qt::Key_Z){
|
||
z_trans += 3.0;
|
||
distance = z_trans;
|
||
}
|
||
if(event->key() == Qt::Key_E){
|
||
z_trans -= 3.0;
|
||
distance = z_trans;
|
||
}
|
||
// cam or worlde moving
|
||
if(event->key() == Qt::Key_U){//up
|
||
x_cam_center+=20.; y_cam_center+=20.; z_cam_center+=20;
|
||
|
||
}
|
||
if(event->key() == Qt::Key_J){//down
|
||
x_cam_center-=20.; y_cam_center-=20.; z_cam_center-=20;
|
||
}
|
||
if(event->key() == Qt::Key_H){//left look
|
||
x_cam_center+=30.; y_cam_center=0.; z_cam_center+=30.;
|
||
}
|
||
if(event->key() == Qt::Key_K){//right look
|
||
x_cam_center-=30.; y_cam_center=0.; z_cam_center-=30.;
|
||
}*/
|
||
//-------------------------
|
||
if(event->key() == Qt::Key_K){//right look
|
||
o1.smooth = !o1.smooth;
|
||
}
|
||
if(event->key() == Qt::Key_L){//right look
|
||
o1.ligth = !o1.ligth;
|
||
}
|
||
//----------ligth move----------------
|
||
|
||
if(event->key() == Qt::Key_F){//up x
|
||
o1.lpos[0] += 25.;
|
||
}
|
||
if(event->key() == Qt::Key_C){//down x
|
||
o1.lpos[0] -= 25.;
|
||
}
|
||
if(event->key() == Qt::Key_X){//up y
|
||
o1.lpos[1] += 25.;
|
||
}
|
||
if(event->key() == Qt::Key_V){//down y
|
||
o1.lpos[1] -= 25.;
|
||
}
|
||
if(event->key() == Qt::Key_B){//up z
|
||
o1.lpos[2] += 25.;
|
||
}
|
||
if(event->key() == Qt::Key_N){//down x
|
||
o1.lpos[2] -= 25.;
|
||
}
|
||
updateGL();// on modifie l'affichage
|
||
}
|
||
|
||
|
||
/*************************
|
||
*
|
||
* Sourie
|
||
*
|
||
* *********************/
|
||
|
||
|
||
void GLWidget::wheelEvent(QWheelEvent *event)
|
||
{
|
||
distance += (2.0 * event->delta() / 120.0);
|
||
z_trans = distance;
|
||
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(activeZrotate){
|
||
if (event->buttons() & Qt::LeftButton ) {
|
||
setXRotation(x_rot + 8 * dx);
|
||
//setYRotation(y_rot + 8 * dx);
|
||
}
|
||
if (event->buttons() & Qt::RightButton) {
|
||
setYRotation(y_rot + 8 * dy);
|
||
//setZRotation(z_rot + 8 * dx);
|
||
}
|
||
}else if (event->buttons() & Qt::LeftButton) {
|
||
setZRotation(z_rot + 8 * dy);
|
||
}
|
||
|
||
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( -2., 2. , 2., -2., -1, 10000 ); // 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_MODELVIEW ); // Select Modelview
|
||
glPopMatrix(); // Pop The Matrix
|
||
glMatrixMode( GL_PROJECTION ); // Select Projection
|
||
glPopMatrix(); // Pop The Matrix
|
||
|
||
}
|
||
/*************************
|
||
* *
|
||
* * outil de dessin
|
||
* *
|
||
* *
|
||
* ***********************/
|
||
// Repere orthonorme
|
||
void GLWidget::repereScene3D(float l)
|
||
{
|
||
glDisable(GL_LIGHTING);
|
||
glDisable(GL_DEPTH_TEST);
|
||
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_DEPTH_TEST);
|
||
glEnable(GL_LIGHTING);
|
||
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
// Affiche le sol de la sc<73>ne.
|
||
//-----------------------------------------------------------------------------
|
||
// Param<61>tres :
|
||
// _
|
||
// Retour :
|
||
// _
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
void GLWidget::affiche_sol()
|
||
{
|
||
glDisable(GL_LIGHTING);
|
||
glDisable(GL_DEPTH_TEST);
|
||
glNormal3f( 0.0f, 1.0f, 0.0f); // Normale du quadrilat<61>re
|
||
//qglColor(Qt::white);
|
||
glBegin(GL_QUADS); // Affichage d'un quadrilat<61>re
|
||
glVertex3f(-20, 0, -20);
|
||
glVertex3f(-20, 0, 20);
|
||
glVertex3f( 20, 0, 20);
|
||
glVertex3f( 20, 0, -20);
|
||
glEnd();
|
||
glEnable(GL_DEPTH_TEST);
|
||
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);
|
||
}
|