QSurfaceFormat 不允许使用 OpenGL 进行绘制
Posted
技术标签:
【中文标题】QSurfaceFormat 不允许使用 OpenGL 进行绘制【英文标题】:QSurfaceFormat does not allow to draw with OpenGL 【发布时间】:2021-12-04 12:04:44 【问题描述】:当我评论它时,它很好用(我看到一个正方形)没有 QSurfaceFormat:
int main(int argc, char *argv[])
QApplication a(argc, argv);
// QSurfaceFormat format;
// format.setSamples(8);
Widget w;
// w.setFormat(format);
w.show();
return a.exec();
但是当我取消注释时,代码不会绘制正方形:
int main(int argc, char *argv[])
QApplication a(argc, argv);
QSurfaceFormat format;
// format.setSamples(8);
Widget w;
w.setFormat(format);
w.show();
return a.exec();
main.cpp
// Add this line to .pro:
// win32: LIBS += -lopengl32
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QSurfaceFormat>
class Widget : public QOpenGLWidget
public:
Widget()
setWindowTitle("Square. Qt, OpenGL 3.3, C++");
setFixedSize(QSize(400, 400));
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertPosBuffer;
QOpenGLBuffer m_texCoordBuffer;
QMatrix4x4 m_mvpMatrix;
QMatrix4x4 m_projMatrix;
QMatrix4x4 m_viewMatrix;
QMatrix4x4 m_modelMatrix;
int m_uMvpMatrixLocation;
void initializeGL() override
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
const char *vertShaderSrc =
"#version 330\n"
"in vec3 aPosition;"
"uniform mat4 uMvpMatrix;"
"void main()"
""
" gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
"";
const char *fragShaderSrc =
"#version 330\n"
"out vec4 fragColor;"
"void main()"
""
" fragColor = vec4(0.9, 0.9, 1.0, 1.0);"
"";
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
m_program.link();
m_program.bind();
float vertPositions[] =
-0.5f, -0.5f, 0.f,
0.5f, -0.5f, 0.f,
-0.5f, 0.5f, 0.f,
0.5f, 0.5f, 0.f
;
m_vertPosBuffer.create();
m_vertPosBuffer.bind();
m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
m_program.bindAttributeLocation("aPosition", 0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
m_program.enableAttributeArray(0);
m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 50.f),
QVector3D(0.f, 0.f, 0.f),
QVector3D(0.f, 1.f, 0.f));
m_modelMatrix.scale(100.f, 100.f, 100.f);
void paintGL() override
glClear(GL_COLOR_BUFFER_BIT);
m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
m_program.bind();
m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
void resizeGL(int w, int h) override
glViewport(0, 0, w, h);
m_projMatrix.setToIdentity();
m_projMatrix.ortho(-100.f, 100.f, -100.f, 100.f, 100.f, -100.f);
;
int main(int argc, char *argv[])
QApplication a(argc, argv);
QSurfaceFormat format;
// format.setSamples(8);
Widget w;
w.setFormat(format);
w.show();
return a.exec();
【问题讨论】:
无法重现(Linux,Qt5.15.2)。请检查QOpenGLShaderProgram::addShaderFromSourceCode
/ link
/ bind
等返回的值。
所有这些方法都返回 true。我也检查了qDebug() << m_vertPosBuffer.create();
和qDebug() << m_vertPosBuffer.bind();
。我试图重新创建一个新项目,但它与此源代码相同。但是另一个项目没有这个问题。这是魔术。
@G.M.我之前只做了一件事——我禁用了代码分析器,重新运行 Qt Creator 并编写了这个示例。我试图打开另一个示例,但它们没有这个问题。我无法启用分析器,因为我在插件列表中看不到他。我的笔记本电脑很重。
有些事情看起来不太对劲。首先,您的着色器代码暗示您使用的是 3.3 核心配置文件,但您似乎没有按照该配置文件的要求创建顶点数组对象。其次,glDrawArrays
等各种OpenGL
函数入口点如何初始化?您是否在代码的其他地方使用了 glad
或 glew
之类的东西?
@G.M.我的项目中只有一个包含源代码的文件 - main.cpp
。但是为什么当我评论QSurfaceFormat format;
时它会起作用?
【参考方案1】:
我发现了我的愚蠢错误。我只是忘记获取 uMvpMatrix 的统一位置:m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
main.cpp
// Add this line to .pro:
// win32: LIBS += -lopengl32
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QSurfaceFormat>
class Widget : public QOpenGLWidget
Q_OBJECT
public:
Widget()
setWindowTitle("Rectangle. Qt, OpenGL 3.3, C++");
setFixedSize(QSize(400, 400));
resize(400, 400);
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertPosBuffer;
QOpenGLBuffer m_texCoordBuffer;
QMatrix4x4 m_mvpMatrix;
QMatrix4x4 m_projMatrix;
QMatrix4x4 m_viewMatrix;
QMatrix4x4 m_modelMatrix;
int m_uMvpMatrixLocation;
void initializeGL() override
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glEnable(GL_DEPTH_TEST);
const char *vertShaderSrc =
"#version 330\n"
"in vec3 aPosition;"
"uniform mat4 uMvpMatrix;"
"void main()"
""
" gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
"";
const char *fragShaderSrc =
"#version 330\n"
"out vec4 fragColor;"
"void main()"
""
" fragColor = vec4(0.9, 0.9, 1.0, 1.0);"
"";
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
m_program.link();
m_program.bind();
m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
float vertPositions[] =
-0.5f, -0.5f, 0.f,
0.5f, -0.5f, 0.f,
-0.5f, 0.5f, 0.f,
0.5f, 0.5f, 0.f
;
m_vertPosBuffer.create();
m_vertPosBuffer.bind();
m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
m_program.bindAttributeLocation("aPosition", 0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
m_program.enableAttributeArray(0);
m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 50.f),
QVector3D(0.f, 0.f, 0.f),
QVector3D(0.f, 1.f, 0.f));
m_modelMatrix.translate(QVector3D(0.f, 0.f, 0.f));
m_modelMatrix.rotate(20.f, QVector3D(0.f, 0.f, 1.f));
m_modelMatrix.scale(50.f, 70.f, 1.f);
void paintGL() override
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
m_program.bind();
m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
void resizeGL(int w, int h) override
glViewport(0, 0, w, h);
m_projMatrix.setToIdentity();
m_projMatrix.ortho(-100.f, 100.f, -100.f, 100.f, 100.f, -100.f);
;
#include "main.moc"
int main(int argc, char *argv[])
QApplication a(argc, argv);
QSurfaceFormat format;
format.setSamples(8);
Widget w;
w.setFormat(format);
QSurfaceFormat::setDefaultFormat(format);
w.show();
return a.exec();
【讨论】:
以上是关于QSurfaceFormat 不允许使用 OpenGL 进行绘制的主要内容,如果未能解决你的问题,请参考以下文章
对 ios7 的 shm_open 调用现在导致在 O_CREAT (EPERM) 期间不允许操作
IE浏览器在弹出窗口时提示:不支持此接口 window.open()方法是啥原因,以前用得挺好的