首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

opengl跟Qt5.0.2

2013-06-19 
opengl和Qt5.0.2openGL的初学者,尝试把opengl与Qt结合程式目的 : 画一个三角形平台 : mac osx 10.8.3编译

opengl和Qt5.0.2
openGL的初学者,尝试把opengl与Qt结合

程式目的 : 画一个三角形
平台 : mac osx 10.8.3
编译器 : clang3.2

问题有二
1 : 无法显示三角形
2 : 关闭视窗后程式不会跟着关闭

.hpp


#include <QGLWidget>

#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLShaderProgram>

class QWidget;

class ch1HelloTriangle : public QGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit ch1HelloTriangle(QWidget *parent = 0);

protected:
    virtual void initializeGL();
    void initShaders();
    void InitializeVertexBuffer();

    virtual void resizeGL(int w, int h);
    virtual void paintGL();

private:
    QOpenGLShaderProgram program;

    GLuint positionBufferObject;
};


.cpp

#include <locale.h>

#include <QWidget>

#include "ch1HelloTriangle.hpp"

namespace
{

float const vertexPositions[] = {
    0.75f,  0.75f, 0.0f, 1.0f,
    0.75f, -0.75f, 0.0f, 1.0f,
    -0.75f, -0.75f, 0.0f, 1.0f,
};

}

ch1HelloTriangle::ch1HelloTriangle(QWidget *parent) :
    QGLWidget(parent)
{
}

void ch1HelloTriangle::initializeGL()
{
    initializeOpenGLFunctions();
    InitializeVertexBuffer();
    initShaders();
}

void ch1HelloTriangle::initShaders()
{
    // Override system locale until shaders are compiled
    setlocale(LC_NUMERIC, "C");

    // Compile vertex shader
    if (!program.addShaderFromSourceCode(QOpenGLShader::Vertex,
                                         "attribute vec4 position;\n"
                                         "void main()\n"
                                         "{\n"
                                         "   gl_Position = position;\n"
                                         "}\n"))
    {
        close();
    }



    // Compile fragment shader
    if (!program.addShaderFromSourceCode(QOpenGLShader::Fragment,
                                         "out vec4 outputColor;\n"
                                         "void main()\n"
                                         "{\n"
                                         "   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
                                         "}\n"))
    {
        close();

    }

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

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

    // Restore system locale
    setlocale(LC_ALL, "");
}

void ch1HelloTriangle::InitializeVertexBuffer()
{
    glGenBuffers(1, &positionBufferObject);

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void ch1HelloTriangle::resizeGL(int w, int h)
{
    // Set OpenGL viewport to cover whole widget
    glViewport(0, 0, w, h);
}

void ch1HelloTriangle::paintGL()
{             
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);

    int vertexLocation = program.attributeLocation("position");
    program.enableAttributeArray(vertexLocation);

    glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glDrawArrays(GL_TRIANGLES, 0, 3);    
}



main.cpp

#include <QApplication>

#include "ch1HelloTriangle.hpp"

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



    ch1HelloTriangle ch1;
    ch1.show();

    return a.exec();
}


[解决办法]
以前写的Qt中使用OpenGL
==================================[GLWidget.h]==================================
#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QtOpenGL/QGLWidget>

class GLWidget : public QGLWidget {
    Q_OBJECT

public:
    GLWidget(QWidget *parent = 0);
    ~GLWidget();

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

    virtual void hideEvent(QHideEvent *event);
    virtual void showEvent(QShowEvent *event);
    virtual void timerEvent(QTimerEvent *event);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void wheelEvent(QWheelEvent *event);

private:
    int     timerId;
    QPoint  lastPos;
    GLfloat rotateX;
    GLfloat rotateY;
    GLfloat rotateZ;
    GLfloat zoom;

    void drawCube(GLfloat factorX = 1, GLfloat factorY = 1,
                  GLfloat factorZ = 1, GLfloat w = 1);
    void drawCone(GLfloat radius = 1.0f, GLfloat height = 1,
                  GLuint steps = 18);
};

