缓冲区类型 1、顶点缓冲区(ARRAY_BUFFER) 2、索引缓冲区(ELEMENT_ARRAY_BUFFER) 3、纹理 4、帧缓冲(可能包含深度缓冲区) 5、深度缓冲区 6、颜色缓冲区 7、模板缓冲区
矩阵 1、模型矩阵 2、观察矩阵 3、投影矩阵 4、视口
opengl 纯可编程式管线技术 创建main 往main插入代码 然后 编译代码 创建进程 把编译好的main放入进程 链接进程 使用进程
创建一个缓冲区
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body onload="initLoad()">
<canvas id="myCanvas"></canvas>
</body>
<script id="vertexShader" type="x-shader/x_vertex">
attribute vec3 v3Position;
void main(void)
{
gl_Position = vec4(v3Position,1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x_fragment">
void main(void)
{
gl_FragColor = vec4(0.0,1.0,1.0,1.0);
}
</script>
<script>
var VSHADER_SOURCE =
"attribute vec4 v3Position;" +
"void main() {" +
//设置坐标
"gl_Position = v3Position; " +
"} ";
var FSHADER_SOURCE =
"void main() {" +
//设置颜色
"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
"}";
var webgl
var programObject
function initLoad() {
var v3PositionIndex = 0;
var canvas = document.getElementById('myCanvas');
webgl = canvas.getContext('webgl');
webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
// 向显卡传递要执行的代码
// 初始化类似创建了一个main
// 创建顶点着色器对象
var vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
// 创建片元着色器对象
var fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
// 像main函数里插入代码
webgl.shaderSource(vertexShaderObject, VSHADER_SOURCE)
webgl.shaderSource(fragmentShaderObject, FSHADER_SOURCE)
// 编译代码
webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);
if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) {
// 获取vertexShaderObject的编译状态
alert("error:vertexShaderObject");
}
if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) {
// 获取fragmentShaderObject的编译状态
alert("error:fragmentShaderObject");
}
// 创建一个进程类似exe
programObject = webgl.createProgram();
// 向进程里传入编译好的程序
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
// 输入值
webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");
// 链接生成一个真正的可执行程序
webgl.linkProgram(programObject)
if (!webgl.getProgramParameter(programObject, webgl.LINK_STATUS)) {
// 获取fragmentShaderObject的编译状态
alert("error:programObject");
}
console.log(webgl.getAttribLocation(programObject, 'v3Position'))
// glsl
// 使用这个可执行程序
webgl.useProgram(programObject);
// 坐标
var jsArrayData = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
]
var triangleBuffer = webgl.createBuffer(); // 创建一个缓冲区
// 绑定
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
// 给缓冲区绑定值和类型 第三个参数标识静态类型
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW); // 如果经常要变化的话使用 DYNAMIC_DRAW
// 偶尔变STREAM_DRAW 顶点缓冲区的三种类型
// webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
//将缓冲区对象分配给v3PositionIndex变量
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
//连接v3PositionIndex变量与分配给它的缓冲区对象
webgl.enableVertexAttribArray(v3PositionIndex);
// 清除指定<画布>的颜色
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空 <canvas>
webgl.clear(webgl.COLOR_BUFFER_BIT);
// 要赋值的名称 类型就是几维度 变量的类型 是否规格化
webgl.drawArrays(webgl.TRIANGLES, 0, 3);
}
</script>
</html>
</script>
</html>
</script>
</html>
顶点缓冲区
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW);
webgl.bufferData(webgl.ARRAY_BUFFER,4 * 9, webgl.STATIC_DRAW); // 字节
// 更新部分缓冲区
webgl.bufferSubData(webgl.ARRAY_BUFFER,2,new Float32Array([]))
// 修改从第二个字节开始修改成后面的内容
索引缓冲区
假如要绘制一个矩形的话 可以通过两个三角形拼接起来
var v3PositionIndex = 0;
var VSHADER_SOURCE =
"attribute vec3 v3Position;" +
"void main() {" +
//设置坐标
"gl_Position = vec4(v3Position,1.0); " +
"} ";
var FSHADER_SOURCE =
"void main() {" +
//设置颜色
"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
"}";
let webgl = null;
let programObject = null;
var canvas = document.getElementById('myCanvas');
webgl = canvas.getContext('webgl');
webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
var vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
var fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
webgl.shaderSource(vertexShaderObject, VSHADER_SOURCE)
webgl.shaderSource(fragmentShaderObject, FSHADER_SOURCE)
webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);
programObject = webgl.createProgram();
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
webgl.linkProgram(programObject);
webgl.useProgram(programObject);
webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");
var triangleBuffer = webgl.createBuffer();
var jsArrayData2 = [
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0
]
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData2), webgl.STATIC_DRAW);
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
webgl.enableVertexAttribArray(v3PositionIndex);
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT);
webgl.drawArrays(webgl.TRIANGLES, 0, 6);
然后矩形就画好了 但是 下面的那个用来绘图的float数组一个是4个字节 所有画矩形时需要向显卡传输4*3*6字节的内容(72字节)
可以发现有些坐标是重复的 可以少写两个点可以节省4*3*2个字节(24字节)
可以用到索引缓冲区
var jsArrayData2 = [
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0
]
用法
可以看出这个矩形是由两个三角形012和023构成的
var v3PositionIndex = 0;
var VSHADER_SOURCE =
"attribute vec3 v3Position;" +
"void main() {" +
//设置坐标
"gl_Position = vec4(v3Position,1.0); " +
"} ";
var FSHADER_SOURCE =
"void main() {" +
//设置颜色
"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
"}";
let webgl = null;
let programObject = null;
var canvas = document.getElementById('myCanvas');
webgl = canvas.getContext('webgl');
webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
var vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
var fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
webgl.shaderSource(vertexShaderObject, VSHADER_SOURCE)
webgl.shaderSource(fragmentShaderObject, FSHADER_SOURCE)
webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);
programObject = webgl.createProgram();
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
webgl.linkProgram(programObject);
webgl.useProgram(programObject);
webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");
// 修改的内容------
// 这里是矩形的四个点
var jsArrayData2 = [
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0
]
// 索引数组
var indexArray = [
0,1,2,
0,2,3
]
// ------
var triangleBuffer = webgl.createBuffer();
// 创建一个索引缓冲区
var indexBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData2), webgl.STATIC_DRAW);
// 操作索引缓冲区
// 把当前操作的缓冲区换成indexBuffer
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer);
// 赋值 注意这里只能使用无符号的短整型
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), webgl.STATIC_DRAW);
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
webgl.enableVertexAttribArray(v3PositionIndex);
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT);
// 这里调用绘画的方法就要变了
// webgl.drawArrays(webgl.TRIANGLES, 0, 6);
// 第一个参数绘画的类型 ,第二个参数要话几个点 几个索引就一般就几个点 第三个索引值的类型 ,第四个参数是偏移值offset 从几个索引开始绘制
webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_SHORT, 0)
运行效果和上面一样 渐变的矩形
var v3PositionIndex = 0;
var inColor = 1;
var VSHADER_SOURCE =
"precision lowp float;" +
"attribute vec3 v3Position;" +
"attribute vec4 inColor;" +
"varying vec4 outColor;" +
"void main() {" +
//设置坐标
"outColor= inColor;" +
"gl_Position = vec4(v3Position,1.0); " +
"} ";
var FSHADER_SOURCE =
"precision lowp float;" +
"varying vec4 outColor;" +
"void main() {" +
//设置颜色
"gl_FragColor = outColor;" +
"}";
let webgl = null;
let programObject = null;
var canvas = document.getElementById('myCanvas');
webgl = canvas.getContext('webgl');
webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
var vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
var fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
webgl.shaderSource(vertexShaderObject, VSHADER_SOURCE)
webgl.shaderSource(fragmentShaderObject, FSHADER_SOURCE)
webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);
programObject = webgl.createProgram();
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
webgl.linkProgram(programObject);
webgl.useProgram(programObject);
webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");
// 修改的内容------
// 这里是矩形的四个点
var jsArrayData2 = [
// x,y,z,r,g,b,a
-0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0,
0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0,
0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0,
-0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0,
]
// 索引数组
var indexArray = [
0,1,2,
0,2,3
]
// ------
var triangleBuffer = webgl.createBuffer();
// 创建一个索引缓冲区
var indexBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData2), webgl.STATIC_DRAW);
// 操作索引缓冲区
// 把当前操作的缓冲区换成indexBuffer
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer);
// 赋值 注意这里只能使用无符号的短整型
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), webgl.STATIC_DRAW);
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 4 * 7, 0);
webgl.vertexAttribPointer(inColor, 4, webgl.FLOAT, false, 4 * 7, 3 * 4);
webgl.enableVertexAttribArray(v3PositionIndex);
webgl.enableVertexAttribArray(inColor);
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT);
// 这里调用绘画的方法就要变了
// webgl.drawArrays(webgl.TRIANGLES, 0, 6);
// 第一个参数绘画的类型 ,第二个参数要话几个点 几个索引就一般就几个点 第三个索引值的类型 ,第四个参数是偏移值offset 从几个索引开始绘制
webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_SHORT, 0)
查看顶点着色器对象和片元着色器对象编译后的错误信息
var canvas = document.getElementById('myCanvas');
webgl = canvas.getContext('webgl');
if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) {
// 获取vertexShaderObject的编译状态
var err = webgl.getShaderInfoLog(vertexShaderObject)
console.log(err)
alert("error:vertexShaderObject");
}
if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) {
// 获取fragmentShaderObject的编译状态
var err = webgl.getShaderInfoLog(fragmentShaderObject)
console.log(err)
alert("error:fragmentShaderObject");
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!