opengl 3 qt渲染空白屏幕

时间:2016-06-14 08:19:57

标签: c++ qt opengl

我是OpenGL的新手。我使用OpenGL 3和QT5来最终渲染类似地形的类似地形。到目前为止,我只尝试渲染一个立方体,但我一直在看一个空白的屏幕。我正在学习本教程系列:https://www.youtube.com/playlist?list=PLRwVmtr-pp06qT6ckboaOhnm9FxmzHpbY,这里是代码:

glwindow.h:

#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_3_Core>


class glWiwndow : public QOpenGLWidget,
                  protected QOpenGLFunctions_4_3_Core
{
protected:
    void sendDataToOpenGL();
    void installShaders();
    QString readShaderCode(const QString fileName);
    void initializeGL();
    void paintGL();
    void teardownGL();
public:

};

vertex.h:

#pragma once
#include <glm\glm.hpp>

struct Vertex
{
    glm::vec3 position;
    glm::vec3 color;
    glm::vec3 normal;
};

shapedata.h:

#pragma once
#include <QOpenGLShaderProgram>
#include"vertex.h"

struct shapeData
{
    shapeData() :
        vertices(0), numVertices(0),
        indices(0), numIndices(0) {}
    Vertex* vertices;
    GLuint numVertices;
    GLushort* indices;
    GLuint numIndices;
    GLsizeiptr vertexBufferSize() const
    {
        return numVertices * sizeof(Vertex);
    }
    GLsizeiptr indexBufferSize() const
    {
        return numIndices * sizeof(GLushort);
    }
    void cleanup()
    {
        delete [] vertices;
        delete [] indices;
        numVertices = numIndices = 0;
    }
};

shapegenerator.h:

#include"shapedata.h"
class ShapeGenerator
{
public:
    ShapeGenerator();
    static shapeData makeTriangle();
    static shapeData makeCube();
};

glwindow.cpp:

#include "glwindow.h"
#include"shapegenerator.h"
#include<iostream>
#include <QDebug>
#include <QString>
#include <QOpenGLShaderProgram>
#include<QMessageBox>
#include<QStringList>
#include <QMatrix4x4>
#include<QFile>
#include "glm\gtc\matrix_transform.hpp"
#include "glm\gtx\transform.hpp"
using glm::mat4;
using glm::vec3;


GLint  programID;
GLuint numIndices;

QString  glWiwndow::readShaderCode(const QString  fileName){

    QFile file(fileName);
     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return NULL;
     }

     QByteArray total;
     QByteArray line;
     while (!file.atEnd()) {
        line = file.read(1024);
        total.append(line);
     }

     return QString(total);


}

void glWiwndow::installShaders(){

    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    const GLchar * adapter[1];
    QString temp = readShaderCode(":/vertexshader.vert");
    adapter[0] = temp.toStdString().c_str();
    glShaderSource(vertexShaderID,1,adapter,0);
    temp = readShaderCode(":/fragmentshader.frag");
    adapter[0] = temp.toStdString().c_str();
    glShaderSource(fragmentShaderID,1,adapter,0);
    //cout<<"here";
    glCompileShader(vertexShaderID);
    //cout<<"yoo";
    glCompileShader(fragmentShaderID);


    GLuint programID = glCreateProgram();
    glAttachShader(programID,vertexShaderID);
    glAttachShader(programID,fragmentShaderID);

    glLinkProgram(programID);

    glUseProgram(programID);

}

void glWiwndow :: initializeGL(){
    // Initialize OpenGL Backend
    initializeOpenGLFunctions();
    connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(teardownGL()), Qt::DirectConnection);
    glEnable(GL_DEPTH_TEST);

    shapeData cube = ShapeGenerator::makeCube();


    GLuint myBufferID;
    glGenBuffers(1,&myBufferID);
    glBindBuffer(GL_ARRAY_BUFFER,myBufferID);
    glBufferData(GL_ARRAY_BUFFER,cube.vertexBufferSize(),cube.vertices,GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(float)*6,0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(float)*6,(char*)(sizeof(float)*3));

    GLuint indexArrayBufferID;
    glGenBuffers(1,&indexArrayBufferID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexArrayBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,cube.indexBufferSize(),cube.indices,GL_STATIC_DRAW);
    numIndices = cube.numIndices;

    installShaders();


}

