Revert "Use fabs() for floats, not abs()".
[agianapa.git] / sphere-orbit / myglwidget.cpp
blob383f3e03035ef939b9cb88114182c09ab3dedf00
1 #include <iostream>
2 #include <QKeyEvent>
3 #include <QtOpenGL>
5 #include <cmath>
6 #include "myglwidget.h"
8 MyGLWidget::MyGLWidget(QWidget *parent)
9 : QGLWidget(parent)
11 std::cout << "GLWidget() constructor\n";
13 nStacks = 10;
14 nSlices = 10;
16 xRot = 0.0f;
17 yRot = 0.0f;
18 zRot = 0.0f;
21 thread.setData(&this->data);
22 thread.start();
24 // Setup timer
25 connect(&timer, SIGNAL(timeout()), this, SLOT(pullData()));
26 timer.start(10);
28 this->setMinimumWidth(300);
29 this->setMinimumHeight(300);
32 MyGLWidget::~MyGLWidget()
34 std::cout << "~GLWidget() deconstructor\n";
37 void MyGLWidget::setNumOfStacks(int dir)
39 std::cout << "myglWidget::setNumOfStacks()" << std::endl;
41 nStacks += dir;
42 if (nStacks < 4)
43 nStacks = 3;
45 makeCurrent();
46 glClear(GL_COLOR_BUFFER_BIT);
47 drawSphere(nStacks, nSlices, 0.5f);
48 updateGL();
51 void MyGLWidget::setNumOfSlices(int dir)
53 std::cout << "myglWidget::setNumOfSlices()" << std::endl;
55 nSlices += dir;
56 if (nSlices < 4)
57 nSlices = 3;
59 makeCurrent();
60 glClear(GL_COLOR_BUFFER_BIT);
61 drawSphere(nStacks, nSlices, 0.5f);
62 updateGL();
65 void MyGLWidget::rotateX(GLfloat angle)
67 std::cout << "MyGLWidget::rotateX()\n";
69 xRot += angle;
70 updateGL();
73 void MyGLWidget::rotateY(GLfloat angle)
75 std::cout << "MyGLWidget::rotateY()\n";
77 yRot += angle;
78 updateGL();
81 void MyGLWidget::rotateZ(GLfloat angle)
83 std::cout << "MyGLWidget::rotateZ()\n";
85 zRot += angle;
86 updateGL();
89 void MyGLWidget::initializeGL()
91 std::cout << "MyGLWidget::initializeGL()\n";
93 // Enable backface culling
94 glEnable(GL_CULL_FACE);
96 // Clear color is set to black
97 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
98 glShadeModel(GL_SMOOTH);
100 // Reset modelview matrix
101 glMatrixMode(GL_MODELVIEW);
102 glLoadIdentity();
104 // We don't need to call drawSphere() here,
105 // since the resizeGL() will be called upon
106 // the initial creation of the window.
109 void MyGLWidget::paintGL()
111 std::cout << "MyGLWidget::paintGL()\n";
113 // Clear scene
114 glClear(GL_COLOR_BUFFER_BIT);
116 // Reset modelview matrix
117 glMatrixMode(GL_MODELVIEW);
118 glLoadIdentity();
120 // Rotate appropriately
121 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
122 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
123 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
125 // Draw x, y, z axis
126 drawAxis();
128 // Draw sphere
129 drawSphere(nStacks, nSlices, 0.5f);
131 glFlush();
134 void MyGLWidget::resizeGL(int width, int height)
136 std::cout << "MyGLWidget::resizeGL()\n";
137 std::cout << "New width = " << width
138 << "\nNew height = " << height << "\n";
140 // Update viewport to cover the whole screen
141 glViewport(0, 0, width, height);
143 // Reset projection matrix
144 glMatrixMode(GL_PROJECTION);
145 glLoadIdentity();
146 //gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
148 // Reset modelview matrix
149 glMatrixMode(GL_MODELVIEW);
150 glLoadIdentity();
153 void MyGLWidget::drawAxis(void)
155 // Draw axis
156 glLineWidth(3);
157 glEnable(GL_LINE_SMOOTH);
158 glColor3f(0.0f, 1.0f, 0.0f);
160 glBegin(GL_LINES);
161 glVertex3f(0.0f, 0.0f, 0.0f); // x axis
162 glVertex3f(1.0f, 0.0f, 0.0f);
164 glVertex3f(0.0f, 0.0f, 0.0f); // y axis
165 glVertex3f(0.0f, 1.0f, 0.0f);
167 glVertex3f(0.0f, 0.0f, 0.0f); // z axis
168 glVertex3f(0.0f, 0.0f, 1.0f);
169 glEnd();
171 // Restore color and line width
172 glColor3f(1.0f, 1.0f, 1.0f);
173 glDisable(GL_LINE_SMOOTH);
174 glLineWidth(1);
177 void MyGLWidget::drawSphere(GLuint nStacks, GLuint nSlices, GLfloat r)
179 GLfloat theta, phi, x, y, z, stepTheta, stepPhi;
181 stepTheta = M_PI / nStacks;
182 stepPhi = 2 * M_PI / nSlices;
184 for (theta = 0; theta <= M_PI; theta += stepTheta) {
185 glBegin(GL_QUAD_STRIP);
186 for (phi = 0; phi <= 2.0 * M_PI + 0.1; phi += stepPhi) {
187 x = r * sin(theta) * cos(phi);
188 y = r * sin(theta) * sin(phi);
189 z = r * cos(theta);
190 glVertex3f(x, y, z);
192 x = r * sin(theta + stepTheta) * cos(phi);
193 y = r * sin(theta + stepTheta) * sin(phi);
194 z = r * cos(theta + stepTheta);
195 glVertex3f(x, y, z);
197 glEnd();
200 // The boundary edges of the polygon are drawn as line segments.
201 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
204 void MyGLWidget::pullData(void)
206 float r;
208 mutex.lock();
209 if (!data.isEmpty()) {
210 r = data.dequeue();
211 //std::cout << "r = " << r << std::endl;
212 xRot = yRot = zRot = r;
214 else {
215 mutex.unlock();
216 std::cout << "MyGLWidget::pullData()\t[WAKING THREAD]\n";
217 thread.condition.wakeOne();
218 return;
220 mutex.unlock();
221 updateGL();