2011-05-10 65 views
0

我試圖讓我的屏幕上使用一些代碼,我直接從Qt的OpenGL的例子。但是,我無法在屏幕上顯示任何內容。所有的GL函數似乎都返回正確的值,並且錯誤日誌不會顯示任何問題。調試VBO /着色器的最佳方法是什麼?與OpenGL VBO和着色器的Qt應用程序不產生

這是我的shader代碼:

QGLShaderProgram* ShaderFactory::buildFlatShader(QObject *parent) 
{ 

    string vertSource = string("in vec3 vertex;\n" \ 
           "in vec2 a_texcoord;\n" \ 
           "uniform mat4 objToWorld;\n" \ 
           "uniform mat4 cameraPV;\n" \ 
           "void main() {\n" \ 
           " gl_Position = cameraPV * objToWorld * vec4(vertex,1.0);\n" \ 
           " gl_FrontColor = vec4(a_texcoord.x, 1, 0, 1);\n" \ 
           "}\n"); 

    string fragSource = string("void main() {\n" \ 
           " gl_FragColor = gl_Color;\n" \ 
           "}\n"); 

    QGLShader* vertShader = new QGLShader(QGLShader::Vertex); 
    vertShader->compileSourceCode(vertSource.c_str()); 

    QGLShader* fragShader = new QGLShader(QGLShader::Fragment); 
    fragShader->compileSourceCode(fragSource.c_str()); 

    QGLShaderProgram* program = new QGLShaderProgram(parent); 
    program->addShader(vertShader); 
    program->addShader(fragShader); 

    program->link(); 

    cout << program->log().toStdString() << endl; 
    cout << "Log end--" << endl; 

    return program; 
} 

QGLShaderProgram* ShaderFactory::buildShader(QObject *parent) 
{ 
    string vertSource = string("in vec3 vertex;\n" \ 
           "in vec3 normal;\n" \ 
           "in vec4 color;\n" \ 
           "varying vec3 worldNormal;\n" \ 
           "varying vec3 worldPos;\n" \ 
           "uniform vec3 cameraPos;\n" \ 
           "uniform mat4 objToWorld;\n" \ 
           "uniform mat4 cameraV;\n" \ 
           "uniform mat4 cameraP;\n" \ 
           "uniform mat4 cameraPV;\n" \ 
           "void main() {\n" \ 
           " gl_Position = cameraPV * objToWorld * vec4(vertex,1.0);\n" \ 
           " gl_FrontColor = color;\n" \ 
           " gl_BackColor = color;\n" \ 
           " worldPos = vertex;\n" \ 
           " worldNormal = normal;\n" \ 
           "}\n"); 

    string fragSource = string("varying vec3 worldNormal;\n" \ 
           "varying vec3 worldPos;\n" \ 
           "uniform vec3 cameraPos;\n" \ 
           "uniform vec3 lightDir;\n" \ 
           "uniform vec4 singleColor;\n" \ 
           "uniform float isSingleColor;\n" \ 
           "void main() {\n" \ 
           " vec3 L = lightDir;\n" \ 
           " vec3 V = normalize(cameraPos - worldPos);\n" \ 
           " vec3 N = normalize(worldNormal);\n" \ 
           " vec3 H = normalize(L+V);\n" \ 
           " vec4 color = isSingleColor*singleColor + (1.0-isSingleColor)*gl_Color;\n" \ 
           " //vec4 color = gl_Color;\n" \ 
           " float amb = .4;\n" \ 
           " vec4 ambient = color * amb;\n" \ 
           " vec4 diffuse = color * (1.0 - amb) * max(dot(L, N), 0.0);\n" \ 
           " vec4 specular = vec4(0);\n" \ 
           " gl_FragColor = vec4(ambient + diffuse + specular);\n" \ 
           "}\n"); 

    QGLShader* vertShader = new QGLShader(QGLShader::Vertex); 
    vertShader->compileSourceCode(vertSource.c_str()); 

    QGLShader* fragShader = new QGLShader(QGLShader::Fragment); 
    fragShader->compileSourceCode(fragSource.c_str()); 

    QGLShaderProgram* program = new QGLShaderProgram(parent); 
    program->addShader(vertShader); 
    program->addShader(fragShader); 

    return program; 
} 

這是我的OpenGL代碼