#endif // GLWIDGET_H


==================================[GLWidget.cpp]==================================
#include "GLWidget.h"
#include <qDebug>
#include <QTimerEvent>
#include <QMouseEvent>
#include <cmath>

GLWidget::GLWidget(QWidget *parent)
    : QGLWidget(parent) {
    setFormat(QGLFormat(QGL::DoubleBuffer 
[解决办法]
 QGL::DepthBuffer));

    rotateX = 0.0f;
    rotateY = 0.0f;
    rotateZ = 0.0f;
    zoom = 1.0f;
}

GLWidget::~GLWidget() {

}

void GLWidget::hideEvent(QHideEvent *event) {
    this->killTimer(this->timerId);


}

void GLWidget::showEvent(QShowEvent *event) {
    this->timerId = this->startTimer(500);
}

void GLWidget::timerEvent(QTimerEvent *event) {
    if (event->timerId() == this->timerId) {
    } else {
        QGLWidget::timerEvent(event);
    }
}

void GLWidget::mousePressEvent(QMouseEvent *event) {
    if (Qt::LeftButton == event->button()) {
        lastPos = event->pos();
    } else if (Qt::RightButton == event->button()) {
        lastPos = event->pos();
    }
}

void GLWidget::mouseMoveEvent(QMouseEvent *event) {
    if (Qt::LeftButton & event->buttons()) {
        GLfloat dx = event->pos().x() - lastPos.x();
        GLfloat dy = event->pos().y() - lastPos.y();

        rotateX += dy;
        rotateY += dx;

        updateGL();
        //qDebug() << QString("RotateX:%1, RotateY:%2").arg(rotateX).arg(rotateY);
    } else if (Qt::RightButton & event->buttons()) {
        GLfloat dz = event->pos().y() - lastPos.y();
        dz *= 0.01f;
        zoom += dz;
        updateGL();
    }

    lastPos = event->pos();
}

void GLWidget::mouseReleaseEvent(QMouseEvent *event) {

}

void GLWidget::wheelEvent(QWheelEvent *event) {
    GLfloat degrees = event->delta();
    zoom -= degrees * 0.0002f;
    // 注意, 如果zoom为负值, eye就会被放置到z轴的负方向, 而从物体的背面看了.
    if (zoom < 1.0f) {
        zoom = 1.0f;
    }

    updateGL();
}

///////////////////////////////////////////////////////////////////////////////
//                               Opengl Code
///////////////////////////////////////////////////////////////////////////////
void GLWidget::initializeGL() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glFrontFace(GL_CCW);
    //glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glShadeModel(GL_SMOOTH);

    // Point size
    // glPointSize(GLfloat size);
    GLfloat sizes[2];
    GLfloat step;


    glGetFloatv(GL_LINE_WIDTH_RANGE, sizes);
    glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);
}

