Commit 4332f836 by Alisa Jung

fertig bis trackball

parent 3ebc80d3
...@@ -95,6 +95,12 @@ MainWindow::MainWindow(QWidget *parent) ...@@ -95,6 +95,12 @@ MainWindow::MainWindow(QWidget *parent)
tesselationSlider->setValue(1); tesselationSlider->setValue(1);
connect(tesselationSlider,SIGNAL(valueChanged(int)),myGLWidget,SLOT(setTessellation(int))); connect(tesselationSlider,SIGNAL(valueChanged(int)),myGLWidget,SLOT(setTessellation(int)));
toolBar->addWidget(tesselationSlider); toolBar->addWidget(tesselationSlider);
//reset Camera button
resetCameraAction = new QAction("Reset Camera",toolBar);
connect(resetCameraAction,SIGNAL(triggered(bool)),myGLWidget,SLOT(resetCamera()));
toolBar->addAction(resetCameraAction);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
......
...@@ -47,6 +47,8 @@ private: ...@@ -47,6 +47,8 @@ private:
QAction *shadePhongAction; QAction *shadePhongAction;
QActionGroup *shaderGroup; QActionGroup *shaderGroup;
QAction *resetCameraAction;
//Widgets //Widgets
MyGLWidget *myGLWidget; MyGLWidget *myGLWidget;
......
...@@ -4,9 +4,10 @@ MyGLWidget::MyGLWidget(QWidget *parent) ...@@ -4,9 +4,10 @@ MyGLWidget::MyGLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{ {
tesselation = 1; tesselation = 1;
cameraZoom = -5; qubeRotationQuaternion = QQuaternion();
translationX = 0; tx = 0;
translationY = 0; ty = 0;
cameraZoom = cameraZoomDefault;
clickStartPosition = QPoint(0,0); clickStartPosition = QPoint(0,0);
rightButtonPressed = false; rightButtonPressed = false;
} }
...@@ -97,11 +98,18 @@ void MyGLWidget::paintGL(){ ...@@ -97,11 +98,18 @@ void MyGLWidget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); glLoadIdentity();
glTranslatef(translationX,translationY,cameraZoom);//Kamera sitzt sonst in (0,0,0) und man sieht nichts (duh) //zoom camera
glTranslatef(0,0,cameraZoom);//Kamera sitzt sonst in (0,0,0) und man sieht nichts (duh)
//for translation
double qubeWidth = 1.0; double qubeWidth = 1.0;
double dist = qubeWidth/(double)tesselation; double dist = qubeWidth/(double)tesselation;
//for cube rotation
QMatrix4x4 m = QMatrix4x4();
m.rotate(qubeRotationQuaternion);
glMultMatrixf(m.data());
//4.1.1 Unit Qube + Tesselation + Diffuse Material //4.1.1 Unit Qube + Tesselation + Diffuse Material
{ {
glBegin(GL_QUADS); glBegin(GL_QUADS);
...@@ -116,14 +124,16 @@ void MyGLWidget::paintGL(){ ...@@ -116,14 +124,16 @@ void MyGLWidget::paintGL(){
// glColor3f(0,0,1);//blau // glColor3f(0,0,1);//blau
GLfloat blue[] = {0,0,1}; GLfloat blue[] = {0,0,1};
glMaterialfv(GL_FRONT,GL_DIFFUSE,blue); glMaterialfv(GL_FRONT,GL_DIFFUSE,blue);
glNormal3f(0,0,1);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(0.5-dist*i,0.5-dist*j,0.5); glVertex3f(tx+0.5-dist*i,ty+0.5-dist*j,0.5);
glVertex3f(0.5-dist*(i+1),0.5-dist*j,0.5); glVertex3f(tx+0.5-dist*(i+1),ty+0.5-dist*j,0.5);
glVertex3f(0.5-dist*(i+1),0.5-dist*(j+1),0.5); glVertex3f(tx+0.5-dist*(i+1),ty+0.5-dist*(j+1),0.5);
glVertex3f(0.5-dist*i,0.5-dist*(j+1),0.5); glVertex3f(tx+0.5-dist*i,ty+0.5-dist*(j+1),0.5);
} }
} }
//reference for previous front
// glVertex3f(0.5, 0.5, 0.5);//4 // glVertex3f(0.5, 0.5, 0.5);//4
// glVertex3f(-0.5, 0.5, 0.5);//3 // glVertex3f(-0.5, 0.5, 0.5);//3
// glVertex3f(-0.5, -0.5, 0.5);//2 // glVertex3f(-0.5, -0.5, 0.5);//2
...@@ -132,12 +142,13 @@ void MyGLWidget::paintGL(){ ...@@ -132,12 +142,13 @@ void MyGLWidget::paintGL(){
//oben // y-Achse //oben // y-Achse
GLfloat green[] = {0,1,0}; GLfloat green[] = {0,1,0};
glMaterialfv(GL_FRONT,GL_DIFFUSE,green); glMaterialfv(GL_FRONT,GL_DIFFUSE,green);
glNormal3f(0,1,0);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(0.5-dist*(i+1), 0.5, 0.5-dist*(j+1)); glVertex3f(tx+0.5-dist*(i+1), ty+0.5, 0.5-dist*(j+1));
glVertex3f(0.5-dist*(i+1), 0.5, 0.5-dist*j); glVertex3f(tx+0.5-dist*(i+1), ty+0.5, 0.5-dist*j);
glVertex3f(0.5-dist*i, 0.5, 0.5-dist*j); glVertex3f(tx+0.5-dist*i, ty+0.5, 0.5-dist*j);
glVertex3f(0.5-dist*i, 0.5, 0.5-dist*(j+1)); glVertex3f(tx+0.5-dist*i, ty+0.5, 0.5-dist*(j+1));
} }
} }
...@@ -145,12 +156,13 @@ void MyGLWidget::paintGL(){ ...@@ -145,12 +156,13 @@ void MyGLWidget::paintGL(){
//rechts //x-Achse //rechts //x-Achse
GLfloat red[] = {1,0,0}; GLfloat red[] = {1,0,0};
glMaterialfv(GL_FRONT,GL_DIFFUSE,red); glMaterialfv(GL_FRONT,GL_DIFFUSE,red);
glNormal3f(1,0,0);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(0.5, 0.5-dist*i, 0.5-dist*j); glVertex3f(tx+0.5, ty+0.5-dist*i, 0.5-dist*j);
glVertex3f(0.5, 0.5-dist*(i+1), 0.5-dist*j); glVertex3f(tx+0.5, ty+0.5-dist*(i+1), 0.5-dist*j);
glVertex3f(0.5, 0.5-dist*(i+1), 0.5-dist*(j+1)); glVertex3f(tx+0.5, ty+0.5-dist*(i+1), 0.5-dist*(j+1));
glVertex3f(0.5, 0.5-dist*i, 0.5-dist*(j+1)); glVertex3f(tx+0.5, ty+0.5-dist*i, 0.5-dist*(j+1));
} }
} }
...@@ -158,36 +170,39 @@ void MyGLWidget::paintGL(){ ...@@ -158,36 +170,39 @@ void MyGLWidget::paintGL(){
//hinten // z-Achse //hinten // z-Achse
GLfloat yellow[] = {1,0.9,0}; GLfloat yellow[] = {1,0.9,0};
glMaterialfv(GL_FRONT,GL_DIFFUSE,yellow); glMaterialfv(GL_FRONT,GL_DIFFUSE,yellow);
glNormal3f(0,0,-1);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(0.5-dist*i, 0.5-dist*(j+1), -0.5);//4 glVertex3f(tx+0.5-dist*i, ty+0.5-dist*(j+1), -0.5);//4
glVertex3f(0.5-dist*(i+1), 0.5-dist*(j+1), -0.5);//3 glVertex3f(tx+0.5-dist*(i+1), ty+0.5-dist*(j+1), -0.5);//3
glVertex3f(0.5-dist*(i+1), 0.5-dist*j, -0.5);//2 glVertex3f(tx+0.5-dist*(i+1), ty+0.5-dist*j, -0.5);//2
glVertex3f(0.5-dist*i, 0.5-dist*j, -0.5);//1 glVertex3f(tx+0.5-dist*i,ty+ 0.5-dist*j, -0.5);//1
} }
} }
//links //links
GLfloat cyan[] = {0,1,1}; GLfloat cyan[] = {0,1,1};
glMaterialfv(GL_FRONT,GL_DIFFUSE,cyan); glMaterialfv(GL_FRONT,GL_DIFFUSE,cyan);
glNormal3f(-1,0,0);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(-0.5, 0.5-dist*i, 0.5-dist*(j+1)); glVertex3f(tx-0.5, ty+0.5-dist*i, 0.5-dist*(j+1));
glVertex3f(-0.5, 0.5-dist*(i+1), 0.5-dist*(j+1)); glVertex3f(tx-0.5, ty+0.5-dist*(i+1), 0.5-dist*(j+1));
glVertex3f(-0.5, 0.5-dist*(i+1), 0.5-dist*j); glVertex3f(tx-0.5, ty+0.5-dist*(i+1), 0.5-dist*j);
glVertex3f(-0.5, 0.5-dist*i, 0.5-dist*j); glVertex3f(tx-0.5, ty+0.5-dist*i, 0.5-dist*j);
} }
} }
//unten //-y //unten //-y
GLfloat magenta[] = {1,0,1}; GLfloat magenta[] = {1,0,1};
glMaterialfv(GL_FRONT,GL_DIFFUSE,magenta); glMaterialfv(GL_FRONT,GL_DIFFUSE,magenta);
glNormal3f(0,-1,0);
for (int i = 0; i < tesselation; i++){ for (int i = 0; i < tesselation; i++){
for (int j = 0; j < tesselation; j++){ for (int j = 0; j < tesselation; j++){
glVertex3f(0.5-dist*i, -0.5, 0.5-dist*(j+1)); glVertex3f(tx+0.5-dist*i, ty-0.5, 0.5-dist*(j+1));
glVertex3f(0.5-dist*i, -0.5, 0.5-dist*j); glVertex3f(tx+0.5-dist*i, ty-0.5, 0.5-dist*j);
glVertex3f(0.5-dist*(i+1), -0.5, 0.5-dist*j); glVertex3f(tx+0.5-dist*(i+1), ty-0.5, 0.5-dist*j);
glVertex3f(0.5-dist*(i+1), -0.5, 0.5-dist*(j+1)); glVertex3f(tx+0.5-dist*(i+1), ty-0.5, 0.5-dist*(j+1));
} }
} }
...@@ -199,28 +214,31 @@ void MyGLWidget::paintGL(){ ...@@ -199,28 +214,31 @@ void MyGLWidget::paintGL(){
void MyGLWidget::resizeGL(int width, int height){ void MyGLWidget::resizeGL(int width, int height){
double p = (double)width / (double)height; double p = (double)width / (double)height;
qDebug() << "Resize to " << width << "," << height << ", Perspective: " << p; qDebug() << "Resize to " << width << "," << height << ", Perspective: " << p;
//old:
// GLInt x = 0;//The lower-left corner of the viewport rectangle, in pixels. The default is (0,0).
// GLInt y = 0;//The lower-left corner of the viewport rectangle, in pixels. The default is (0,0).
// glViewport(x,y,width,height);//The width of the viewport. When an OpenGL context is first attached to a window, width and height are set to the dimensions of that window.
glViewport(0,0,width,height); glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);//from HelloGL example
glLoadIdentity(); glLoadIdentity();
gluPerspective(45.0,p,0.1,1000);//TODO komisch: wenn schmaler als hoch auf einmal grau. gluPerspective(45.0,p,0.1,1000);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
screenCenter = QPoint((double)width/2.0,(double)height/2.0);//lieber zu oft casten bevors nicht tut...
} }
void MyGLWidget::mousePressEvent(QMouseEvent *event){ void MyGLWidget::mousePressEvent(QMouseEvent *event){
rightButtonPressed = false; rightButtonPressed = false;
leftButtonPressed = false;
if (event->button() == Qt::RightButton){ if (event->button() == Qt::RightButton){
rightButtonPressed = true; rightButtonPressed = true;
clickStartPosition = event->pos(); clickStartPosition = event->pos();
qDebug() << "mouse press at " << clickStartPosition; qDebug() << "mouse press at " << clickStartPosition;
} else if (event->button() == Qt::LeftButton){
leftButtonPressed = true;
clickStartPosition = event->pos();
} }
} }
void MyGLWidget:: mouseMoveEvent(QMouseEvent *event){ void MyGLWidget:: mouseMoveEvent(QMouseEvent *event){
...@@ -229,11 +247,73 @@ void MyGLWidget:: mouseMoveEvent(QMouseEvent *event){ ...@@ -229,11 +247,73 @@ void MyGLWidget:: mouseMoveEvent(QMouseEvent *event){
QPoint currentPosition = event->pos(); QPoint currentPosition = event->pos();
QPoint diff = currentPosition - clickStartPosition; QPoint diff = currentPosition - clickStartPosition;
clickStartPosition = currentPosition; clickStartPosition = currentPosition;
translationX -= 0.01*diff.x(); tx += 0.01*diff.x();
translationY += 0.01*diff.y(); ty -= 0.01*diff.y();
updateGL();
}else if (leftButtonPressed){
//according to https://www.opengl.org/wiki/Object_Mouse_Trackball
double radius = std::min(screenCenter.x(),screenCenter.y());
//translate touches around screen center
double xOld = ((double)(clickStartPosition.x() - screenCenter.x()));
double yOld = ((double)(clickStartPosition.y() - screenCenter.y()));
QPoint newPosition = event->pos();
double xNew = ((double)(newPosition.x() - screenCenter.x()));
double yNew = ((double)(newPosition.y() - screenCenter.y()));
clickStartPosition = newPosition;
//https://www.opengl.org/wiki/Object_Mouse_Trackball#Sit_and_spin
//compute z coordinates ether on sphere or on hyperbolic sheet
double zOld, zNew;
double rsquareover2 = radius*radius/2.0;
double xyOld = xOld*xOld + yOld*yOld;
double xyNew = xNew*xNew + yNew*yNew;
if (xyOld < rsquareover2){
zOld = sqrt(radius*radius - xyOld);
}else{
zOld = rsquareover2/(sqrt(xyOld));
}
if(xyNew < rsquareover2){
zNew = sqrt(radius*radius - xyNew);
}else{
zNew = rsquareover2/sqrt(xyNew);
}
// set V_1 and V_2 (Vectors on Sphere around screen center, corresponding to input
QVector3D v1 = QVector3D(xOld,yOld,zOld);
v1.normalize();
QVector3D v2 = QVector3D(xNew,yNew,zNew);
v2.normalize();
//Compute normal of plane through v1 and v2 -> rotation axis
QVector3D n = QVector3D::crossProduct(v1,v2);
n.normalize();
//and theta (angle between v1 and v2)
double theta = acos(QVector3D::dotProduct(v1,v2));
//Accumulate Rotation
QQuaternion q = QQuaternion(cos(theta/2.0),sin(theta/2)*n);
q.normalize();
/*
* Wikipedia: Two rotation quaternions can be combined into
* one equivalent quaternionby the relation:
* q' = q_2*q_1'
* in which q′ corresponds to the rotation q1 followed by the rotation q2.
* (Note that quaternion multiplication is not commutative.)
*/
qubeRotationQuaternion = q*qubeRotationQuaternion;
qubeRotationQuaternion.normalize();
updateGL(); updateGL();
} }
qDebug() << "mouse move button " << event->button();
} }
//4.1.2 User Input: Zooming //4.1.2 User Input: Zooming
...@@ -278,3 +358,11 @@ void MyGLWidget::setTessellation(int t){ ...@@ -278,3 +358,11 @@ void MyGLWidget::setTessellation(int t){
tesselation = t; tesselation = t;
updateGL(); updateGL();
} }
void MyGLWidget::resetCamera(){
qubeRotationQuaternion = QQuaternion();
tx = 0;
ty = 0;
cameraZoom = cameraZoomDefault;
updateGL();
}
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#include <gl/GLU.h> #include <gl/GLU.h>
#include <QDebug> #include <QDebug>
#include <QWheelEvent> #include <QWheelEvent>
#include <QQuaternion>
#include <QMatrix4x4>
#include <math.h>
#include <QVector3D>
class MyGLWidget : public QGLWidget class MyGLWidget : public QGLWidget
{ {
...@@ -28,11 +32,22 @@ protected: ...@@ -28,11 +32,22 @@ protected:
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
private: private:
//tesselation slider
int tesselation; int tesselation;
//zoom camera
const double cameraZoomDefault = -5;
double cameraZoom; double cameraZoom;
//translate camera
QPoint clickStartPosition; QPoint clickStartPosition;
bool rightButtonPressed; bool rightButtonPressed;
double translationX, translationY; double tx, ty;
//rotate cube
bool leftButtonPressed;
QQuaternion qubeRotationQuaternion;
QPoint screenCenter;//Center of screen in pixel coordinates
public slots: public slots:
...@@ -42,6 +57,7 @@ public slots: ...@@ -42,6 +57,7 @@ public slots:
void shadeGouraudSlot(); void shadeGouraudSlot();
void shadePhongSlot(); void shadePhongSlot();
void setTessellation(int t); void setTessellation(int t);
void resetCamera();
}; };
#endif // GLWIDGET_H #endif // GLWIDGET_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment