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项目的时候,因为精灵层级的问题,我得按照一定的先后顺序将不同类别的精灵添加到场景中去. ...
随机推荐
- unserialize3 攻防世界
序列化是将对象转换为便于保存的字符串, 而反序列化是将便于保存的字符串转换为字符串. _wakeup()魔法方法 如果直接传参给code会被__wakeup()函数再次序列化,所以要绕过他, 利用__ ...
- 《C++深度解析》课程目录
<C++深度解析>课程目录 第1课 - 学习 C++ 的意义 第2课 - C到C++的升级 第3课 - 进化后的const分析 第4课 - 布尔类型和引用 第5课 - 引用的本质分 ...
- 【高并发】面试官:Java中提供了synchronized,为什么还要提供Lock呢?
写在前面 在Java中提供了synchronized关键字来保证只有一个线程能够访问同步代码块.既然已经提供了synchronized关键字,那为何在Java的SDK包中,还会提供Lock接口呢?这是 ...
- 我的Python自学之路-003 字符串的知识
'''字符串是以引号或者单引号括起来的任意文本,例如"123","asdfjk",'adfa'引号或者单引号,只是一种表示方法,并不是字符串的一部分如果字符串本 ...
- Linux实战(12):Centos装机常用脚本-进阶版
#!/bin/bash #shell菜单演示 function menu() { echo -e `date` cat <<EOF ---------------------------- ...
- 动态加载dll的实现+远线程注入
1.在目标进程中申请内存 2.向目标进程内存中写入shellcode(没有特征,编码比较麻烦) 3.创建远线程执行shellcode 之前可以看到shellcode很难编写还要去依赖库,去字符串区等等 ...
- VueX中state变化捕捉不到_getters监测不到state的变化
原因 可能有多种原因, 现在我说一下我碰到的一种情况: state种有一个变量叫state,它是一个json对象, 可把我害惨了.因为他这个json长这个样: messageBox:{ friendI ...
- Vue常用指令详解分析
Vue入门 Vue是一个MVVM(Model / View / ViewModel)的前端框架,相对于Angular来说简单.易学上手快,近两年也也别流行,发展速度较快,已经超越Angular了.比较 ...
- Python实现的数据结构与算法之快速排序详解
一.概述 快速排序(quick sort)是一种分治排序算法.该算法首先 选取 一个划分元素(partition element,有时又称为pivot):接着重排列表将其 划分 为三个部分:left( ...
- MATLAB中exist函数的用法
exist:exist主要有两种形式,一个参数和两个参数的,作用都是用于确定某值是否存在:1. b = exist( a) 若 a 存在,则 b = 1: 否则 b = 0:2. b = e ...