void GLWidget::resizeGL(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(75, (GLdouble)w / h, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void GLWidget::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT 
[解决办法]
 GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    //glTranslatef(0.0f, 0.0f, zoom);
    gluLookAt(0.0f, 0.0f, zoom, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    glRotatef(rotateX, 1, 0, 0);
    glRotatef(rotateY, 0, 1, 0);
    glRotatef(rotateZ, 0, 0, 1);

    // Real draw code.
    //glColor3f(1.0f, 0.0f, 0.0f);
    //drawCube(1, 1, 1, 1);
    glPolygonMode(GL_BACK, GL_LINE);
    drawCone(1.0f, 1.50, 48);

}

void GLWidget::drawCube(GLfloat factorX, GLfloat factorY,
                        GLfloat factorZ, GLfloat w) {
    GLfloat x = factorX * 0.5f;
    GLfloat y = factorY * 0.5f;
    GLfloat z = factorZ * 0.5f;

    // x / w, y / w, z / w
    // 前左下, 前右下, 前右上, 前左上: p0, p1, p2, p3
    // 后左下, 后右下, 后右上, 后左上: p4, p5, p6, p7
    GLfloat p0[4] = {-x, -y, z, w};
    GLfloat p1[4] = {x, -y, z, w};
    GLfloat p2[4] = {x, y, z, w};
    GLfloat p3[4] = {-x, y, z, w};

    GLfloat p4[4] = {-x, -y, -z, w};
    GLfloat p5[4] = {x, -y, -z, w};
    GLfloat p6[4] = {x, y, -z, w};
    GLfloat p7[4] = {-x, y, -z, w};

    // 开始绘制Cube的六个面: 逆时针
    glBegin(GL_QUADS);
    // 前面: p0, p1, p2, p3
    glVertex4fv(p0);
    glVertex4fv(p1);
    glVertex4fv(p2);
    glVertex4fv(p3);
    // 右面: p1, p5, p6, p2
    glVertex4fv(p1);
    glVertex4fv(p5);
    glVertex4fv(p6);
    glVertex4fv(p2);
    // 后面: p5, p4, p7, p6
    glVertex4fv(p5);


    glVertex4fv(p4);
    glVertex4fv(p7);
    glVertex4fv(p6);
    // 左右: p4, p0, p3, p7
    glVertex4fv(p4);
    glVertex4fv(p0);
    glVertex4fv(p3);
    glVertex4fv(p7);
    // 上面: p2, p6, p7, p3
    glVertex4fv(p2);
    glVertex4fv(p6);
    glVertex4fv(p7);
    glVertex4fv(p3);
    // 下面: p0, p4, p5, p1
    glVertex4fv(p0);
    glVertex4fv(p4);
    glVertex4fv(p5);
    glVertex4fv(p1);
    glEnd();
}


void GLWidget::drawCone(GLfloat radius, GLfloat height,
                        GLuint steps) {
    const GLfloat GL_PI = 3.1415f;
    GLfloat angles = 2 * GL_PI / steps;
    GLfloat vertices[steps][3];

    for (int i = 0; i < steps; ++i) {
        vertices[i][0] = radius * cos(i * angles);
        vertices[i][1] = radius * sin(i * angles);
        vertices[i][2] = 0;
    }

    // top surface
    glBegin(GL_TRIANGLE_FAN);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(0.0f, 0.0f, height);
        for (int i = 0; i < steps; ++i) {
            glVertex3fv(vertices[i]);
            if ((i & 1) == 0) {
                glColor3f(1.0f, 0.0f, 0.0f);
            } else {
                glColor3f(0.0f, 0.0f, 1.0f);
            }
        }
        glVertex3fv(vertices[0]);
    glEnd();

    // bottom surface
    glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.0f, 0.0f, 0);
        for (int i = steps - 1; i >= 0; --i) {
            glVertex3fv(vertices[i]);
            if ((i & 1) == 0) {
                glColor3f(0.0f, 1.0f, 0.0f);
            } else {


                glColor3f(1.0f, 0.0f, 1.0f);
            }
        }
        glVertex3fv(vertices[steps - 1]);
    glEnd();
}


[解决办法]
引用:
还是无法执行
opengl中有out这个关键字

opengl3.3的教学
http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html

opengl3.2的教学
http://tomdalling.com/blog/modern-opengl/01-getting-started-in-xcode-and-visual-cpp/

Qt5.0中的QOpenGLShaderProgram为了跨平台,他仅仅只能编译 Opengl2.0/ES2.0规范的Shader吧,我所知道的在OpenglES2.0中是没有out的关键字的.
Qt5.1中好像对此有所改进,楼主可以去看看这两篇文章:
http://www.kdab.com/opengl-in-qt-5-1-part-1/
http://www.kdab.com/opengl-in-qt-5-1-part-2/
在我这里把FragmentShader改掉是可以执行的,我的环境是Win7+Qt5.0.1,不知你有没有看到报什么错误?

热点排行