2016-07-31 8 views
-1

Как новичок в QT + OpenGL с использованием QOpenGLWidget, я не могу покрасить свой треугольник. Пожалуйста, найти свой код здесь, используя QMainWindow для GUI ...Qt OpenGL (QOpenGLWidget) - Простой треугольник

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

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

Здесь GUI - окно

// 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 

Здесь реализация - файл ...

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

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

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

Вот рендеринг виджета Opengl-Context.

#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 

Вот файл реализации ...

#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); 
} 

Здесь оказанной треугольник просто белый. Я не могу понять, скомпилирован ли шейдер и связаны ли атрибуты, но все же я не могу пометить треугольник.

Если я могу получить руководство ... ??? Output

+0

Проверки на успех ваших шейдерных сборников. Эти шейдеры не будут компилироваться с совместимой реализацией OpenGL. Прецизионные квалификаторы не поддерживаются в GLSL 1.10, это то, что вы используете, если вы не укажете версию шейдера. –

+0

Я проверил, флаг возврата ** addShaderFromSourceCode ** - это правда. – Saket

+0

Вам повезло тогда, в том смысле, что реализация OpenGL не обнаруживает ошибку. Это может сильно потерпеть неудачу на другой платформе. Другая проблема заключается в том, что вы используете результат 'attributeLocation()' для мест расположения атрибутов в некоторых местах, но в других случаях используются жесткие значения, например вызовы 'glEnableVertexAttribArray()'. –

ответ

0

Давайте посмотрим, что делают ваши шейдеры. Ваш фрагмент шейдера:

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

Так будет принимать col выход каждой вершины, интерполированное для каждого фрагмента в примитив, и использовать это как окончательный цвет.

Теперь ваши вершинные шейдеры:

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

Это ясно красный. Тот факт, что вы добавили некоторый атрибут ввода colAttr, и указать для него некоторый массив вершин, абсолютно неактуальен, пока вы фактически не используете этот атрибут - в настоящее время это неактивный атрибут, который просто оптимизирован, поскольку он никогда не влияет на любой выход.

UPDATE

Если вы получаете белый треугольник, это свидетельствовало о том, что ваши шейдеры даже вообще не используются. Существует mprogram->release() звонок в вашем paintGL методе, но вы никогда не на самом деле включить программы, поэтому он не будет использоваться.

+1

'(1, 0, 0, 1)' красный, а не белый. –

+0

@RetoKoradi: omg, я этого даже не заметил. Тогда должно быть что-то еще неправильное. – derhass

+0

@derhass: Hii! Я благодарен за ваш ответ. Я заметил ваши 2 балла Point-1: (При тестировании ColAttr - я горжусь его жестко-красным цветом.), Если компилятор оптимизирует его для «colAttr». Треугольник, по крайней мере, красный. Point-2: Как я считаю, вы указываете на: // m_program-> bind(); m_program-> bind(); Если я раскомментирую его (как определение: эквивалентно вызову glUseProgram().) Треугольник не отображался. – Saket

0

Может быть, вы можете использовать

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

вместо

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

Если вы пишете в шейдере

gl_FragColor = col; 

цв = Col, colAttr!= Col

Изменить имя атрибута, и если это не поможет изменить этот вызов в initializeGL

program->release(); 

в

program->bind(); 
Смежные вопросы