3.QOpenGLWidget-通过着色器来渲染渐变三角形
#version version_number
in type in_variable_name;
in type in_variable_name;
out type out_variable_name;
uniform type uniform_name; //type:变量类型,是一个可以包含有1、2、3或者4个分量的容器,可以定义为float(vecn)、bool(bvecn)等类型,在第2节讲述
int main()
{
// 处理输入并进行一些图形操作
...
// 输出处理过的结果到输出变量
out_variable_name = weird_stuff_we_processed;
}
当我们特别谈论到顶点着色器的时候,每个输入变量也叫顶点属性(老版本的Vertex Attribute)。我们能声明的顶点属性是有上限的,它一般由硬件来决定。
int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl; //打印上限
2.数据类型
|
类型
|
含义
|
|
vecn
|
包含n个float分量的默认向量
|
|
bvecn
|
包含n个bool分量的向量
|
|
ivecn
|
包含n个int分量的向量
|
|
uvecn
|
包含n个unsigned int分量的向量
|
|
dvecn
|
包含n个double分量的向量
|
vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
vec2 vect = vec2(0.5, 0.7); //初始化vect,设置第一分量为0.5、第二分量为0.7
vec4 result = vec4(vect, 0.0, 0.0); //初始化result,设置XYZW为0.5,0.7,0.0 ,0.0
vec4 otherResult = vec4(result.xyz, 1.0);
3.输入与输出
glUniform{1,2,3,4}{i,f,ub,ui,uiv,dv,v}
比如glUniform1i()、glUniform4ui等,其中i表示32位整形,f表示32位浮点型,ub表示8位无符号byte,ui表示32位无符号整形,v表示指针类型。
glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); //表示设置location位置的uniform变量值的xyzw分量
#version 330 core
layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为0 void main()
{
gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数 }
#version 330 core
out vec4 FragColor; uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量 void main()
{
FragColor = ourColor;
}
float timeValue = glfwGetTime();//获取运行的秒数
float greenValue = (sin(timeValue) / 2.0f) + 0.5f; //让颜色在0.0到1.0之间改变
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");//查询uniform ourColor的位置值
glUseProgram(shaderProgram);
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); //设置颜色

