2016-08-23 441 views
-1

我正在使用Qt(5.6.0)在Qt和遊戲場景(3D地圖,角色,怪物等)中完成界面製作地牢爬行器/流氓類。 )在OpenGL中。該視圖是一個提升的QWidget,我可以使用舊的glBegin/glEnd方法進行繪製,但每當我嘗試使用glDrawArrays或glDrawElements時,我都會看到一個空白屏幕。QT OpenGL,glDrawElements和glDrawArray只顯示空白屏幕

清晰的顏色工作,被設置爲比黑色稍輕,所以應該顯示黑色的形狀。我正在使用glBegin/glEnd方法用相同的頂點進行測試,並且它的渲染效果與它應該一樣。我嘗試了一個或多或少的直接OpenGL方法,如Jamie King所示,通過幾個更多示例和教程,最後以this example結尾,以便使用QOpenGLShaderProgram和QOpenGLVertexArrayObject對象以及QOpenGLShaderProgram Qt文檔中的示例。目前initializeGL函數中的着色器代碼阻止繪製glBegin/glEnd三角形。

目前代碼:

oglwidget.cpp:

#include "GL/glew.h" 
#include "GL/glext.h" 
#include "oglwidget.h" 
#include "general.h" 

#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes)) 

extern const char * vertexShader; 
extern const char * fragmentShader; 

OGLWidget::OGLWidget(QWidget *parent): QOpenGLWidget(parent){ 

} 

OGLWidget::~OGLWidget(){ 

} 

void OGLWidget::initializeGL(){ 
    QOpenGLFunctions gl; 
    gl.initializeOpenGLFunctions(); 
    cout<<"Init"<<endl; 
    //-----Create Shader 
    shader2.create(); 
    shader2.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShader); 
    shader2.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShader); 
    shader2.link(); 
    shader2.bind(); 
    int vertexLocation = shader2.attributeLocation("vertex"); 
    int matrixLocation = shader2.uniformLocation("matrix"); 
    int colorLocation = shader2.uniformLocation("color"); 
    QMatrix4x4 pmvMatrix; 
    pmvMatrix.ortho(rect()); 
    QColor color(0, 255, 0, 255); 

    shader2.enableAttributeArray(vertexLocation); 
    shader2.setAttributeArray(vertexLocation, verts, 3); 
    shader2.setUniformValue(matrixLocation, pmvMatrix); 
    shader2.setUniformValue(colorLocation, color); 

    //-----Create VAO2 
    VAO2=new QOpenGLVertexArrayObject(this); 
    VAO2->create(); 
    VAO2->bind(); 
    //-----Create VBO2 
    VBO2.create(); 
    VBO2.setUsagePattern(QOpenGLBuffer::StaticDraw); 
    VBO2.bind(); 
    VBO2.allocate(verts,sizeof(verts)); 
} 

void OGLWidget::paintGL(){ 
    cout<<"Painting"<<endl; 
    QOpenGLFunctions gl; 
    gl.initializeOpenGLFunctions(); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glClearColor(0.05,0.05,0.05,1); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glTranslatef(0.0f,0.0f,-2.0f); 

    //draw(); 
    shader2.bind(); 
    VAO2->bind(); 
    glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT,inds); 
    VAO2->release(); 
} 