void glWiwndow :: paintGL(){

    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glViewport(0,0,width(),height());


    mat4 modelTransformMatrix = glm::translate(mat4(),vec3(0.0f,0.0f,-3.0f));
    mat4 projectionMatrix = glm::perspective(60.0f, ((float)width()) / height(), 0.1f, 20.0f);

    GLint modelTransformMatrixUniformLocation = glGetUniformLocation(programID,"modelTransformMatrix");

    GLint projectionMatrixUniformLocation = glGetUniformLocation(programID,"projectionMatrix");

    glUniformMatrix4fv(modelTransformMatrixUniformLocation,1,GL_FALSE,&modelTransformMatrix[0][0]);

    glUniformMatrix4fv(projectionMatrixUniformLocation,1,GL_FALSE,&projectionMatrix[0][0]);


    glDrawElements(GL_TRIANGLES,numIndices,GL_UNSIGNED_SHORT,0);

}

void glWiwndow::teardownGL()
{

}

shapegenerator.cpp:

#include "ShapeGenerator.h"
#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <vertex.h>
using glm::vec3;
using glm::mat4;
using glm::mat3;
#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a)

glm::vec3 randomColor()
{
    glm::vec3 ret;
    ret.x = rand() / (float)RAND_MAX;
    ret.y = rand() / (float)RAND_MAX;
    ret.z = rand() / (float)RAND_MAX;
    return ret;
}

shapeData ShapeGenerator::makeTriangle()
{
    shapeData ret;

    Vertex verts[] =
    {
        glm::vec3(+0.0f, +1.0f, +0.0f),
        glm::vec3(+0.0f, +1.0f, +0.0f),


        glm::vec3(-1.0f, -1.0f, +0.0f),
        glm::vec3(+0.0f, +1.0f, +0.0f),


        glm::vec3(+1.0f, -1.0f, +0.0f),
        glm::vec3(+0.0f, +0.0f, +1.0f),

    };
    ret.numVertices = NUM_ARRAY_ELEMENTS(verts);
    ret.vertices = new Vertex[ret.numVertices];
    memcpy(ret.vertices, verts, sizeof(verts));

    GLushort indices[] = { 0, 1, 2 };
    ret.numIndices = NUM_ARRAY_ELEMENTS(indices);
    ret.indices = new GLushort[ret.numIndices];
    memcpy(ret.indices, indices, sizeof(indices));

    return ret;
}