PanelGL::PanelGL() : QGLWidget(PanelGL::defaultFormat()) 
{ 
    setMouseTracking(true); 
    _validShaders = false; 

    camera = new Camera(); 

    if (mainGrid == NULL) { 
     int range[] = {-10,10}; 
     int numSegments = range[1]-range[0]+1; 
     QVector<LineSegment> segments(numSegments); 
     for (int i = 0; i < numSegments; i++) { 
      segments[i].p1 = Point3(i, 0, 10); 
      segments[i].p2 = Point3(i, 0, -10); 
      segments[i].r = 0.4f; 
      segments[i].g = 0.4f; 
      segments[i].b = 0.4f; 
     } 
     mainGrid = new LineRenderer(segments, 2); 
    } 
} 

QGLFormat PanelGL::defaultFormat() 
{ 
    QGLFormat format; 
    //format.setVersion(3,2); 
    //format.setProfile(QGLFormat::CompatibilityProfile); 
    return format; 
} 

bool glewInitialized = false; 

void PanelGL::initializeGL() 
{ 
    if (!glewInitialized) { 
     GLenum err = glewInit(); 
     if (GLEW_OK != err) 
     { 
      /* Problem: glewInit failed, something is seriously wrong. */ 
      cerr << "Error: " << glewGetErrorString(err) << endl; 
     } 
    } 
} 

void PanelGL::paintGL() 
{ 
    glClearColor(0.3f, 0.3f, 0.3f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    //glEnable(GL_DEPTH_TEST); 

    if (!_validShaders) { 
     _dummyShader = ShaderFactory::buildShader(this); 
     _flatShader = ShaderFactory::buildFlatShader(this); 
     _validShaders = true; 
    } 

    // render the grid 
    mainGrid->render(this); 

    //glDisable(GL_DEPTH_TEST); 
} 

void PanelGL::resizeGL(int width, int height) 
{ 
    glViewport(0,0,width,height); 
} 

LineRenderer::LineRenderer(QVector<LineSegment> segments, float lineWidth) 
{ 
    _validVBOs = FALSE; 
    //_segments = segments; 
    _lineWidth = lineWidth; 
} 

struct VertexData 
{ 
    Vector3 position; 
    Vector2 texCoord; 
}; 

void LineRenderer::render(PanelGL* panel) 
{ 
    if (!_validVBOs) { 
     glGenBuffers(2, _vboIds); 

     _validVBOs = TRUE; 
    } 

    loadVBOs(panel); 

    Camera* camera = panel->camera; 
    QMatrix4x4 cameraViewM = Camera::getViewMatrix(camera,panel->width(),panel->height()); 
    QMatrix4x4 cameraProjM = Camera::getProjMatrix(camera,panel->width(),panel->height()); 
    QMatrix4x4 cameraProjViewM = cameraProjM * cameraViewM; 
    QMatrix4x4 objToWorld; 

    QGLShaderProgram* flatShader = panel->getFlatShader(); 

    glLineWidth(_lineWidth); 
    flatShader->bind(); 
    int objToWorldLoc = flatShader->attributeLocation("objToWorld"); 
    flatShader->setUniformValue(objToWorldLoc, objToWorld); 
    int cameraPVLoc = flatShader->attributeLocation("cameraPV"); 
    flatShader->setUniformValue(cameraPVLoc, cameraProjViewM); 
    int overrideStrengthLoc = flatShader->attributeLocation("overrideStrength"); 
    flatShader->setUniformValue(overrideStrengthLoc, 0.0f); 

    // Tell OpenGL which VBOs to use 
    glBindBuffer(GL_ARRAY_BUFFER, _vboIds[0]); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIds[1]); 
    // Offset for position 
    int offset = 0; 
    // Tell OpenGL programmable pipeline how to locate vertex position data 
    int vertexLocation = flatShader->attributeLocation("vertex"); 
    flatShader->enableAttributeArray(vertexLocation); 
    glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); 
    // Offset for texture coordinate 
    offset += sizeof(QVector3D); 
    // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data 
    int texcoordLocation = flatShader->attributeLocation("a_texcoord"); 
    flatShader->enableAttributeArray(texcoordLocation); 
    glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); 
    // Draw cube geometry using indices from VBO 1 
    glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0); 

    //drawSegments.call 
    flatShader->release(); 
} 

