WEBGL学习【三】颜色选择
<html lang="zh-CN"> <head>
<title>NeHe's WebGL</title>
<meta charset="UTF-8"/>
<!--引入需要的库文件-->
<script type="text/javascript" src="Oak3D_v_0_5.js"></script> <!--片元着色器;为JavaScript片段指定一个ID编号,后面我可以更具这个ID编号来获取这段片元着色器的JavaScript片段代码-->
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float; varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script> <!--顶点着色器;后面可以通过ID编号来获取这段顶点着色器代码-->
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor; uniform mat4 uMVMatrix;
uniform mat4 uPMatrix; varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
</script> <script type="text/javascript"> var gl;
//初始化WEBGL
function initGL(canvas) {
try {
//获取WEBGL上下文
gl = canvas.getContext("experimental-webgl");
//gl这个上下文中存放了一些属性(canvas的宽度、长度和其他相关属性数据)
//设置我的视口的宽度和高度
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
//如果获取失败
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
} //获取我的着色器对象
function getShader(gl, id) {
//根据id获取着色器源程序代码
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
} var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
} var shader;
//1.根据着色器的类型创建相应的着色器对象
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
} //2.向着色器对象中指定相应的GLSL ES源代码(以字符串的形式传递进去)
gl.shaderSource(shader, str);
//3.开始编译着色器(编译成为二进制的可执行文件)
gl.compileShader(shader); //检查下着色器的状态(是否编译成功)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
} return shader;
} //一个着色器对象必须包含一个顶点着色器和一个片元着色器
var shaderProgram; //初始化着色器
function initShaders() {
//获取我的顶点着色器和片元着色器
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs"); //每一个program中可以存放一个顶点着色器和一个片元着色器
//4.创建我的程序对象
shaderProgram = gl.createProgram();
//5.为程序对象分配着色器对象
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader); //6.链接程序对象
/**
* 1.可以保证顶点着色器和片元着色器同名并且是同类型的
* 2.attribute,uniform和varying变量个数不超过着色器的上限
*/
gl.linkProgram(shaderProgram);
//检测是否连接成功
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
//7.告诉WEBGL要使用的程序对象
gl.useProgram(shaderProgram); //指定一个新的属性;gl.enableVertexAttribArray,我们使用它来告诉WebGL我们会用一个数组来为属性赋值
//顶点的位置信息
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); //获取我的顶点着色器中的attribute颜色变量
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); //从program中取得另外的两个属性值(模型视图投影矩阵)
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
} //定义了我的模型视图矩阵和投影矩阵
var mvMatrix;
var pMatrix; //在这里实现我的矩阵的进栈和出栈操作
var mvMatrixStack = [];
function myPushMatrix() {
var copy = new okMat4();
mvMatrix.clone(copy);
mvMatrixStack.push(copy);
} function myPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
} //把我们新设置的模型视图投影矩阵传给顶点着色器中的uniform变量
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray());
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray());
} //定义我的三角形和矩形缓冲区顶点位置
var triangleVertexPositionBuffer;
var squareVertexPositionBuffer;
//定义我的三角形和矩形缓冲区的顶点颜色
var triangleVertexColorBuffer;
var squareVertexColorBuffer; //缓冲区的初始化
function initBuffers() {
//1.新建三角形顶点缓冲区对象
triangleVertexPositionBuffer = gl.createBuffer();
//2.绑定目标对象到缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
//初始化我的顶点数组
var vertices = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
];
//3.缓冲区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); //计算顶点数组的大小和顶点个数
triangleVertexPositionBuffer.itemSize = 3;
triangleVertexPositionBuffer.numItems = 3; //1.创建我的颜色缓冲区
triangleVertexColorBuffer = gl.createBuffer();
//2.绑定我的颜色缓冲区到目标对象
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
//初始化我的颜色数组(对每一个顶点指定相应的颜色)
var colors = [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
];
//3.向缓冲区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
//计算三角形顶点颜色数组的大小和顶点个数
triangleVertexColorBuffer.itemSize = 4;
triangleVertexColorBuffer.numItems = 3; //1.新建矩形顶点缓冲区对象
squareVertexPositionBuffer = gl.createBuffer();
//2.绑定目标对象到缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
//设置我的正方形顶点数组
vertices = [
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0
];
//3.向缓冲区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
//计算矩形顶点数组每一项数据的大小,和顶点个数(有四个不同的顶点位置,每个顶点由3个数字组成)
squareVertexPositionBuffer.itemSize = 3;
squareVertexPositionBuffer.numItems = 4; //1.创建我的矩形顶点颜色缓冲区
squareVertexColorBuffer = gl.createBuffer();
//2.绑定目标对象到缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
//定义我的矩形的颜色数组
colors = [];
//对于矩形的四个顶点赋予相同的颜色
for (var i=0; i<4; i++){
/** colors的颜色数组如下
* 0.5, 0.5, 1.0, 1.0,
* 0.5, 0.5, 1.0, 1.0,
* 0.5, 0.5, 1.0, 1.0,
* 0.5, 0.5, 1.0, 1.0,
* @type {Array.<number>}
*/
colors = colors.concat([0.5, 0.5, 1.0, 1.0]);
}
//3.向缓冲区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
//计算我的正方形的顶点数组
squareVertexColorBuffer.itemSize = 4;
squareVertexColorBuffer.numItems = 4;
} //定义我的三角形和我的矩形的初始旋转角度
var rTri = 0;
var rSquare = 0; //绘制我的场景(三角形和矩形)
function drawScene() {
//设置视口大小
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
//清空颜色缓存和深度缓存
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //建立一个透视投影(视场角,视口比例,最近,最远距离)
pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0); //新建一个模型视图矩阵
mvMatrix = new okMat4();
//保存矩阵的初始状态
myPushMatrix(); //设置我的模型视图矩阵为平移矩阵
//mvMatrix = okMat4Trans(-1.5, 0.0, -7.0);
mvMatrix.translate(OAK.SPACE_WORLD, -1.5, 0.0, -7.0, true);
//三角形绕着Y轴旋转(本地坐标系旋转)
mvMatrix.rotY(OAK.SPACE_LOCAL, rTri, true); //1.绑定三角形顶点数据到缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); //2.绑定三角形颜色信息到缓冲区对象,并且传递给顶点着色器
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0); //告诉WEBGL当前使用的模型视图投影矩阵
setMatrixUniforms();
//开始绘制三角形(从第0个位置开始,绘制numItems个顶点)
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
//绘制完毕后再次恢复我的模型视图矩阵
myPopMatrix(); //再次保存我的模型视图矩阵
myPushMatrix();
//开始绘制矩形
//mvMatrix = okMat4Trans(1.5, 0.0, -7.0);
mvMatrix.translate(OAK.SPACE_WORLD, 1.5, 0.0, -7.0, true);
//让我的矩形绕着X轴旋转
mvMatrix.rotX(OAK.SPACE_LOCAL, rSquare, true); //绑定四边形的顶点信息
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); //开始传递颜色数据
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, squareVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); //绘制完毕后,恢复我的模型视图矩阵的初始状态
myPopMatrix();
} //这里是我的主函数
function webGLStart() {
//获取canvas元素
var canvas = document.getElementById("lesson01-canvas"); //初始化WEBGL上下文信息
initGL(canvas); //初始化着色器
initShaders(); //出事阿虎缓冲区
initBuffers(); //指定清空画布的颜色,开启隐藏面消除的功能
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST); //开始绘制我的场景
//drawScene();
//开始使用动画效果来绘制我的图形
tick();
} //实现我的动画绘制函数
function tick() {
//重复调用tick函数
okRequestAnimationFrame(tick); //开始绘制场景
drawScene(); //改变我的三角形和我的矩阵的旋转角度
animate();
} //开始不断修改我的旋转角度
var lastTime = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime; //三角形 90/s, 矩形 75/s
rTri += (90 * elapsed) / 1000.0;
rSquare += (75 * elapsed) / 1000.0;
}
lastTime = timeNow;
} </script> </head> <body onload="webGLStart();">
<canvas id="lesson01-canvas" style="border: none;" width="500" height="500"></canvas>
</body> </html>
WEBGL学习【三】颜色选择的更多相关文章
- webgl学习笔记三-平移旋转缩放
		写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ... 