shapeData ShapeGenerator::makeCube() {
    shapeData ret;
    Vertex stackVerts[] =
    {
        vec3(-1.0f, +1.0f, +1.0f),  // 0
        vec3(+1.0f, +0.0f, +0.0f),  // Color

        vec3(+1.0f, +1.0f, +1.0f),  // 1
        vec3(+0.0f, +1.0f, +0.0f),  // Color

        vec3(+1.0f, +1.0f, -1.0f),  // 2
        vec3(+0.0f, +0.0f, +1.0f),  // Color

        vec3(-1.0f, +1.0f, -1.0f),  // 3
        vec3(+1.0f, +1.0f, +1.0f),  // Color


        vec3(-1.0f, +1.0f, -1.0f),  // 4
        vec3(+1.0f, +0.0f, +1.0f),  // Color

        vec3(+1.0f, +1.0f, -1.0f),  // 5
        vec3(+0.0f, +0.5f, +0.2f),  // Color

        vec3(+1.0f, -1.0f, -1.0f),  // 6
        vec3(+0.8f, +0.6f, +0.4f),  // Color

        vec3(-1.0f, -1.0f, -1.0f),  // 7
        vec3(+0.3f, +1.0f, +0.5f),  // Color


        vec3(+1.0f, +1.0f, -1.0f),  // 8
        vec3(+0.2f, +0.5f, +0.2f),  // Color

        vec3(+1.0f, +1.0f, +1.0f),  // 9
        vec3(+0.9f, +0.3f, +0.7f),  // Color

        vec3(+1.0f, -1.0f, +1.0f),  // 10
        vec3(+0.3f, +0.7f, +0.5f),  // Color

        vec3(+1.0f, -1.0f, -1.0f),  // 11
        vec3(+0.5f, +0.7f, +0.5f),  // Color


        vec3(-1.0f, +1.0f, +1.0f),  // 12
        vec3(+0.7f, +0.8f, +0.2f),  // Color

        vec3(-1.0f, +1.0f, -1.0f),  // 13
        vec3(+0.5f, +0.7f, +0.3f),  // Color

        vec3(-1.0f, -1.0f, -1.0f),  // 14
        vec3(+0.4f, +0.7f, +0.7f),  // Color

        vec3(-1.0f, -1.0f, +1.0f),  // 15
        vec3(+0.2f, +0.5f, +1.0f),  // Color


        vec3(+1.0f, +1.0f, +1.0f),  // 16
        vec3(+0.6f, +1.0f, +0.7f),  // Color

        vec3(-1.0f, +1.0f, +1.0f),  // 17
        vec3(+0.6f, +0.4f, +0.8f),  // Color

        vec3(-1.0f, -1.0f, +1.0f),  // 18
        vec3(+0.2f, +0.8f, +0.7f),  // Color

        vec3(+1.0f, -1.0f, +1.0f),  // 19
        vec3(+0.2f, +0.7f, +1.0f),  // Color


        vec3(+1.0f, -1.0f, -1.0f),  // 20
        vec3(+0.8f, +0.3f, +0.7f),  // Color

        vec3(-1.0f, -1.0f, -1.0f),  // 21
        vec3(+0.8f, +0.9f, +0.5f),  // Color

        vec3(-1.0f, -1.0f, +1.0f),  // 22
        vec3(+0.5f, +0.8f, +0.5f),  // Color

        vec3(+1.0f, -1.0f, +1.0f),  // 23
        vec3(+0.9f, +1.0f, +0.2f),  // Color

    };

    ret.numVertices = NUM_ARRAY_ELEMENTS(stackVerts);
    ret.vertices = new Vertex[ret.numVertices];
    memcpy(ret.vertices, stackVerts, sizeof(stackVerts));

    unsigned short stackIndices[] = {
        0,   1,  2,  0,  2,  3, // Top
        4,   5,  6,  4,  6,  7, // Front
        8,   9, 10,  8, 10, 11, // Right
        12, 13, 14, 12, 14, 15, // Left
        16, 17, 18, 16, 18, 19, // Back
        20, 22, 21, 20, 23, 22, // Bottom
    };
    ret.numIndices = NUM_ARRAY_ELEMENTS(stackIndices);
    ret.indices = new GLushort[ret.numIndices];
    memcpy(ret.indices, stackIndices, sizeof(stackIndices));

    return ret;
}

main.cpp中:

#include "glwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    glWiwndow w;
    w.show();

    return a.exec();
}

顶点着色器代码:(vertexshader.vert)

#version 430
layout(location = 0) in vec3 position;
layout(location=1) in vec3 vertexColor;
uniform mat4 modelTransformMatrix;
uniform mat4 projectionMatrix;
out vec3 theColor;
void main()
{
  vec4 v = vec4(position,1.0);
  vec4 newPosition = modelTransformMatrix * v;
  vec4 projectedPosition = projectionMatrix * newPosition;
  gl_Position = projectedPosition;
  theColor = vertexColor;
}

片段着色器代码:(fragmentshader.frag)

#version 430
out highp vec4 fColor;
in vec3 theColor; 
void main()
{
   fColor =vec4(theColor,1.0);
}

1 个答案:

答案 0 :(得分:0)

问题在于programID,但不是我在评论中概述的原因。目前,您有一个全球可靠的...

GLint  programID;

然后在glWiwndow::installShaders你有......

GLuint programID = glCreateProgram();

因此,您的代码使用本地作用域glUseProgram调用programID,然后在glWiwndow::paintGL中将未初始化的全局programID传递给glGetUniformLocation,返回-1表示失败。你真的需要在GL中检查这些类型的错误。