void LineRenderer::loadVBOs(PanelGL* panel) 
{ 
    VertexData vertices[] = { 
      // Vertex data for face 0 
      {QVector3D(-1.0, -1.0, 1.0), QVector2D(0.0, 0.0)}, // v0 
      {QVector3D(1.0, -1.0, 1.0), QVector2D(0.33, 0.0)}, // v1 
      {QVector3D(-1.0, 1.0, 1.0), QVector2D(0.0, 0.5)}, // v2 
      {QVector3D(1.0, 1.0, 1.0), QVector2D(0.33, 0.5)}, // v3 
      // Vertex data for face 1 
      {QVector3D(1.0, -1.0, 1.0), QVector2D(0.0, 0.5)}, // v4 
      {QVector3D(1.0, -1.0, -1.0), QVector2D(0.33, 0.5)}, // v5 
      {QVector3D(1.0, 1.0, 1.0), QVector2D(0.0, 1.0)}, // v6 
      {QVector3D(1.0, 1.0, -1.0), QVector2D(0.33, 1.0)}, // v7 
      // Vertex data for face 2 
      {QVector3D(1.0, -1.0, -1.0), QVector2D(0.66, 0.5)}, // v8 
      {QVector3D(-1.0, -1.0, -1.0), QVector2D(1.0, 0.5)}, // v9 
      {QVector3D(1.0, 1.0, -1.0), QVector2D(0.66, 1.0)}, // v10 
      {QVector3D(-1.0, 1.0, -1.0), QVector2D(1.0, 1.0)}, // v11 
      // Vertex data for face 3 
      {QVector3D(-1.0, -1.0, -1.0), QVector2D(0.66, 0.0)}, // v12 
      {QVector3D(-1.0, -1.0, 1.0), QVector2D(1.0, 0.0)}, // v13 
      {QVector3D(-1.0, 1.0, -1.0), QVector2D(0.66, 0.5)}, // v14 
      {QVector3D(-1.0, 1.0, 1.0), QVector2D(1.0, 0.5)}, // v15 
      // Vertex data for face 4 
      {QVector3D(-1.0, -1.0, -1.0), QVector2D(0.33, 0.0)}, // v16 
      {QVector3D(1.0, -1.0, -1.0), QVector2D(0.66, 0.0)}, // v17 
      {QVector3D(-1.0, -1.0, 1.0), QVector2D(0.33, 0.5)}, // v18 
      {QVector3D(1.0, -1.0, 1.0), QVector2D(0.66, 0.5)}, // v19 
      // Vertex data for face 5 
      {QVector3D(-1.0, 1.0, 1.0), QVector2D(0.33, 0.5)}, // v20 
      {QVector3D(1.0, 1.0, 1.0), QVector2D(0.66, 0.5)}, // v21 
      {QVector3D(-1.0, 1.0, -1.0), QVector2D(0.33, 1.0)}, // v22 
      {QVector3D(1.0, 1.0, -1.0), QVector2D(0.66, 1.0)} // v23 
     }; 
     // Indices for drawing cube faces using triangle strips. 
     // Triangle strips can be connected by duplicating indices 
     // between the strips. If connecting strips have opposite 
     // vertex order then last index of the first strip and first 
     // index of the second strip needs to be duplicated. If 
     // connecting strips have same vertex order then only last 
     // index of the first strip needs to be duplicated. 
     GLushort indices[] = { 
      0, 1, 2, 3, 3,  // Face 0 - triangle strip (v0, v1, v2, v3) 
      4, 4, 5, 6, 7, 7, // Face 1 - triangle strip (v4, v5, v6, v7) 
      8, 8, 9, 10, 11, 11, // Face 2 - triangle strip (v8, v9, v10, v11) 
      12, 12, 13, 14, 15, 15, // Face 3 - triangle strip (v12, v13, v14, v15) 
      16, 16, 17, 18, 19, 19, // Face 4 - triangle strip (v16, v17, v18, v19) 
      20, 20, 21, 22, 23  // Face 5 - triangle strip (v20, v21, v22, v23) 
     }; 
     // Transfer vertex data to VBO 0 
     glBindBuffer(GL_ARRAY_BUFFER, _vboIds[0]); 
     glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(VertexData), vertices, GL_STATIC_DRAW); 

     // Transfer index data to VBO 1 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIds[1]); 
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 34 * sizeof(GLushort), indices, GL_STATIC_DRAW); 
} 
+0

您是否知道QVector3D的XYZ組件是否緊密封裝?我建議做一個glGetBufferSubData並看看你正在上傳的內容,或者只用純浮點C數組來測試相同的數字。 – cmannett85 2011-05-10 21:50:34

+0

你也已經告訴你的頂點指針希望使用浮點數,但是QVector3D/2D存儲的是qreal類型,它在PC平臺類型定義中加倍。 – cmannett85 2011-05-11 11:36:57

回答

0

我只是一個非常簡單的片段着色器(沒有頂點着色器)一樣啓動:

void main() 
{ 
    /* Color the fragment red */ 
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
}