Rendering 2D com OpenGL e interface gráfica em Qt
Qt Framework multiplataforma para desenvolvimento de interfaces gráficas em C++ https://www.qt.io/ 2
Ferramentas Qt Creator IDE (Ambiente Integrado de Desenvolvimento) multiplataforma, desenhado para as necessidades dos desenvolvedores de Qt. https://www.qt.io/download-open-source/ Qt Designer Ferramenta gráfica de criação de interfaces incluída no Qt Creator. 3
Módulos 4
Hello World! #include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); QPushButton hello( "Hello world!", 0 ); hello.resize( 100, 30 ); } a.setmainwidget( &hello ); hello.show(); return a.exec(); 5
Signals e Slots Mecanismo de comunicação entre objetos QT Um sinal é emitido quando algum evento particular ocorre. Os widgets do QT já possuem muitos sinais predefinidos, mas sempre podemos adicionar nossos próprios sinais às nossas subclasses. Não devem ser implementados; Sempre retornam void; Devem ser chamados com emit signal_name(parameter), quando necessário. Um slot é uma função chamada em resposta a um sinal em particular. Novamente, os widgets do QT já possuem muitos slots predefinidos, mas comumente criamos nossos próprios slots para lidar com os sinais que nos interessam. A conexão entre signals e slots é feita com connect, como por exemplo: QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); 6
Signals e Slots class MyClass : public QObject { Q_OBJECT //Macro obrigatória, sem ponto-e-vírgula... signals: void somethinghappened();... public slots: void slotdosomething();... private slots: void slotdosomethinginternal();... }; 7
OpenGL API para interface com hardware gráfico, independente de plataforma e de sistemas de janelas. 8
Rendering Pipeline Sequência de etapas para renderizar (desenhar) objetos Etapas programáveis Etapas opcionais 9
Transformações 10
Projeção perspectiva x Projeção ortográfica 11
Projeção perspectiva x Projeção ortográfica P = f aspect 0 0 0 0 f 0 0 0 0 far + near 2 near far near far near far 0 0 1 0, onde f = cot fovy 2 QMatrix4x4 view; view.perspective(fovy,aspect, near,far); O = 2 right left 0 0 0 right + left 0 0 right left 2 top + bottom 0 top bottom top bottom 2 far + near far near far near 0 0 0 1 QMatrix4x4 view; view.ortho(left,right, bottom,top,near,far); 12
Vertex Shader Processa VÉRTICES individualmente. Entrada: atributos de vértice. layout( location = #) in type var_name; Saída built-in: gl_position Uso: Tipicamente para realizar transformações geométricas para o espaço de projeção, e algumas vezes para realizar iluminação por vértice. 13
Vertex Shader #version 330 core layout( location = 0 ) in vec3 vertexpos; uniform mat4 transformmatrix; void main() { gl_position = transformmatrix * vec4( vertexpos, 1 ); } 14
Fragment Shader Processa FRAGMENTOS individualmente, resultantes do processo de rasterização. Um fragmento de entrada -> um fragmento de saída. Saída: um valor de depth (depth value) e zero ou mais cores. Uso: Tipicamente para realizar iluminação por fragmento. 15
Fragment Shader #version 330 core uniform vec3 color; out vec3 finalcolor; void main() { finalcolor = color; } 16
QT + OpenGL Classe QOpenGLWidget Provê funcionalidades para desenhar utilizando OpenGL Herde da classe QOpenGLWidget (e possivelmente de QOpenGLFunctions) e implemente os métodos: void initializegl() override; void paintgl() override; void resizegl(int width, int height) override; Implemente os eventos de mouse que forem necessários para a sua aplicação: void mousepressevent(qmouseevent *) override; void mousemoveevent(qmouseevent *event) override; void mousereleaseevent(qmouseevent *event) override; 17
QT + OpenGL QOpenGLShaderProgram Encapsula compilação e linkagem de shaders QOpenGLShaderProgram* program = new QOpenGLShaderProgram(); program->addshaderfromsourcecode(qopenglshader::vertex, vertexshadersource); program->addshaderfromsourcecode(qopenglshader::fragment, fragmentshadersource); program->link(); QOpenGLBuffer Encapsula criação e gerenciamento de OpenGL buffer objects QOpenGLBuffer pointsbuffer; pointsbuffer.create(); pointsbuffer.bind(); pointsbuffer.allocate( &points[0], (int)points.size()*sizeof(qvector3d) ); 18
QT + OpenGL Desenhando: program->bind(); glclearcolor(0, 0, 0, 1); glclear(gl_color_buffer_bit); if(!points.empty() && pointsbuffer.iscreated()) { pointsbuffer.bind(); pointsbuffer.allocate( &points[0],(int)points.size()*sizeof(qvector3d) ); program->enableattributearray(0); program->setattributebuffer(0,gl_float,0,3,sizeof(qvector3d)); program->setuniformvalue("color", QVector3D(1,0,0)); } gldrawarrays(gl_line_strip, 0, (int)points.size()); 19