2016-07-31 29 views
-1

Als Newbee zu QT + OpenGL mit QOpenGLWidget kann ich mein Dreieck nicht färben. Finden Sie hier meinen Code, mit QMainWindow für GUI ...Qt OpenGL (QOpenGLWidget) - Einfaches Dreieck

// main.cpp 
#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 

Hier wird die GUI - Fenster

// MainWindow.h 
#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

Hier Implementierung - Datei ...

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

Hier ist die Widget Rendering OpenGL-Kontext. Hier

#ifndef OPENGLWIDGET_H 
#define OPENGLWIDGET_H 

#include <QWidget> 
#include <QOpenGLWidget> 
#include <QOpenGLFunctions> 
#include <QOpenGLContext> 
#include <QOpenGLShaderProgram> 
#include <QOpenGLBuffer> 
#include <QOpenGLVertexArrayObject> 
#include <QMatrix4x4> 

class OpenglWidget : public QOpenGLWidget, public QOpenGLFunctions 
{ 
public: 
    OpenglWidget(QWidget *parent = 0); 
    ~OpenglWidget(); 

protected: 
    void initializeGL(); 
    void resizeGL(int width, int height); 
    void paintGL(); 
    GLuint m_posAttr; 
    GLuint m_colAttr; 
    GLuint m_matrixUniform; 
    QOpenGLShaderProgram *m_program; 
}; 
#endif // OPENGLWIDGET_H 

ist die Implementierung-Datei ...

#include "openglwidget.h" 


OpenglWidget::OpenglWidget(QWidget *parent) : 
    QOpenGLWidget(parent) 
{ 
    setFormat(QSurfaceFormat::defaultFormat()); 
} 

OpenglWidget::~OpenglWidget() 
{ 
} 

static const char *vertexShaderSource = 
    "attribute highp vec4 posAttr;\n" 
    "attribute lowp vec4 colAttr;\n" 
    "varying lowp vec4 col;\n" 
    "uniform highp mat4 matrix;\n" 
    "void main() {\n" 
    " col = vec4(1, 0, 0, 1);\n" 
    " gl_Position = matrix * posAttr;\n" 
    "}\n"; 

static const char *fragmentShaderSource = 
    "varying lowp vec4 col;\n" 
    "void main() {\n" 
    " gl_FragColor = col;\n" 
    "}\n"; 

void OpenglWidget::initializeGL() 
{ 
    makeCurrent(); 
    initializeOpenGLFunctions(); 
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 

    // Create Shader (Do not release until VAO is created) 
    m_program = new QOpenGLShaderProgram(this); 
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource); 
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource); 
    m_program->link(); 
    m_posAttr = m_program->attributeLocation("posAttr"); 
    m_colAttr = m_program->attributeLocation("colAttr"); 
    m_matrixUniform = m_program->attributeLocation("matrix"); 

    m_program->release(); 
} 

void OpenglWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    makeCurrent(); 

    //m_program->bind(); 

    QMatrix4x4 matrix; 
    matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f); 
    matrix.translate(0, 0, -2); 

    m_program->setUniformValue(m_matrixUniform, matrix); 

    GLfloat vertices[] = { 
     0.0f, 0.707f, 0.0f, 
     -0.5f, -0.5f, 0.0f, 
     0.5f, -0.5f, 0.0f 
    }; 

    GLfloat colors[] = { 
     1.0f, 0.0f, 0.0f, 
     0.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 1.0f 
    }; 

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices); 
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(0); 

    m_program->release(); 
} 

void OpenglWidget::resizeGL(int width, int height) 
{ 
    glViewport(0, 0, width, height); 
} 

Hier das gerenderte Dreieck nur weiß ist. Ich kann nicht verstehen, ob der Shader kompiliert ist und Attribute verknüpft sind, aber ich kann das Dreieck nicht färben.

Wenn ich irgendeine Anleitung bekommen kann ... ??? Output

+0

prüfen Erfolg Ihrer Shader-Compilations. Diese Shader werden nicht mit einer konformen OpenGL-Implementierung kompiliert. Präzisions-Qualifier werden in GLSL 1.10 nicht unterstützt. Dies ist der Fall, wenn Sie keine Shader-Version angeben. –

+0

Ich habe überprüft, das Rückgabeflag von ** addShaderFromSourceCode ** ist es stimmt. – Saket

+0

Sie haben Glück, in dem Sinne, dass die OpenGL-Implementierung den Fehler nicht erkennt. Es könnte auf einer anderen Plattform scheitern. Ein weiteres Problem ist, dass Sie das Attribut 'attributeLocation()' für die Attributpositionen an einigen Stellen verwenden, aber festverdrahtete Werte in anderen, wie die 'glEnableVertexAttribArray()' Aufrufe. –

Antwort

0

Schauen wir uns an, was Ihre Shader machen. Ihr Fragment-Shader:

varying lowp vec4 col; 
[...] 
    gl_FragColor = col; 

So dauert es, bis die col Ausgang jedes Vertex, für jedes Fragment in der primitiven interpoliert und verwenden, die als die endgültige Farbe.

nun Ihre Vertex-Shader:

col = vec4(1, 0, 0, 1); 

Das rot klar ist. Die Tatsache, dass Sie ein Eingabe-Attribut colAttr hinzugefügt und ein Vertex-Array dafür angegeben haben, ist völlig irrelevant, solange Sie dieses Attribut nicht tatsächlich verwenden - derzeit ist es ein inaktives Attribut, das nur optimiert wird, da es nie beeinflusst jede Ausgabe.

UPDATE

Wenn Sie ein weißes Dreieck erhalten, angedeutet dies, dass Ihre Shadern nicht einmal überhaupt verwendet werden. Es ist ein mprogram->release() Aufruf in Ihrer paintGL Methode, aber Sie nie wirklich aktivieren Sie das Programm, so dass es nicht verwendet wird.

+1

'(1, 0, 0, 1)' ist rot, nicht weiß. –

+0

@RetoKoradi: omg, das habe ich nicht einmal bemerkt. Da muss etwas anderes falsch sein. – derhass

+0

@derhass: Hii! Ich bin dankbar für Ihre freundliche Antwort. Ich bemerkte Ihre 2 Punkte Point-1: (Während des Tests der ColAttr - ich Magd es hartcodiert auf rote Farbe.), Wenn der Compiler es für die "colAttr" zu optimieren. Das Dreieck wird zumindest rot. Punkt-2: Wie ich glaube, verweisen Sie auf: // m_program-> bind(); m_Programm-> bind(); Wenn ich es auskommentiere (wie die Definition: gleichbedeutend mit dem Aufruf von glUseProgram().), Wurde das Dreieck nicht gerendert. – Saket

0

Vielleicht können Sie

m_colAttr = m_program->attributeLocation("col"); 

statt

m_colAttr = m_program->attributeLocation("colAttr"); 

Wenn Sie Shader

gl_FragColor = col; 

col = col, colAttr schreiben in verwenden!= Col

ändern Name des Attributs, und wenn dies dazu beitragen, diesen Aufruf nicht in initializeGL ändern

program->release(); 

zu

program->bind();