2016-08-23 443 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};