void OGLWidget::resizeGL(int w, int h){ 
    cout<<"Resizing"<<endl; 
    glViewport(0,0,w,h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    //glFrustum (-1.0, 1.0, -1.0, 1.0, 1, 1000.0); //-----Assuming this is right? 
    glOrtho(-5,5,-5,5,-5,5); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 
int OGLWidget::loadModel(string path){ 
    //-----loads the model path if not already loaded, returns the index of the model 
    //---check if already loaded 
    for(int p=0;p<loadedPaths.size();p++){ 
     if(!loadedPaths[p].compare(path)){ 
      return p; 
     } 
    } 
    loadedPaths.push_back(path); 
    //-----continue with path loading 
    Model m; 
    m.loadModel(path); 
    return loadedPaths.size()-1; 
} 

void OGLWidget::draw(){ 
    cout<<"drawing..."<<endl; 
    glBegin(GL_TRIANGLES); 
    for(int i=0;i<sizeof(verts)/sizeof(GLfloat);i+=3){ 
     //cout<<i<<endl; 
     glVertex3f(verts[i],verts[i+1],verts[i+2]); 
    } 
    glEnd(); 
} 

oglwidget.h:

#ifndef OGLWIDGET_H 
#define OGLWIDGET_H 

#include <QWidget> 
#include <QOpenGLWidget> 
#include <glm/glm.hpp> 
#include <QOpenGLFunctions> 
#include <vector> 
#include "entity.h" 
#include "general.h" 
#include <qopenglfunctions_3_3_core.h> 
//#include <GL/glu.h> 
//#include <GL/gl.h> 

#define VERTEXATTR 0 
#define INDEXATTR 1 
#define POSITIONATTR 2 
#define ROTATIONATTR 3 

using namespace std; 


class OGLWidget : public QOpenGLWidget 
{ 
    //QOpenGLFunctions gl; 
    //QOpenGLFunctions_3_3_Core core; 
    QOpenGLVertexArrayObject *VAO2; 
    QOpenGLBuffer VBO2; 
    QOpenGLShaderProgram shader2; 
    QOpenGLContext *m_context; 
    vector<GLuint>statics; //-----buffer number for static models 
    vector<GLuint>dynamics; //-----buffer number of dynamic models 

    vector<GLfloat[1]>staticVerts; //-----vertex data for static models 
    vector<GLfloat[1]>dynamicVerts; //-----vertex data for dynamic models 

    vector<vector<GLfloat>*>staticPos; //-----position data for static models 
    vector<vector<GLfloat>*>dynamicPos; //-----position data for dynamic models 

    vector<GLfloat>staticRot; //-----rotation data for static models 
    vector<GLfloat>dynamicRot; //-----rotation data for dynamic models 

    vector<string>loadedPaths; //-----name in folder of matching VBO 
    GLuint VBO; 
    GLuint IND; 
    GLuint FragID; 
    GLuint VertID; 
    GLuint shader; 

    //-----Testing 
    GLfloat verts[9]={-1.0f, 0.0f, 0.0f, 
         0.0f, 1.0f, 0.0f, 
         1.0f, 0.0f, 0.0f}; 
    GLuint inds[3]={0,1,2}; 

public: 
    OGLWidget(QWidget *parent = 0); 
    ~OGLWidget(); 
    int loadModel(string path); 
private: 
    void draw(); 
    QGLShaderProgram m_shader; 
    QGLBuffer m_vertexBuffer; 

protected: 
    void initializeGL(); 
    void resizeGL(int w, int h); 
    void paintGL(); 
}; 

#endif // OGLWIDGET_H 

shader.cpp:

const char * vertexShader= 
     "attribute highp vec4 vertex;\n" 
     "uniform highp mat4 matrix;\n" 
     "void main(void)\n" 
     "{\n" 
     " gl_Position = matrix * vertex;\n" 
     "}"; 
const char * fragmentShader= 
     "uniform mediump vec4 color;\n" 
     "void main(void)\n" 
     "{\n" 
     " gl_FragColor = color;\n" 
     "}"; 

從我讀過(糾正我,如果我錯了)它的目標使用VAO將頂點,顏色,紋理和其他數據加載到GPU內存,在繪製之前重新綁定VAO,使用glDrawArrays或glDrawElement繪製並釋放VAO。使用函數的索引版本將允許位置,比例和旋轉的更改,這意味着更大數量的同一對象(即遊戲切片)的更快渲染和GL_STATIC_DRAW應該用於未經常更新的對象,其中GL_DYNAMIC_DRAW一切。

我想知道我錯過了什麼,或者做錯了什麼應該是一個簡單的練習。我已經重做了至少5次,完全失利。

  • OS:Debian的測試
  • GPU:的GeForce610米
  • OpenGL的核心:3.3
  • 的Qt:5.6
  • 軟件:Qt Creator的
+0

你有沒有嘗試添加誤差glGetError檢查()? –

+0

綁定vao後,需要綁定頂點的東西(vao在那裏存儲綁定)。您可以設置正投影顯示窗口座標(0左上角,y正下),但是您的座標應在[0-1]左右,大小約爲一個像素。你也試圖綁定一個緩衝區和數組都作爲頂點屬性(它應該只是緩衝區) – PeterT

+0

最後一點我的意思是使用'setAttributeBuffer'而不是'setAttributeArray'(並且在綁定緩衝區後明顯做到這一點) – PeterT

回答

0

解決方案由於@PeterT在註釋:將着色器enableAttributeArray和setAttributeBuffer(從setAttributeArray更改)移至VBO分配之後,並將頂點座標和鄰點修改爲「更大」。

void OGLWidget::initializeGL() 
{ 
    QOpenGLFunctions gl; 
    gl.initializeOpenGLFunctions(); 
    glDisable(GL_CULL_FACE); 
    cout<<"Init"<<endl; 
    shader2.create(); 
    shader2.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShader); 
    shader2.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShader); 
    shader2.link(); 
    shader2.bind(); 
    int vertexLocation = shader2.attributeLocation("vertex"); 
    int matrixLocation = shader2.uniformLocation("matrix"); 
    int colorLocation = shader2.uniformLocation("color"); 
    QMatrix4x4 pmvMatrix; 
    //pmvMatrix.ortho(rect()); 
    pmvMatrix.ortho(-100,100,-100,100,-1000,1000); 
    QColor color(0, 255, 0, 255); 

    shader2.enableAttributeArray(vertexLocation); 
    shader2.setUniformValue(matrixLocation, pmvMatrix); 
    shader2.setUniformValue(colorLocation, color); 

    //-----Create VAO2 
    VAO2=new QOpenGLVertexArrayObject(this); 
    VAO2->create(); 
    VAO2->bind(); 

    VBO2.create(); 
    VBO2.setUsagePattern(QOpenGLBuffer::StaticDraw); 
    VBO2.bind(); 
    VBO2.allocate(verts,sizeof(verts)); 

    shader2.enableAttributeArray("vertex"); 
    shader2.setAttributeBuffer("vertex",GL_FLOAT,0,3,0); 
} 

*

GLfloat verts[9]={-100.0f, 0.0f, 30.0f, 
         0.0f, 100.0f, 50.0f, 
         100.0f, 0.0f, 30.0f};