-
Notifications
You must be signed in to change notification settings - Fork 0
/
Piramide.cpp
265 lines (232 loc) · 9.13 KB
/
Piramide.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#include "piramide.h"
#include <QKeyEvent>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <QTimer>
GLint LAST_NVL=45;//ultimo nivel da pirâmide
GLfloat escala=1;
float yrot=0.0;
GLint DLid;
// Constructor
Piramide::Piramide() {
setWindowTitle("Piramide");
timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, SIGNAL(timeout()),this,SLOT(updateGL()));
}
// Empty destructor
Piramide::~Piramide() {}
// Initialize OpenGL
void Piramide::initializeGL() {
glShadeModel(GL_SMOOTH); // Enable smooth shading
qglClearColor(Qt::white); // Set the clear color to a black background
glClearDepth(1.0f); // Depth buffer setup
glEnable(GL_DEPTH_TEST); // Enable depth testing
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Habilita o uso de texturas
glEnable(GL_TEXTURE_2D);
//carrega uma imagem BMP
QImage imgBloco = convertToGLFormat(QImage("bloco.jpg"));
QImage imgCeu = convertToGLFormat(QImage("ceu.jpg"));
QImage imgSolo = convertToGLFormat(QImage("solo.jpg"));
//definir a forma de armazenamento dos pixeis na textura (1 = alinhamento por byte)
glGenTextures(1, &_texturaBloco); //Make room for our texture
//define a textura corrente
glBindTexture(GL_TEXTURE_2D,_texturaBloco);
//GL_TEXTURE_2D ==> define que será usanda uma textura 2D (bitmaps)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgBloco.width(), imgBloco.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgBloco.bits());
//definir a forma de armazenamento dos pixeis na textura (1 = alinhamento por byte)
glGenTextures(1, &_texturaCeu); //Make room for our texture
//define a textura corrente
glBindTexture(GL_TEXTURE_2D, _texturaCeu);
//GL_TEXTURE_2D ==> define que será usanda uma textura 2D (bitmaps)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgCeu.width(), imgCeu.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgCeu.bits());
//definir a forma de armazenamento dos pixeis na textura (1 = alinhamento por byte)
glGenTextures(1, &_texturaSolo); //Make room for our texture
//define a textura corrente
glBindTexture(GL_TEXTURE_2D, _texturaSolo);
//GL_TEXTURE_2D ==> define que será usanda uma textura 2D (bitmaps)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgSolo.width(), imgSolo.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgSolo.bits());
// Set up lighting
GLfloat ambLight[] = {1, 1, 1, 1.0f};
GLfloat diffLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat lightPos[] = {0, 100, 0 , 0.0f};
// Ativa o uso da luz ambiente
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambLight);
glLightfv(GL_LIGHT1, GL_AMBIENT, ambLight);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffLight);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
// Habilita a definição da cor do material a partir da cor corrente
glEnable(GL_COLOR_MATERIAL);
//Habilita o uso de iluminação
glEnable(GL_LIGHTING);
// Habilita a luz de número 1
glEnable(GL_LIGHT1);
// Habilita o depth-buffering
glEnable(GL_DEPTH_TEST);
DLid = createDL(); //cria lista
}
// This is called when the OpenGL window is resized
void Piramide::resizeGL(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset projection matrix
gluPerspective(45.0f, static_cast<GLfloat>(width)/height, 5.f, LAST_NVL*10); // Calculate aspect ratio
// Especifica posição do observador e do alvo
gluLookAt(0.f,0.f,LAST_NVL+100, 0,-40,0, 0,1,0);
}
// OpenGL painting code goes here
void Piramide::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glScalef(escala, escala, escala);
escala=1;//para impede o aumento da escala no proximo frame
// Desenha Ceu
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, _texturaCeu);
glTranslatef(0,0,-200);
glBegin(GL_QUADS);
glTexCoord3f(0,0,0);glVertex3f(-2000,1000,0);
glTexCoord3f(1,0,0);glVertex3f(2000,1000,0);
glTexCoord3f(1,1,0);glVertex3f(1000,-1000,0);
glTexCoord3f(0,1,0);glVertex3f(-1000,-1000,0);
glEnd();
glPopMatrix();
glRotatef(yrot, 0.0, 1.0, 0.0);
//Desenha solo
glBindTexture(GL_TEXTURE_2D, _texturaSolo);
glBegin(GL_QUADS);
glTexCoord3f(0,0,0);glVertex3f(-400,-46,400);
glTexCoord3f(1,0,0);glVertex3f(-400,-46,-400);
glTexCoord3f(1,1,0);glVertex3f(400,-46,-400);
glTexCoord3f(0,1,0);glVertex3f(400,-46,400);
glEnd();
glCallList(DLid); //chama lista de exibição
if ( yrot != 0.0 ) {//economizar processamento quando não tem mudança no angulo da piramide
timer->start(30);
}
}
// Key handler
void Piramide::keyPressEvent(QKeyEvent *event) {
switch (event->key()) {
case Qt::Key_Up:
escala=1.1;
break;
case Qt::Key_Down:
escala=0.91;
break;
case Qt::Key_Right:
yrot += 1;
if (yrot > 360)
yrot = 0.0;
break;
case Qt::Key_Left:
yrot -= 1;
if (yrot > 360)
yrot = 0.0;
break;
case Qt::Key_Escape:
close(); // Quit on Escape
break;
case Qt::Key_F1:
setWindowState(windowState() ^ Qt::WindowFullScreen); // Toggle fullscreen on F1
break;
default:
QGLWidget::keyPressEvent(event); // Let base class handle the other keys
}
updateGL();
}
void Piramide::changeEvent(QEvent *event) {
switch (event->type()) {
case QEvent::WindowStateChange:
// Hide cursor if the window is fullscreen, otherwise show it
if (windowState() == Qt::WindowFullScreen)
setCursor(Qt::BlankCursor);
else if(windowState() == Qt::WindowMaximized) {
update();
}
else
unsetCursor();
break;
default:
break;
}
}
void Piramide::desenhaCubo() {
//Base
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,0);glVertex3f(0,-1,0);
glTexCoord3f(1,0,0);glVertex3f(0,-1,1);
glTexCoord3f(1,1,0);glVertex3f(1,-1,1);
glTexCoord3f(0,1,0);glVertex3f(1,-1,0);
glEnd();
//Front
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,0);glVertex3f(1,-1,1);
glTexCoord3f(1,0,0);glVertex3f(1,-1,0);
glTexCoord3f(1,1,0);glVertex3f(1,0,0);
glTexCoord3f(0,1,0);glVertex3f(1,0,1);
glEnd();
// Back
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,0);glVertex3f(0,-1,1);
glTexCoord3f(1,0,0);glVertex3f(0,-1,0);
glTexCoord3f(1,1,0); glVertex3f(0,0,0);
glTexCoord3f(0,1,0);glVertex3f(0,0,1);
glEnd();
// Top
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,0);glVertex3f(0,0,1);
glTexCoord3f(1,0,0);glVertex3f(0,0,0);
glTexCoord3f(1,1,0);glVertex3f(1,0,0);
glTexCoord3f(0,1,0); glVertex3f(1,0,1);
glEnd();
// Left
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,1);glVertex3f(0,-1,1);
glTexCoord3f(1,0,1); glVertex3f(1,-1,1);
glTexCoord3f(1,1,1);glVertex3f(1,0,1);
glTexCoord3f(0,1,1);glVertex3f(0,0,1);
glEnd();
// Right
glBegin(GL_QUADS); // Wall
glTexCoord3f(0,0,1);glVertex3f(0,-1,0);
glTexCoord3f(1,0,1); glVertex3f(1,-1,0);
glTexCoord3f(1,1,1);glVertex3f(1,0,0);
glTexCoord3f(0,1,1); glVertex3f(0,0,0);
glEnd();
}
GLuint Piramide::createDL() {
GLuint blockDL;
blockDL = glGenLists(1); //aloca o numero de IDs
glNewList(blockDL,GL_COMPILE); //inclue na lista
glBindTexture(GL_TEXTURE_2D, _texturaBloco);
for (int nvl = 0; nvl < LAST_NVL; nvl++ ){//para determinar o nivel atual da piramide ou o Y onde o cubo sera desenhado
for (int x=-nvl; x <= nvl ; x++) {// para determinar a coordena X onde o cubo sera desenhado
for ( int z=-nvl; z <= nvl; z++) {// para determinar a coordena Z onde o cubo sera desenhado
if( (nvl == 0 || nvl == LAST_NVL) ||
(x == -nvl || x == nvl) ||
(z == -nvl || z == nvl)
){// apenas desenhar os cubos que estão expõe a aréa externa da piramide
glTranslatef(x, -nvl, z);
desenhaCubo();
glTranslatef(-x, nvl, -z);
}
}
}
}
glEndList();
return(blockDL);
}