- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在试验新的 QOpenGLWidget 类(请注意,这不是 QGLWidget 类)。
我正在画一个三角形。我有一个普通的顶点着色器,它接收剪辑空间中的坐标,因此不涉及矩阵或投影。其中一个顶点的坐标为 -1, -1, 0, 1
,另一个顶点的坐标为 1, 1, 0, 1
。
当我没有调用任何 glViewport 时,程序呈现为好像我正在调用 glViewport(0, 0, w, h);
在我的 resizeGL 函数中,我不是。也就是说,无论我如何调整窗口大小,三角形的两个顶点都附在窗口的左下角和右上角。
当我在我的 resizeGL
函数中实际添加一个对 glViewport
的调用时,它显然被忽略了——如果我传递 w 也没关系/2、h/2 或任何其他值,渲染与调用 glViewport(0, 0, w, h);
时完全相同(例如,我希望在 glViewport(0, 0, w/2, h/2);
)
当我在 paingGL
函数中调用 glViewport(0, 0, width()/2, height()/2)
时,渲染如预期 - 一切正常绘制在窗口的左下角。
所以看起来 glViewport 在 resizeGL
和 paintGL
之间的某处被覆盖了。这是怎么回事,我该如何解决?我是否必须求助于在我的 paintGL
函数中进行视口(viewport)转换?
文档中列出的 QGLWidget 和 QOpenGLWidgets 之间的区别之一是后者呈现到帧缓冲区而不是直接呈现到屏幕。这能成为解释的关键吗?
为了以防万一,我附上了完整的代码以供引用。
//三角形.h
#ifndef TRIANGLE_H
#define TRIANGLE_H
#include <QOpenGLBuffer>
#include <QOpenGLFunctions>
class Triangle
{
public:
Triangle();
void render();
void create();
private:
QOpenGLBuffer position_vbo;
QOpenGLFunctions *glFuncs;
};
#endif // TRIANGLE_H
//三角形.cpp
#include "triangle.h"
Triangle::Triangle()
:position_vbo(QOpenGLBuffer::VertexBuffer)
{
}
void Triangle::create()
{
glFuncs = QOpenGLContext::currentContext()->functions();
position_vbo.create();
float val[] = {
-1.0f, -1.0f, 0.0f, 1.0f,
0.0f, -0.366f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
position_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
position_vbo.bind();
position_vbo.allocate(val, sizeof(val));
position_vbo.release();
}
void Triangle::render()
{
position_vbo.bind();
glFuncs->glEnableVertexAttribArray(0);
glFuncs->glEnableVertexAttribArray(1);
glFuncs->glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glFuncs->glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)(3*4*sizeof(float)));
glFuncs->glDrawArrays(GL_TRIANGLES, 0, 3);
glFuncs->glDisableVertexAttribArray(0);
glFuncs->glDisableVertexAttribArray(1);
position_vbo.release();
}
//控件.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include "triangle.h"
class Widget : public QOpenGLWidget
, protected QOpenGLFunctions
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
protected:
virtual void initializeGL() override;
virtual void paintGL() override;
virtual void resizeGL(int w, int h) override;
private:
QOpenGLShaderProgram* program;
Triangle t;
};
#endif // WIDGET_H
//控件.cpp
#include "widget.h"
#include <exception>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
Widget::~Widget()
{
}
void Widget::initializeGL()
{
initializeOpenGLFunctions();
program = new QOpenGLShaderProgram(this);
if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vertexshader.vert"))
{
throw std::exception(("Vertex Shader compilation error: " + program->log()).toLocal8Bit().constData());
}
if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fragmentshader.frag"))
{
throw std::exception(("Fragment Shader compilation error: " + program->log()).toLocal8Bit().constData());
}
if(!program->link())
{
throw std::exception(("Program Link error: " + program->log()).toLocal8Bit().constData());
}
t.create();
}
void Widget::paintGL()
{
glClearColor(0.f, 0.15f, 0.05f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
//glViewport(0, 0, width()/2, height()/2); //works!!
program->bind();
t.render();
program->release();
}
void Widget::resizeGL(int w, int h)
{
glViewport(0, 0, w/2, h/2); //doesn't work
}
// main.cpp
#include "widget.h"
#include <exception>
#include <QApplication>
#include <QMessageBox>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
try
{
Widget w;
w.show();
return a.exec();
}
catch(std::exception const & e)
{
QMessageBox::warning(nullptr, "Error", e.what());
}
}
//顶点着色器
#version 330
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
smooth out vec4 theColor;
void main()
{
gl_Position = position;
theColor = color;
}
//片段着色器
#version 330
out vec4 fragColor;
smooth in vec4 theColor;
void main()
{
fragColor = theColor;
}
最佳答案
So it seems that the glViewport is overridden somewhere between resizeGL and paintGL. What is going on and how do I fix it? Do I have to resort to doing viewport transformations in my paintGL function?
Qt5 可能会使用 OpenGL 进行自己的绘图。此外,作为 QOpenGLWindow 子级的小部件的内容将呈现给 FBO。所以这意味着,在您的代码和 Qt 执行的操作之间进行了大量的 glViewport 调用。
When I actually add a call to glViewport in my resizeGL function, it is apparently ignored (…)
是的。而你的期望究竟是什么?调用 glViewport
以使 OpenGL 程序健壮的唯一有效位置是在绘图代码中。将 glViewport
放在窗口调整大小处理程序中的每一个教程都是错误的,应该被烧掉。
When I call glViewport(0, 0, width()/2, height()/2) in paingGL function, the rendering is as expected
是的,这就是您应该使用它的方式。
关于c++ - QOpenGLWidget 的 resizeGL 不是调用 glViewport 的地方?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33059185/
我很难理解这些是如何工作的。首先,在 2d 游戏中,投影矩阵应该设置为左、右、上、下与窗口匹配的正交投影矩阵,对吗?但是当窗口调整大小时,我应该只更改 glViewport,而不是投影矩阵吗?以及如何
在“多点触控”环境中,显示在表面上的任何应用程序都可以旋转/缩放到用户的方向。实际的解决方案是在 FBO 上绘制应用程序,并绘制一个带有纹理的旋转/缩放矩形。我不认为这对性能有好处,而且所有显卡都不提
我有一个在世界坐标中定义的对象,比如一个以 (2,3) 为中心、半径为 4 的圆。如果我希望圆不变形,则在视口(viewport)中完全可见并在视口(viewport)中尽可能大,我如何制定一个 gl
我对 glViewport 有疑问。在我的小程序中,我有两个视口(viewport)。我可以在其中一个视口(viewport)中绘制一个表格(使用 motionfunc),在另一个视口(viewpor
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我制作了一个大小为 800x600 的窗口。我打了电话 gluOrtho2D(-400,400,-300,300); glViewport(400,300,400,300); 我在 (-100,-10
在底部编辑我已添加源文件 我的程序只是渲染一个三角形,但它工作正常,但是当我使用glviewport函数将其设置为x和y的createwindow尺寸,即640和640并在两台不同的计算机上运行相同的
我读了这个tutorial我正确地执行了它。 但是,我想应用一些更改。第一个变化是看到该圆的不同 View ,例如仅显示圆的 1/4。我知道这是由 glViewPort(parameters) 完成的
我正在使用现代 opengl,我的目标是调试视锥体剔除。为了实现这一点,我创建了另一个视口(viewport),这样我就可以在我的主要程序中移动时查看我的整个模型和我的平截头体移动。 它有效,但仍然有
我正在对 FrameBufferObject 进行渲染传递,这样我就可以在下一个渲染传递中将结果用作纹理。查看教程,我需要调用: glBindFramebuffer(GL_TEXTURE2D, mFr
在 OpenGL-ES 上,我对设置之间的区别感到困惑 glOrthof() glViewPort() GLU.gluOrtho2D() 及其各自的参数。因为我相信这一切都将您可以看到的部分设置为指
我有一个包含大约 3 个不同大小的帧缓冲区的程序。我在开始时初始化它们,为它们提供适当的渲染目标并更改每个的视口(viewport)大小。 我原本以为你只需调用glViewport仅当您初始化帧缓冲区
我用 OpenGL 和 C 编写了一个小型拼贴游戏引擎,但我似乎无法弄清楚问题出在哪里。我的主循环看起来像这样: void main_game_loop() { (poll for event
我创建了一个带有 Canvas 的 JFrame,如下面的代码所示。我想做的是在屏幕尺寸更新时调整 openGL 上下文的大小。这应该像调用 glViewport() 一样简单,我在名为 resize
我刚刚开始使用 opengl es 为我的跨平台框架(iOS 和 Android)制作渲染器。当我到达视口(viewport)的东西(分屏的东西需要)并注意到 iOS 和 Android 之间存在差异
我正在试验新的 QOpenGLWidget 类(请注意,这不是 QGLWidget 类)。 我正在画一个三角形。我有一个普通的顶点着色器,它接收剪辑空间中的坐标,因此不涉及矩阵或投影。其中一个顶点的坐
我将 glViewport 放在 QOpenGLWidget::resizeGL 覆盖的虚拟函数中,它确实被调用并设置视口(viewport)仅使用部分小部件空间。但它没有任何效果,内容仍然绘制到小部
在大多数 Android OpenGL 示例中,我看到人们在 onSurfaceChanged 中调用 glViewport。但是,我只是注意到,如果我将其注释掉,我的程序的行为仍然相同。所以有必要调
原始问题 我想使用“gluPerspective”、“glViewport”和“gluLookAt”来操作我的相机和屏幕。 我将哪些功能应用于哪种矩阵模式?我应该/必须以什么顺序使用它们? 例如,我正
为什么我们将 0 作为 GLES20.glViewport(0, 0, width, height) 的前两个参数传递?什么意思? 最佳答案 看看规范,它解释了一切:Opengl spec . 参数
我是一名优秀的程序员,十分优秀!