- WebGL学习(1) - 三角形
		原文地址:WebGL学习(1) - 三角形 还记得第一次看到canvas的粒子特效的时候,真的把我给惊艳到了,原来在浏览器也能做出这么棒的效果.结合<HTML5 Canvas核心技术>和网 ... 
- webgl学习笔记五-纹理
		写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ... 
- SCARA——OpenGL入门学习三
		OpenGL入门学习[三] 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用 ... 
- Java语法基础(三)----选择结构的if语句、switch语句
		[前言] 流程控制语句: 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过 ... 
- WebGL学习(2) - 3D场景
		原文地址:WebGL学习(2) - 3D场景 经过前面WebGL学习(1) - 三角形的学习,我们已经掌握了webGL的基础知识,也已经能够画出最基本的图形,比如点,线,三角形,矩形等.有了2D绘图的 ... 
- WebGL学习之纹理贴图
		为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ... 
- SVG 学习<三>渐变
		目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ... 
- webgl学习笔记四-动画
		写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ... 
- webgl学习笔记二-绘图多点
		写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ... 
随机推荐
- [bzoj3389][Usaco2004Dec]Cleaning Shifts安排值班_最短路
			Cleaning Shifts bzoj-3389 Usaco-2004Dec 题目大意:每天有n个时间段,每个时间段都必须安排一个奶牛值班.有m个奶牛,每个奶牛只有一个空闲时间s[i]~e[i],求 ... 
