本节我们将绘制一个3维物体,立方体. 如果要渲染3D物体,我们需要了解MVP(Model View Projection),它表示三个转换矩阵.实际上这个名字不够明确,更加确切的释义如下: Model - Model to World  模型空间到世界空间 View - World to View      世界空间到视图空间 Projection - View to Projection   视图空间到投影空间 要实现这三个转换矩阵,我们需要借助glm数学库提供的一些方便的结构体和函数. 重构…
在11节我们说过,MVP矩阵中目前只应用了两个矩阵,World to View 矩阵被省略了,这就导致我们的画面没有办法转换视角. 本节我们将添加这一环节,让相机可以旋转. 为了实现这一目的,我们添加一个相机类, Camera类. Camera.h: #pragma once #include <glm\glm.hpp> class Camera { private: glm::vec3 position; glm::vec3 viewDirection; const glm::vec3 UP…
友情提示:继续本节之前,需要保存此前的代码,本节为了试验,会对代码做一些修改,但后续的修改需要我们把代码返回之前的进度. OpenGL内置支持Instancing,有专门的函数来处理这件事情. 为了方便,我们先使用最简单的三角形来学习 先修改sendDataToOpenGL()函数: void MyGlWindow::sendDataToOpenGL() { GLfloat tri[] = { -1.0f,+0.0f, -1.0f,+1.0f, -0.9f,+0.0f }; GLuint ver…
启用Depth Test OpenGL是个3D绘图API,也就是说不只有xy坐标轴,还有第三个坐标轴z,z轴的方向是垂直于屏幕,指向屏幕内. 靠近人眼的方向是负方向,标准化设备坐标的最小值是-1, 最大正值是1. 在未启用深度测试的情况下,同一个像素如果被绘制两次,后绘制的像素会覆盖先绘制的像素. 如果启用了深度测试,情况则完全不同了.后绘制的像素会对深度做一次比较,如果后绘制的像素深度(z)小于之前的像素深度,则会覆盖,如果大于或者等于之前的像素深度,则不会覆盖. Depth需要在绘制之前启用…
从这里就接触到了可编程图形渲染管线. 下面介绍使用Vertex Shader (顶点着色器)和 Fragment Shader(像素着色器)的方法. 我们的目标是使用这两个着色器给三角形填充绿色. 添加了一个cpp文件存放Shader文件,MyShaderCode.cpp: 1 const char* vertexShaderCode = 2 " #version 430 \r\n" 3 " \r\n" 4 " in layout(location=0)…
大部分OpenGL教程都会在一开始就讲解VAO,但是该教程的作者认为这是很不合理的,因为要理解它的作用需要建立在我们此前学过的知识基础上.因此直到教程已经进行了一大半,作者才引入VAO这个概念.在我看来这也是非常合理和自然的. 先预览一下最终的代码逻辑: 准备工作 为了讲解后面的内容,我们对代码进行了更改(算是回退吧,改回到以前不使用Instancing的版本): 去掉了sendDataToOpenGL()函数中关于实例化的部分代码 把VertexShader中的MVP矩阵改回Uniform 在…
我们使用15节学到的知识来绘制14节的立方体. 在第14节我们使用了两次glDrawElements实现了OpenGL实例化,发现这样仍然不太方便,如果需要绘制成千上万的立方体,就需要手写成千上万次的glDrawElements(). 而15节我们知道了glDrawElementsInstanced函数可以支持批量绘制. 我们需要绘制的多个立方体唯一不同的只是转换矩阵,为了达到这个目的,我们只需要定义一组不同的变换矩阵,采用glDrawElementsInstanced即可达到目的. 构建矩阵的…
如果我们需要绘制两个(或者多个)一样的立方体(或者物体),只是位置.缩放.旋转不一样,那么我们可以不需要多次将这个物体的顶点信息.颜色信息等发送到显卡,而是发送一次,绘制多次,仅仅是每次绘制之前应用不同的转换矩阵.这种方法叫做OpenGL Instancing.它的效率比每次都重新发送一次数据到显卡要高很多. 看具体代码: void MyGlWindow::paintGL() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glView…
为了证明我们上节渲染出来的是一个立方体而不是一个平面,我们决定将它旋转一定角度,这样我们就需要一个旋转矩阵(也属于ModelTransformMatrix的一部分) 上一节我们的ModelTransformMatrix中做了一个移动(translation)的操作,所以我们将它重命名为translationMatrix. 先看修改后的paintGL()函数: void MyGlWindow::paintGL() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_B…
本节我们将尝试利用三角形制作一个“走马灯”效果. 一个三角形如图示方式,从左向右依次移动. 先看一下代码: MyGlWindow.cpp #include <gl\glew.h> #include "MyGlWindow.h" #include <iostream> #include <fstream> float triangleWidth = 0.1f; ; ; ; void MyGlWindow::sendDataToOpenGL() { //…
本节将采用两种方法绘制两个三角形. 先看第一种方法的代码 MyGlWindow.cpp #include <gl\glew.h> #include "MyGlWindow.h" void MyGlWindow::initializeGL() { glewInit(); GLfloat verts[] = { +0.0f, +0.0f, +1.0f, +1.0f, -1.0f, +1.0f, +0.0f, +0.0f, -1.0f, -1.0f, +1.0f, -1.0f,…
本节将绘制一个三角形 先看最终代码: MyGlWindow.cpp: #include <gl\glew.h> #include "MyGlWindow.h" void MyGlWindow::initializeGL() { glewInit(); GLfloat verts[]= { +0.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f, }; GLuint myBufferID; glGenBuffers(, &myBufferID…
本节绘制一个三角形,并讲解Buffer Object-缓冲对象 OpenGL的窗口坐标 屏幕中心为坐标原点,横向朝右为x正方向,纵向朝上为y正方向,最大值最小值分别为1,-1. Buffer Object 缓冲对象为内存中的一块空间,用来和OpenGL交互数据. 使用BufferObject的步骤: 创建Buffer的“名称”(或者理解为ID,地址), GLuint类型; 生成Buffer; 绑定Buffer到OpenGL的绑定点(Binding Point); 设置Buffer数据; 具体代码…
用红色来填充GLWidget窗口 修改MyGlWindow.h,添加两个函数,一个用来初始化OpengGL,一个用来绘制OpenGL #pragma once #include <QtOpenGL\qgl.h> class MyGlWindow:public QGLWidget { protected: void initializeGL(); void paintGL(); }; MyGlWindow.cpp #include <gl\glew.h> #include "…
这系列文章是我学习Youtube上一套OpenGL教程的笔记,自己对教程的案例重新制作并且做了一定程度的修改(更有条理,且修正了一些问题).后续将持续更新. Visual Studio 2017工程 教程使用的是visual studio 2012,我电脑上装的是visual studio 2017. 先创建一个Visual C++ Win32 Console Application,命名为GraphicsPad,放在C:\Grphics目录下,不要勾选Create directory for…
在上一节的案例中,我们使用了四个Buffer Object,立方体的VertexBuffer,立方体的索引Buffer,四面体的VertexBuffer,四面体的索引Buffer. 我们这节尝试把两个图形的Vertex Buffer结合,两个图形的索引Buffer结合,形成两个Buffer,让程序更加简化. 先看最终代码: MyGlWindow.cpp: #include <gl\glew.h> #include "MyGlWindow.h" #include <io…
移动相机需要用到键盘按键,按键事件的引入需要包含头文件 #include <Qt3DInput\qkeyevent.h> 并实现QWidget中定义的虚函数keyPressEvent 我们首先在MyGlWindow中重写这个虚函数. 在MyGlWindow.h加入 void keyPressEvent(QKeyEvent*); 在MyGlWindow.cpp中定义: void MyGlWindow::keyPressEvent(QKeyEvent * e) { switch (e->ke…
上节说过矩阵是可以结合的,而且相乘是按照和应用顺序相反的顺序进行的.我们之前初始化translationMatrix和rotationMatrix的时候,第一个参数都是使用的一个初始矩阵 glm::matrix4(),实际上我们可以对代码稍作优化,让初始化过程精简一些. 对比一下优化之前和优化之后的代码: 之前: glm::mat4 projectionMatrix = glm::perspective(30.0f, ((float)width()) / height(), 0.1f, 10.0…
使用之前的方法写Shader是一件很痛苦的事情,把Shader代码直接卸载C++文件中,需要使用很多引号来包裹,既不美观也不方便. 我们这节的目的是使用纯文本文件保存Shader. 首先在工程中创建两个文件,分别命名为VertexShaderCode.glsl 和 FragmentShaderCode.glsl,后缀名可以自己随意指定,不一定非要是glsl. 然后把上节的Shader代码拷贝到两个文件中去. VertexShaderCode.glsl #version ) vec2 positi…
上节的最后我们实现了两个绿色的三角形,而绿色是直接在Fragment Shader中指定的. 这节我们将为这两个三角形进行更加自由的着色——五个顶点各自使用不同的颜色. 要实现这个目的,我们分两步进行,首先 在顶点数组里增加数据用来表示颜色 修改sendDataToOpenGL()函数中的verts数组: GLfloat verts[] = { +0.0f, +0.0f, //Vertex 0 +1.0, +0.0, +0.0f, //Color 0 +1.0f, +1.0f, //Vertex…
MVC框架 同义词 MVC一般指MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面 显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.MVC被独特的发展起来用于 映射传统的输入.处理和输出功能在一个逻辑的图形化用户界面的结构中. 简介 MVC开始是存在于桌面程序中的,M是指业务模型,V是指用…
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 列表部件(List Widget)对应类QListWidget,是从QListView派生的类,用于显示一些数据的列表,不支持多层级数据的显示.QListWidget显示的数据项都通过QListWidgetItem构建. QListWidget是一个便利类,它提供了一个类似于QListView提供的列表视图,具有一个用于添加和删除项的接口.QListWidget使用一个内部模型来管理列表…
最近使用到Qt的Drag Drop功能,结合自己的例子写下来给大家分享一下.实现从QTreeView拖动Node到QGraphicsView上,以及QGraphicsView上item之间的拖动. 先来说Model/View中的实现 1.Model/View要实现Drag Drop操作,首先需要为View设置DragDropMode属性. enum DragDropMode { NoDragDrop, DragOnly, DropOnly, DragDrop, InternalMove } 以上…
http://doc.trolltech.com/main-snapshot/model-view-programming.html 介绍 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的功能上的分离给了开发人员更大的弹性来定制数据项的表示,它也提供一个标准的model接口,使得更多的数据源可以被这些item view使用.这里对model/view的结构进行了描述,结构中的每个组件都进行了解释,给出了一些例子说明了提供的这些类…
MVC模式(Model View Controller): Model:DAO模型 View:JSP  在页面上填写java代码实现显示 Controller:Servlet 重定向和请求的转发: 若目标的相应页面不需要从request里面读取任何信息,则可以使用重定向,可以防止表单重复提交: ------------------------------------------------------------------------------------------------ Stude…
Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也处理用户的输入.为了获得更多的灵性性,交互通过delegagte执行.它既提供输入功能又负责渲染view中的每个数据项. 控制delegates的标准接口在QAbstractItemDelegate类中定义.Delegates通过实现paint()和sizeHint()以达到渲染内容的目的.然而,简…
在views中选择数据项 概念 用于新的view类中的选择模型比Qt3中的模型有了很大的改进.它为基于model/view架构的选择提供了更为全面的描述.尽管对提供了的views来说,负责操纵选择的标准类已经足以应付,但是你也可以创建特定的选择模型来满足你特殊的需求. 关于在view被选择的数据项的信息保持在QItemSelectionModel类的实例中.它也为每个独立的model中的数据项维护model indexes信息,与任何views都关联关系.既然一个model可用于多个views,…
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与底层存储数据项的数据结构完全不同. 内容与显式的分离是通过由QAbstractItemModel提供的标准模型接口,由QAsbstractItemview提供的标准视图接口共同实现的.普遍使用model index来表示数据项.view负责管理从model中读取的数据的外观布局. 它们自己可以去渲染…
创建新的Models 介绍 model/view组件之间功能的分离,允许创建model利用现成的views.这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTreeView来显示来自各种数据源的数据为. QAbstractListModel类提供了非常灵活的接口,允许数据源以层次结构的形式来管理信息,也允许以某种 方式对数据进行插入.删除.修改和存储.它也提供了对拖拽操作的支持. QAbstractListModel与QAbstractTableModel为…
Model类 基本概念 在model/view构架中,model为view和delegates使用数据提供了标准接口.在Qt中,标准接口QAbstractItemModel类中被定义.不管数据在底层以何种数据结构存储,QAabstractItemModel的子类会以层次结构的形式来表示数据,结构中包含了数据项表.我们按这种约定来访问model中的数据项,但这个约定不会对如何显示这些数据有任何限制.数据发生改变时,model通过信号槽机制来通知关联的views. Model Indexes 为了使…