"""Atividade — iluminação incremental do octaedro da Aula 07. Aula 08 — Modelos de Iluminação. Execute com: python octaedro_iluminado_base.py """ from __future__ import annotations import math import sys from PySide6.QtCore import Qt from PySide6.QtGui import QSurfaceFormat from PySide6.QtOpenGLWidgets import QOpenGLWidget from PySide6.QtWidgets import QApplication from OpenGL.GL import * from OpenGL.GLU import gluLookAt, gluPerspective VERTICES = [(0, 1.4, 0), (0, -1.4, 0), (-1, 0, 0), (0, 0, -1), (1, 0, 0), (0, 0, 1)] FACES = [ (0, 3, 2), (0, 4, 3), (0, 5, 4), (0, 2, 5), (1, 2, 3), (1, 3, 4), (1, 4, 5), (1, 5, 2), ] def normal_face(face): a, b, c = (VERTICES[i] for i in face) u = tuple(b[i] - a[i] for i in range(3)) v = tuple(c[i] - a[i] for i in range(3)) normal = (u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]) tamanho = math.sqrt(sum(componente * componente for componente in normal)) return tuple(componente / tamanho for componente in normal) class Octaedro(QOpenGLWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Octaedro iluminado | setas: rotação | Esc: sair") self.angulo = 25.0 self.setFocusPolicy(Qt.FocusPolicy.StrongFocus) def initializeGL(self): # Passo 1: a malha, a câmera e a visibilidade já estão prontas. glClearColor(0.08, 0.09, 0.12, 1.0) glEnable(GL_DEPTH_TEST) glEnable(GL_CULL_FACE) glFrontFace(GL_CCW) glCullFace(GL_BACK) glShadeModel(GL_FLAT) # TODO 2: habilite GL_LIGHTING, GL_LIGHT0 e GL_NORMALIZE. # Passo 2: elimine ambiente global e use o observador local. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (0.0, 0.0, 0.0, 1.0)) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE) glLightfv(GL_LIGHT0, GL_AMBIENT, (0.12, 0.12, 0.12, 1.0)) glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.9, 0.9, 0.9, 1.0)) glLightfv(GL_LIGHT0, GL_SPECULAR, (1.0, 1.0, 1.0, 1.0)) # TODO 4: configure GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR e # GL_SHININESS do material com glMaterialfv/glMaterialf. def resizeGL(self, w, h): dpr = self.devicePixelRatioF() w, h = max(1, round(w * dpr)), max(1, round(h * dpr)) glViewport(0, 0, w, h) glMatrixMode(GL_PROJECTION); glLoadIdentity() gluPerspective(50.0, w / float(h), 0.1, 100.0) glMatrixMode(GL_MODELVIEW) def paintGL(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity(); gluLookAt(0, 1.8, 5, 0, 0, 0, 0, 1, 0) # TODO 3a: envie GL_POSITION = (3.0, 4.0, 5.0, 1.0) aqui. glRotatef(self.angulo, 0, 1, 0) glColor3f(0.85, 0.45, 0.20) # visível apenas enquanto LIGHTING está desligado glBegin(GL_TRIANGLES) for face in FACES: # TODO 3b: envie normal_face(face) com glNormal3f antes dos vértices. for indice in face: glVertex3f(*VERTICES[indice]) glEnd() def keyPressEvent(self, event): if event.key() == Qt.Key.Key_Escape: self.close(); return if event.key() == Qt.Key.Key_Left: self.angulo -= 5 elif event.key() == Qt.Key.Key_Right: self.angulo += 5 else: return self.update() def main(): fmt = QSurfaceFormat(); fmt.setVersion(2, 1) fmt.setProfile(QSurfaceFormat.OpenGLContextProfile.NoProfile); fmt.setDepthBufferSize(24) QSurfaceFormat.setDefaultFormat(fmt) app = QApplication(sys.argv); janela = Octaedro(); janela.resize(800, 600); janela.show() return app.exec() if __name__ == "__main__": raise SystemExit(main())