- POJ 2373
			原本一道挺简单的DP题,思路有了,运用单调队列,但在写单调队列时写挫了... 这道题只需要计算偶数位置的即可,这是显而易见的,我有注意过这情况,写的时候却没在意...--! 加入队列的元素应该当前no ... 
- POJ 3608
			1.计算P上y坐标值最小的顶点(称为 yminP )和Q上y坐标值最大的顶点(称为 ymaxQ). 2.为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于 ... 
- Java使用JAVE获取MP4播放时长
- impdp时卡住,DW等待library cache lock
			同事反映impdp时在SCHEMA_REPORT/TYPE/TYPE_SPEC步骤卡住,1个多小时后也没有响应, 查下v$session: select program,sid, event,bloc ... 
- CentOS 7 安装Nginx做反向代理
			题记 须要使用nginx的反向代理功能,測试环境为centos+NGINX 1.8.0. 跳过一些繁琐的问题,直接记录核心 步骤 (1)centos 安装在VM中.因此须要注意网络连接问题 (2)安装 ... 
- objective-c 中数据类型之四 字典(NSDictionary)
			// 1. 字典初始化.赋值方式1 NSMutableDictionary *m_dictionary = [[NSMutableDictionary alloc] initWithCapacity: ... 
- Android笔记之网络状态推断
			1.首先当然得在 manifest 中加入检查网络状态的权限: <uses-permission android:name="android.permission.ACCESS_NET ... 
- c20---指向函数的指针
			// // main.c // 指向函数的指针 #include <stdio.h> void test() { printf("哥被执行了\n"); } int ge ... 
- 如何用jQuery实现div随鼠标移动而移动?(详解)----2017-05-12
			重点是弄清楚如何获取鼠标现位置与移动后位置,div现在位置与移动后位置: 用jQuery实现div随鼠标移动而移动,不是鼠标自身的位置!!而是div相对于之前位置的移动 代码如下:(注意看绿色部分的解 ... 
