前面文章中讲到的 OPenGL 渲染都是在页面加载完成即立刻渲染的,如果向控制图形渲染的时间,可以在QT界面中添加一些元素来进行控制。此时需要用到OPenGL当中的makeCurrent(),update(),doneCurrent()函数。
效果展示:
opengl与qt交互
在myopenglwidget.h文件中添加一个枚举,放置要绘制的图形类型,同时声明三个函数,分别为drawShape(),clearGraphic(),setWireFrame(),方便主界面上的元素调用,相应代码如下:
myopenglwidget.h:
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
#include <QObject>
#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
class MyOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
//添加图形类型枚举
enum Shape{None,Rect,Circle,Triangle};
explicit MyOpenGLWidget(QWidget *parent = nullptr);
//添加三个辅助函数
void drawShape(Shape shape);
void clearGraphic();
void setWireFrame(bool wireFrame);
protected:
virtual void initializeGL() override;
virtual void resizeGL(int w, int h) override;
virtual void paintGL() override;
signals:
private:
//定义一个中间变量
Shape m_shape;
};
#endif // MYOPENGLWIDGET_H
对上面的三个辅助函数进行设计,其中每触发一个函数,都应该让OPenGL重新绘制,此时应调用 update() 函数,而在更新视图之前,需要记录当前的视图是什么样的,所以还需要在此之前调用 makeCurrent() 函数,视图更新结束后,需要告知OPenGL已经绘制完毕,此时需要调用 doneCurrent() 函数,相应代码如下:
myopenglwidget.cpp:
#include "myopenglwidget.h"
unsigned int VBO,VAO;
//添加一个索引控制器
unsigned int EBO;
//定义一个全局的着色器控制器
unsigned int shaderProgram;
float vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,0.0f
};
//使用4个顶点数据绘制两个三角形
float vertices2[] = {
0.5f,0.5f,0.0f,
0.5f,-0.5f,0.0f,
-0.5f,-0.5f,0.0f,
-0.5f,0.5f,0.0f
};
//添加索引数据
unsigned int indices[]={
0,1,3,
1,2,3
};
MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}
//绘制图形辅助函数
void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{
makeCurrent();//记录当前视图
m_shape = shape;
update();//视图更新
doneCurrent();//结束视图更新
}
//清空函数
void MyOpenGLWidget::clearGraphic()
{
makeCurrent();
drawShape(MyOpenGLWidget::None);
makeCurrent();
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
update();
doneCurrent();
}
//设置线框模式函数
void MyOpenGLWidget::setWireFrame(bool wireFrame)
{
makeCurrent();
if(wireFrame){
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//以线框模式绘制图形
}else{
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//以填充模式绘制图形
}
update();
doneCurrent();
}
void MyOpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
shaderProgram = glCreateProgram();
//void glGenVertexArrays(GLsizei n, GLuint *arrays)生成顶点数组对象名称
// n: 要产生的VAO对象的数量
// arrays: 存放产生的VAO对象的名称
glGenVertexArrays(1,&VAO);
// void glGenBuffers(GLsizei n,GLuint *buffers)生成顶点缓冲对象
// n: 要产生的VBO对象的数量
// arrays: 存放产生的VBO对象的名称
glGenBuffers(1,&VBO);
//初始化索引器
glGenBuffers(1,&EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof (indices),indices,GL_STATIC_DRAW);
//绑定VAO和VBO
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
//在VBO中存入顶点数据
glBufferData(GL_ARRAY_BUFFER,sizeof (vertices2),vertices2,GL_STATIC_DRAW);
//告诉VAO怎么在VBO中拿数据
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof (float),(void*)0);
//开启第一个VAO
glEnableVertexAttribArray(0);
//用完之后解除绑定(信息已经被记录下来了)
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
}
void MyOpenGLWidget::resizeGL(int w, int h)
{
Q_UNUSED(w);
Q_UNUSED(h);
}
void MyOpenGLWidget::paintGL()
{
glClearColor(0.5f,0.9f,0.4f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//在渲染前只需开启对应的VAO即可
glBindVertexArray(VAO);
//switch判断 m_shape 的类型,进行不同图形的绘制
switch (m_shape) {
case Rect:
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,&indices);
break;
default:
break;
}
}
在主界面中添加三个按钮,分别用来绘制,清空,设置线框模式,并相应其clicked信号,调用对应的函数即可,相应代码如下:
myopenglwidget.h:
#ifndef LEARNOPENGL_H
#define LEARNOPENGL_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class LearnOpenGL; }
QT_END_NAMESPACE
class LearnOpenGL : public QMainWindow
{
Q_OBJECT
public:
LearnOpenGL(QMainWindow *parent = nullptr);
~LearnOpenGL();
private slots:
//三个按钮的槽函数
void on_btn_drawRect_clicked();
void on_btn_Clear_clicked();
void on_btn_setFrame_clicked();
private:
Ui::LearnOpenGL *ui;
};
#endif // LEARNOPENGL_H
myopenglwidget.cpp:
#include "learnopengl.h"
#include "ui_learnopengl.h"
LearnOpenGL::LearnOpenGL(QMainWindow *parent)
: QMainWindow(parent)
, ui(new Ui::LearnOpenGL)
{
ui->setupUi(this);
setCentralWidget(ui->openGLWidget);
}
LearnOpenGL::~LearnOpenGL()
{
delete ui;
}
void LearnOpenGL::on_btn_drawRect_clicked()
{
ui->openGLWidget->drawShape(MyOpenGLWidget::Rect);//调用绘制图形
}
void LearnOpenGL::on_btn_Clear_clicked()
{
ui->openGLWidget->clearGraphic();//调用清空图形
}
bool frame = true;
void LearnOpenGL::on_btn_setFrame_clicked()
{
ui->openGLWidget->setWireFrame(frame);//调用线框模式
frame = !frame;
}
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决