gpt4 book ai didi

c++ - 无法在 QWIndow (Qt5) 中使用 OpenGL 启用深度测试

转载 作者:行者123 更新时间:2023-11-30 04:05:04 25 4
gpt4 key购买 nike

我正在尝试使用 QWindow 在 Qt 5.2 中编写一个简单的 OpenGL 应用程序。我似乎无法启用深度测试。我简化了 QWindow OpenGL example heavy:我正在绘制一个带有彩色顶点的三角形,然后是一个带有白色顶点的三角形。白色三角形具有较大的 Z 坐标,因此应该出现在彩色三角形的后面。它没有。

我明确地将 QWindow 的表面格式的深度缓冲区大小设置为 24,但是当我检查 QWindow::format() 函数时,深度缓冲区大小为 0。使用 QGLFormat,我知道有一个 setDepth() 函数可以用来打开深度缓冲区,但是 QSurfaceFormat 中没有类似的函数。

我做错了什么?

我的代码...

测试窗口.cpp:

#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QResizeEvent>
#include <QSurfaceFormat>
#include <QWidget>
#include <QWindow>
#include <QVBoxLayout>

#include "SphereWindow.h"

class GLDialog : public QDialog
{
public:
GLDialog(QWidget *parent = 0, Qt::WindowFlags f = 0) : QDialog(parent, f)
{
QVBoxLayout *layout = new QVBoxLayout(this);

QSurfaceFormat format;
format.setSamples(16);
format.setDepthBufferSize(24);

qDebug() << "requested format:" << format;

window = new SphereWindow;
window->setFormat(format);

qDebug() << "actual format:" << window->format();

window->render();

QWidget *glWidget = QWidget::createWindowContainer(window, this);
layout->addWidget(glWidget);

}

~GLDialog()
{
delete window;
}

protected:
void resizeEvent(QResizeEvent *event)
{
window->resize(event->size());
window->render();
}

private:
SphereWindow *window;



};


int main(int argc, char **argv)
{
QApplication app(argc, argv);

QDialog *dlg = new GLDialog;

dlg->resize(640,480);
dlg->show();

return app.exec();
}

球体窗口.h:

#include <QColor>
#include <QEvent>
#include <QExposeEvent>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLPaintDevice>
#include <QOpenGLShaderProgram>
#include <QPainter>
#include <QResizeEvent>
#include <QSize>
#include <QWindow>


class SphereWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
SphereWindow(QWindow * = 0);
virtual ~SphereWindow();
virtual void render();
virtual void initialize();

public slots:
void resizeViewport(const QSize &);

protected:
virtual void resizeEvent(QResizeEvent *);


private:
bool _initialized;
QOpenGLContext *_context;
QOpenGLPaintDevice *_device;
QOpenGLShaderProgram *_program;

QColor _backgroundColour;

GLuint _posAttr;
GLuint _colAttr;
};

球体窗口.cpp:

#include <QCoreApplication>
#include <QMatrix4x4>
#include <QOpenGLShader>
#include <QScreen>
#include <QSurfaceFormat>

#include <QDebug>

#include "SphereWindow.h"

SphereWindow::SphereWindow(QWindow *parent)
: QWindow(parent),
_initialized(0),
_program(0),
_backgroundColour(Qt::black)
{
setSurfaceType(QWindow::OpenGLSurface);
create();

_context = new QOpenGLContext(this);
_context->setFormat(requestedFormat());
_context->create();
}

SphereWindow::~SphereWindow()
{ }


void SphereWindow::resizeEvent(QResizeEvent *event)
{
resizeViewport(event->size());
}

void SphereWindow::resizeViewport(const QSize &size)
{
int width = size.width();
int height = size.height();
int side = qMin(width, height);

int hoffset = (int)((width - side) / 2.0 + 0.5);
int voffset = (int)((height - side) / 2.0 + 0.5);

glViewport(hoffset, voffset, side, side);
}

void SphereWindow::render()
{

if (! _initialized)
initialize();

if (! isExposed()) return;
glEnable(GL_DEPTH_TEST);

_context->makeCurrent(this);
glClearColor(_backgroundColour.redF(), _backgroundColour.greenF(), _backgroundColour.blueF(), 1.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
_program->bind();

GLfloat vertices[] = {
-0.75f, 0.75f, 0.0f,
-0.75f, -0.75f, 0.0f,
0.75f, -0.75f, 0.0f,

0.75f, 0.75f, 0.5f,
0.75f, -0.75f, 0.5f,
-0.75f, -0.75f, 0.5f,

};

GLfloat colors[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
};

glVertexAttribPointer(_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glDrawArrays(GL_TRIANGLES, 0, 6);

glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);

_program->release();
_context->swapBuffers(this);
_context->doneCurrent();
}

static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = posAttr;\n"
"}\n";

static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";


void SphereWindow::initialize()
{
_context->makeCurrent(this);
_program = new QOpenGLShaderProgram(this);
_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
_program->link();

_program->bind();

_posAttr = _program->attributeLocation("posAttr");
_colAttr = _program->attributeLocation("colAttr");

_program->release();



initializeOpenGLFunctions();
}

testqwindow.pro:

######################################################################
# Automatically generated by qmake (3.0) Sat May 3 05:01:55 2014
######################################################################

TEMPLATE = app
TARGET = testqwindow
INCLUDEPATH += .

QT += widgets
CONFIG += debug

# Input
HEADERS += SphereWindow.h
SOURCES += SphereWindow.cpp testWindow.cpp

最佳答案

问题是这样的:我在调用我的 SphereWindow 构造函数后设置了表面格式,但创建了一个 QOpenGLContext 并在构造函数中设置了它的格式。结果是上下文没有获得深度缓冲区。我已将对 QOpenGLContext::setFormat()QOpenGLContext::create() 的调用移动到我的 SphereWindow::initialize() 函数,深度缓冲现在对我有用。

SphereWindow::SphereWindow(QWindow *parent)
: QWindow(parent),
_initialized(0),
_program(0),
_backgroundColour(Qt::black)
{
setSurfaceType(QWindow::OpenGLSurface);
create();

qDebug() << "format:" << format();


_context = new QOpenGLContext(this);
/* Move these lines into initialize() */
// _context->setFormat(requestedFormat());
// _context->create();
}

...

void SphereWindow::initialize()
{
_context->setFormat(requestedFormat());
_context->create();

_context->makeCurrent(this);
_program = new QOpenGLShaderProgram(this);
_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
_program->link();

_program->bind();

_posAttr = _program->attributeLocation("posAttr");
_colAttr = _program->attributeLocation("colAttr");

_program->release();



initializeOpenGLFunctions();
}

正如我在上面的评论中提到的,我在基于 QGLWidget 的设置中有几乎相同的代码,并且深度缓冲“开箱即用”。我想 QGLWidget(或 QGLFormat?)必须默认打开深度缓冲区,而 QWindow(或 QSurfaceFormat?)则没有。

关于c++ - 无法在 QWIndow (Qt5) 中使用 OpenGL 启用深度测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23462420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com