2015-11-17 85 views
0

嘿家伙在这里我再次。 我已经问了一个关于QOpenglWidget here的问题。 在我最后一个问题中,我只是把错误的方式叫做阴影。 现在我正试图从一个对象中加载我的顶点。 我写了一个加载器,加载顶点,纹理坐标,法线和指数。我已经写了这个代码在本机openGL和检查输出..顶点等与我的Qt代码中的匹配。 唯一的问题是,我无法使paintGL()方法绘制我的对象,它应该是一个简单的多维数据集。QOpenGLWidget绘制对象

--Main.cpp

#include <QApplication> 
#include <QLabel> 
#include <QSurfaceFormat> 

#ifndef QT_NO_OPENGL 
#include "mainwidget.h" 
#endif 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    QSurfaceFormat format; 
    format.setDepthBufferSize(24); 
    QSurfaceFormat::setDefaultFormat(format); 

    app.setApplicationName("MainWidget"); 

#ifndef QT_NO_OPENGL 
    MainWidget widget; 
    widget.resize(800, 600); 
    widget.show(); 
#else 
    QLabel note("OpenGL Support required"); 
    note.show(); 
#endif 
    return app.exec(); 
} 

--MainWidget.h

#ifndef MAINWIDGET_H 
#define MAINWIDGET_H 

#include <QOpenGLWidget> 
#include <QOpenGLFunctions> 
#include <QVector2D> 
#include <QOpenGLShaderProgram> 
#include <QOpenGLBuffer> 
#include <QVector3D> 
#include <QOpenGLVertexArrayObject> 
#include <QVector> 
#include "geometryengine.h" 


class GeometryEngine; 
class MainWidget : public QOpenGLWidget, protected QOpenGLFunctions 
{ 
    Q_OBJECT 
public: 
    MainWidget(QWidget *parent = 0); 
    ~MainWidget(); 
protected: 
    void initializeGL()Q_DECL_OVERRIDE; 
    void resizeGL(int w, int h)Q_DECL_OVERRIDE; 
    void paintGL()Q_DECL_OVERRIDE; 

    void initShaders(); 
private: 
    QOpenGLShaderProgram program; 
    GeometryEngine *geometries; 

}; 

#endif // MAINWIDGET_H 

--MainWidget.cpp

#include "mainwidget.h" 
#include <iostream> 


extern QVector<QVector3D> m_vertices; 
extern QVector<QVector2D> m_uvs; 
extern QVector<QVector3D> m_normals; 

extern QVector<QVector3D> m_indexed_vertices; 
extern QVector<QVector2D> m_indexed_uvs; 
extern QVector<QVector3D> m_indexed_normals; 
extern QVector<unsigned short> m_indices; 

MainWidget::MainWidget(QWidget *parent):QOpenGLWidget(parent), geometries(0){ 

} 

MainWidget::~MainWidget(){ 
    makeCurrent(); 
    delete geometries; 
    doneCurrent(); 
} 

void MainWidget::initializeGL(){ 
    initializeOpenGLFunctions(); 
    glClearColor(0, 0, 0.4f, 0); 
    glEnable(GL_DEPTH_TEST); 
    initShaders(); 

    geometries = new GeometryEngine; 
    for(auto i : m_indexed_vertices){ 
      std::cout<<i.x()<<" "<<i.y()<<" "<<i.z()<<std::endl; 
      //std::cout << i << " " << std::endl; 
     } 
} 

void MainWidget::resizeGL(int w, int h){ 

} 

void MainWidget::paintGL(){ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    /*for(auto i : m_indices){ 
      //std::cout<<i.x()<<" "<<i.y()<<" "<<i.z()<<std::endl; 
      std::cout << i << " " << std::endl; 
     }*/ 
    geometries->drawGeometry(&program, m_indices); 
} 


void MainWidget::initShaders(){ 
    // Compile vertex shader 
    if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, "vertex.vert")) 
     close(); 

    // Compile fragment shader 
    if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fragment.frag")) 
     close(); 

    // Link shader pipeline 
    if (!program.link()) 
     close(); 

    // Bind shader pipeline for use 
    if (!program.bind()) 
     close(); 
} 

--GeometryEngine.h

#ifndef GEOMETRYENGINE_H 
#define GEOMETRYENGINE_H 
#include <QOpenGLFunctions> 
#include <QOpenGLShaderProgram> 
#include <QOpenGLBuffer> 
#include <QOpenGLVertexArrayObject> 
#include "mainwidget.h" 