float vertices[] = {
// 位置 // 颜色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部
};
#version 330 core
layout (location = 0) in vec3 aPos; //位置变量的属性位置值为 0
layout (location = 1) in vec3 aColor; //颜色变量(发送给fragment shader)的属性位置值为 1 out vec3 ourColor; // 向片段着色器输出一个颜色 void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor; // 将ourColor设置为我们从顶点数据那里得到的输入颜色
}
#version 330 core
out vec4 FragColor;
in vec3 ourColor; //vertex shader 传入的数据
void main()
{
FragColor = vec4(ourColor, 1.0);
}
具体代码如下所示:
#include "myglwidget.h"
#include <QtDebug> //GLSL3.0版本后,废弃了attribute关键字(以及varying关键字),属性变量统一用in/out作为前置关键字
#define GL_VERSION "#version 330 core\n" #define GLCHA(x) #@x //加单引号
#define GLSTR(x) #x //加双引号
#define GET_GLSTR(x) GL_VERSION#x const char *vsrc = GET_GLSTR( layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
}
); const char *fsrc =GET_GLSTR(
out vec4 FragColor;
in vec3 ourColor;
void main()
{
FragColor = vec4(ourColor, 1.0);
}
); myGlWidget::myGlWidget(QWidget *parent):QOpenGLWidget(parent)
{
} void myGlWidget::paintGL()
{
// 绘制
// glViewport(0, 0, width(), height()); glClear(GL_COLOR_BUFFER_BIT); // 渲染Shader
vao.bind(); //绑定激活vao
glDrawArrays(GL_TRIANGLES, 0, 3); //绘制3个定点,样式为三角形
vao.release(); //解绑
}
void myGlWidget::initializeGL()
{ // 为当前环境初始化OpenGL函数
initializeOpenGLFunctions(); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置背景色为白色 //1.创建着色器程序
program = new QOpenGLShaderProgram;
program->addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program->addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program->link();
program->bind();//激活Program对象 //2.初始化VBO,将顶点数据存储到buffer中,等待VAO激活后才能释放
float vertices[] = {
// 位置 // 颜色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下 颜色对应红色(1.0f, 0.0f, 0.0f)
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下 颜色对应绿色
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部 颜色对应蓝色
}; vbo.create();
vbo.bind(); //绑定到当前的OpenGL上下文,
vbo.allocate(vertices, 18*sizeof(GLfloat));
vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); //设置为一次修改,多次使用 //3.初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)
vao.create();
vao.bind(); // void setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride = 0);
program->setAttributeBuffer(0, GL_FLOAT, 0, 3, 6 * sizeof(float)); //设置aPos顶点属性
program->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(float), 3, 6 * sizeof(float)); //设置aColor顶点颜色
//offset:第一个数据的偏移量
//tupleSize:一个数据有多少个元素,比如位置为xyz,颜色为rgb,所以是3
//stride:步长,下个数据距离当前数据的之间距离,比如右下位置和左下位置之间间隔了:3个xyz值+3个rgb值,所以填入 6 * sizeof(float) program->enableAttributeArray(0); //使能aPos顶点属性
program->enableAttributeArray(1); //使能aColor顶点颜色 //4.解绑所有对象
vao.release();
vbo.release(); }
void myGlWidget::resizeEvent(QResizeEvent *e)
{ }
3.QOpenGLWidget-通过着色器来渲染渐变三角形的更多相关文章
- D3D三层Texture纹理经像素着色器实现渲染YUV420P
简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Te ...
- WebGL着色器渲染小游戏实战
项目起因 经过对 GLSL 的了解,以及 shadertoy 上各种项目的洗礼,现在开发简单交互图形应该不是一个怎么困难的问题了.下面开始来对一些已有业务逻辑的项目做GLSL渲染器替换开发. 起因是看 ...
- OpenGl中使用着色器的基本步骤及GLSL渲染简单示例
OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...
- Turing渲染着色器网格技术分析
Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...
- 关于着色器LinearGradient的使用
LinearGradient我们可以将之译为线型渐变.线型渲染等,译成什么不重要,重要的是它的显示效果是什么样子,今天我们就一起来看看. 先来看看LinearGradient的构造方法: /** Cr ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader) 代码工 ...
- LearnOpenGL学习笔记(二)——着色器简单理解
着色器在OpenGL中发挥着重要作用,它就像一个画笔,将输入的数据流,转为数学坐标,再将三维坐标变成二维坐标(针对我们现在用的二维显示器,全息显示器肯是三维的),再把二维坐标实际的像素点位置(这里面肯 ...
- Shader基础(固定管线着色器)
在Shader的编码中,要养成不加空格的习惯,否则会有时候出现一些错误 固定管线着色器: 优点:实现简单 缺点:处理的效果比较差 //设置Shader的路径 Shader "MyFixedS ...
- 在pixi中使用你的自定义着色器
通过几天的学习,对openGL.shader有了一个大致的了解. 回到学习的初衷吧,在基于pixi.js重构D3项目的时候,因为精灵层级的问题,我得按照一定的先后顺序将不同类别的精灵添加到场景中去. ...
随机推荐
- Linux实战(7):centos7安装xrdp
系统环境:最小化安装,无安装桌面化 操作 yum更新 yum -y update 安装依赖. tigervnc-server.xrdp .GNOME Desktop yum -y install ep ...
- Oracle学习(六)存储过程
一.简介 1.定义 所谓存储过程,就是一段存储在数据库中执行某块业务功能的程序模块. 它是由一段或者多段的PL/SQL代码块或者SQL语句组成的一系列代码块. 2.结构分析 create [or re ...
- kubeadm单集群部署k8s1.15.1&flannel网络
说明 本次实验在Windows下的VMware进行 系统配置及初始化配置在所有的主机执行 容器镜像全部替换为国内可拉取的 pod网络采用flannel 实验环境 主机名 IP地址 角色 OS CPU/ ...
- MySQL: 1、MySQL基础
一.数据库基本概念 1.什么是数据库? 数据就是存储和管理数据库的仓库,本质上是一个文件系统,以文件的方式将数据保存再电脑上 2.为什么使用数据库? 使用数据库存储数据用户可以方便的对数据库中的数据进 ...
- IntelliJ IDEA 2020.2 x64 最新破解教程有效期到2089年 完全免费分享
作者:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.com 个 ...
- Spring及tomcat初始化日志
Tomcat StandardContext初始化过程 //org.apache.catalina.core.StandardContext#startInternal // 子容器启动 for (C ...
- 结合 Shell 对 Koa 应用运行环境检查
在开发环境中,启动一个koa 应用服务,通常还需要同时启动数据库.比如.Mongodb.mysql 等 如果一直开着数据库服务,在不使用的话,电脑会占一定的性能.然而如果每次手动去启动服务,效率又不高 ...
- 使用Redis做消息队列
基于内存的单线程数据库,使Redis的线程安全性极高.而Redis的双向链表数据类型(List)天生就可作为消息队列存储消息. 在这里就不说消息队列的等等一些优点.但是补充一下Redis的List类型 ...
- Python练习题 008:打印101-200之间的所有素数
[Python练习题 008]判断101-200之间有多少个素数,并输出所有素数. ---------------------------------------------------------- ...
- 052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试——debug2 多断点调试程序
052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试--debug2 多断点调试程序 本文知识点: Eclipse下程序调 ...