opengl和Qt5.0.2

stereoMatching 2013-05-07 02:03:18
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();
}
...全文
559 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jdgdf566 2013-08-06
  • 打赏
  • 举报
回复
搭车问Qt是哪两个单词的缩写?
彩阳 2013-06-05
  • 打赏
  • 举报
回复
引用 9 楼 stereoMatching 的回复:
会接触opengl主要是想用它做一些影像处理的工作 不选择cuda和opencl则是因为现在的mobile大部分 都不支援cuda和opencl,但是有很多都支援opengl es2.0
嘿,其实Qt有一个分支是支持OpenCL的,但目前开发暂停了,你可以看看。 OpenCL在并行计算mandelbrot图形和Julia图形上有着显著的优势。 这里
stereoMatching 2013-05-08
  • 打赏
  • 举报
回复
会接触opengl主要是想用它做一些影像处理的工作 不选择cuda和opencl则是因为现在的mobile大部分 都不支援cuda和opencl,但是有很多都支援opengl es2.0
stereoMatching 2013-05-08
  • 打赏
  • 举报
回复
谢谢hgplan, 成功了 我修改了两个地方 1 : 透过读档案load shader

// Compile vertex shader
    if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, "modernOpenGLShader/ch1/vertex")){
        QMessageBox::warning(this, "QOpenGLShader::Vertex", "QOpenGLShader::Vertex" + program.log());
        close();      
    }

    // Compile fragment shader
    if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, "modernOpenGLShader/ch1/frag")){
        QMessageBox::warning(this, "QOpenGLShader::Fragment", "QOpenGLShader::Fragment" + program.log());
        close();    
    }
2 : 改fragment shader

void main() {
    //set every drawn pixel to white
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
刚开始学opengl,还分不清楚那个版本支援那些关键字,功能 Qt本身提供的例子不是很适合opengl的初学者
蓝色記憶 2013-05-08
  • 打赏
  • 举报
回复
引用 4 楼 stereoMatching 的回复:
还是无法执行 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,不知你有没有看到报什么错误?
stereoMatching 2013-05-08
  • 打赏
  • 举报
回复
引用
以前写的Qt中使用OpenGL
谢谢,不过我想用新的方法而不是deprecated的方法 Qt5在opengl的部分做了很多的改进,但是没弄懂要怎么使用
Inhibitory 2013-05-08
  • 打赏
  • 举报
回复
以前写的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();
}
stereoMatching 2013-05-08
  • 打赏
  • 举报
回复
还是无法执行 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/
蓝色記憶 2013-05-07
  • 打赏
  • 举报
回复
你的FragmentShader错了吧,最简单的FShader应该是: "void main()\n" "{\n" " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" "}\n" Opengl的shader中没有out这个东东,也不能把浮点型数写成1.0f。 至于第二个问题,大概是因为在 if (!program.link()) 的时候调用了close();了,不知道这里的close();为什么没有把窗口关掉,反而让关闭按钮不能使用了。
a514688934 2013-05-07
  • 打赏
  • 举报
回复
是不是该这样设置


initializeGL()
{
	glShadeModel( GL_SMOOTH );
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
	glClearDepth( 1.0 );
	glEnable( GL_DEPTH_TEST );


	glEnable(GL_POINT_SMOOTH);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
	glEnable(GL_LINE_SMOOTH);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);






	glDepthFunc( GL_LEQUAL );
	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

}


resizeGL( int width, int height )  //屏幕的大小
{
	if ( height == 0 )
	{
		height = 1;
	}
	glViewport( 0, 0, (GLint)width, (GLint)height );
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	gluPerspective( 90, ((float)width)/((float)height), 1, 5600 );
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	scalX(dianya_list->size());
}

为啥你的代码不设置 这些那?视口啊,矩阵什么的?
GOLF_R20 2013-05-07
  • 打赏
  • 举报
回复

16,816

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