class GeometryEngine : protected QOpenGLFunctions 
{ 
public: 
    GeometryEngine(); 
    virtual ~GeometryEngine(); 

    void drawGeometry(QOpenGLShaderProgram *program, QVector<unsigned short> indices); 


private: 
    void initGeometry(const char *path, QVector<QVector3D> &vert, QVector<QVector2D> &uv, QVector<QVector3D> &norm,QVector<unsigned short> &indices, QVector<QVector3D> &indexed_vertices, 
    QVector<QVector2D> &indexed_uvs, 
    QVector<QVector3D> &indexed_normals); 

    QOpenGLBuffer arrayBuf; 
    QOpenGLBuffer indexBuf; 
    QOpenGLVertexArrayObject vertexArrayID; 

}; 

#endif // GEOMETRYENGINE_H 

--GeometryEngine.cpp

#include "geometryengine.h" 
#include "mainwidget.h" 
#include "loadobj.h" 
#include <QVector> 
#include <QVector2D> 
#include <QVector3D> 
#include <string> 
#include <iostream> 


QVector<QVector3D> m_vertices; 
QVector<QVector2D> m_uvs; 
QVector<QVector3D> m_normals; 

QVector<QVector3D> m_indexed_vertices; 
QVector<QVector2D> m_indexed_uvs; 
QVector<QVector3D> m_indexed_normals; 
QVector<unsigned short> m_indices; 

GeometryEngine::GeometryEngine() : indexBuf(QOpenGLBuffer::IndexBuffer) 
{ 


    initializeOpenGLFunctions(); 
    vertexArrayID.create(); 
    vertexArrayID.bind(); 
    //generate vbos 
    arrayBuf.create(); 
    indexBuf.create(); 


    initGeometry("cube.obj", m_vertices, m_uvs, m_normals, m_indices, m_indexed_vertices, m_indexed_uvs, m_indexed_normals); 

} 

GeometryEngine::~GeometryEngine(){ 
    arrayBuf.destroy(); 
    indexBuf.destroy(); 
    vertexArrayID.destroy(); 
} 
void GeometryEngine::initGeometry(const char *path,QVector<QVector3D> &vertices, QVector<QVector2D> &uvs, QVector<QVector3D> &normals, QVector<unsigned short> &indices, QVector<QVector3D> &indexed_vertices, QVector<QVector2D> &indexed_uvs, QVector<QVector3D> &indexed_normals){ 
    bool res = loadObj(path, vertices, uvs, normals); 
    vboIndexer(vertices, uvs, normals, indices, indexed_vertices, indexed_uvs, indexed_normals); 
    /*for(auto i : indices){ 
      //std::cout<<i.x()<<" "<<i.y()<<" "<<i.z()<<std::endl; 
      std::cout << i << " " << std::endl; 
     }*/ 
    arrayBuf.bind(); 
    arrayBuf.allocate(&indexed_vertices, indexed_vertices.size() * sizeof(QVector3D)); 

    indexBuf.bind(); 
    indexBuf.allocate(&indices, indices.size() * sizeof(unsigned short)); 

} 

void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program, QVector<unsigned short> indices){ 
    arrayBuf.bind(); 
    indexBuf.bind(); 

    int vertexLocation = program->attributeLocation("vertex"); 
    program->enableAttributeArray(vertexLocation); 
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, sizeof(GLfloat)); 

    //glDrawElements(GL_TRIANGLE_STRIP, indices.size(), GL_UNSIGNED_SHORT, 0); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glDisableVertexAttribArray(0); 
} 

--vertex.vert

#version 330 

layout(location = 0) in vec3 vertex; 

void main(){ 
    gl_Position = vec4(vertex, 1.0); 
} 

--fragment.frag

#version 330 

out vec3 color; 
void main(){ 
    color = vec3(1,0,0); 
} 

我不知道我是否搞砸了一些QOpenGL代码或者是因为我已经将我的顶点存储在QVector中而不是数组中。作为领导者,我使用了Qt中的立方体示例,如代码相似性中所示。

帮助将不胜感激。

干杯!

+0

没有人甚至没有线索? –

回答

0

好的问题解决了。

本地openGL能够绘制来自Vectors的数据,并且QopenGLWidget只能在数据存储在数组中时绘制。即使数组包含Qvector3D数据。

纠正我,如果即时通讯错误..因为这看起来有点可耻我。