最近分配到一个看起来非常简单的优化需求、通过地图上设置工具来改变地图上显示的点的大小和透明度。无非过程就是从控件面板获取到用户设置的值保存到数据库中、然后地图上画点的时候取出设置的值渲染出点即可。前端绘制图形无非canvas、这个方面我之前也是不怎么涉及的部分、所以趁这次分配的任务比较轻时间相对宽裕的情况下、可谓是好好学了一把WebGL的内容。通过一个星期的查找学习、总算有了比较清晰的理解、足以好好理解代码了。

俗话说、工欲善其事必先利其器、我这次可是深刻体会了一把。一开始觉得好像蛮容易的、后来怎么也搞不到一起才静下心来认认真真看了webGL的内容、比较不好理解、反正我对着代码翻来覆去看了四五六七遍以上吧、才终于理解了代码执行的逻辑顺序。

学习准备:

WebGL教程:  http://www.yanhuangxueyuan.com/WebGL_course.html   (推荐、跟着里面说明的方法来学习理解)

W3C关于WebGL的基础学习 (动手前最好看明白的基础理论学习) https://www.w3cschool.cn/webgl/157h1oh3.html

WebGL入门教程(一)-初识webgl  (可以跟着搞起来的实例教程)  http://www.cnblogs.com/bsman/p/6128447.html

从OpenGL传颜色数值到Shader,改变绘图颜色(看了这篇才找到答案的)   http://blog.csdn.net/huutu/article/details/21460835

WebGL基础(辅助理解)  https://www.cnblogs.com/mazhenyu/p/3804518.html

开始解题:

1.大体的思路如下图、代码有省略

其实图上看明白了题已经解了、屡一下思路、WebGL先要声明点着色器和片着色器、然后放在program上建立起来、在建立好program后我们定义一个变量gl.aPointSize,将点着色器的一个属性值a_pointSize赋值给这个变量gl.aPointSize,然后我们根据实际项目需求通过控制这个gl.aPointSize进而改变点着色器中内部变量gl_PointSize。就这么简单,主要是看明白webGL每一个语句的用法,就容易做了。

2.代码参考

①在main.aspx中声明点着色器

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Ext5.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="F5WS.Web" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> <script type="text/javascript">var tinyItems = <%= ViewData["TinyItems"] %></script>
<script id="vshader" type="x-shader/x-vertex">
uniform mat4 u_matrix;
attribute vec4 a_vertex;
attribute float a_pointSize;
attribute vec4 a_color;
varying vec4 v_color; void main() {
// Set the size of the point
// a_pointSize; gl_PointSize = a_pointSize; // multiply each vertex by a matrix.
gl_Position = u_matrix * a_vertex; // pass the color to the fragment shader
v_color = a_color;
}
</script>
<!-- fragment shader --> <!-- vec4 color1 = vec4(v_color[], v_color[], v_color[], 0.6);调整透明度在这里 -->
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
uniform sampler2D uSampler;
void main() { float border = 0.1;
float radius = 0.5;
vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
// 最后一个参数为 透明度设定
vec4 color1 = vec4(v_color[], v_color[], v_color[], v_color[]); vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);
float dist = radius - sqrt(m.x * m.x + m.y * m.y); float t = 0.0;
if (dist > border)
t = 1.0;
else if (dist > 0.0)
t = dist / border; // float centerDist = length(gl_PointCoord - 0.5);
// works for overlapping circles if blending is enabled gl_FragColor = mix(color0, color1, t); } </script> </script>
</asp:Content>

main.aspx

②在CanvasOverlayGL.js中使用、截取了WebGL部分的代码、方便核对自己的代码理解

    setWebGL: function () {
var me = this;
var gl = this._canvas.getContext('experimental-webgl', { antialias: true });
if (!gl) {
me._usingGL = false;
return;
} me._gl = gl; this._pixelsToWebGLMatrix = new Float32Array(16);
this._mapMatrix = new Float32Array(16); // -- WebGl setup
if (!gl) return;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
if (!document.getElementById('vshader')) return;
gl.shaderSource(vertexShader, document.getElementById('vshader').text);
gl.compileShader(vertexShader); var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
if (!document.getElementById('fshader')) return;
gl.shaderSource(fragmentShader, document.getElementById('fshader').text);
gl.compileShader(fragmentShader); // link shaders to create our program
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // look up the locations for the inputs to our shaders.
this._u_matLoc = gl.getUniformLocation(program, "u_matrix");
this._colorLoc = gl.getAttribLocation(program, "a_color");
this._vertLoc = gl.getAttribLocation(program, "a_vertex");
gl.aPointSize = gl.getAttribLocation(program, "a_pointSize"); // Set the matrix to some that makes 1 unit 1 pixel.
this._pixelsToWebGLMatrix.set([2 / this._canvas.width, 0, 0, 0, 0, -2 / this._canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
gl.viewport(0, 0, this._canvas.width, this._canvas.height); gl.uniformMatrix4fv(this._u_matLoc, false, this._pixelsToWebGLMatrix);
},
loadData: function (data, total) { var me = this;
var gl = me._gl;
var usingGL = me._usingGL;
var verts = data; //你自己要渲染的数据 this._size = verts[2]; //我这里的verts[2] = -50
this._cSize = verts[7]; // 我这里的verts[7] = 5.0 this._numPoints = total;
if (usingGL) {
if (!this._buffer) {
var vertBuffer = gl.createBuffer();
this._buffer = vertBuffer;
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.enableVertexAttribArray(this._vertLoc);
gl.enableVertexAttribArray(this._colorLoc);
} var vertArray = new Float32Array(verts); var fsize = vertArray.BYTES_PER_ELEMENT; gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW); gl.vertexAttribPointer(0, 3, gl.FLOAT, false, fsize * 7, 0); // -- offset for color buffer
gl.vertexAttribPointer(this._colorLoc, 4, gl.FLOAT, false, fsize * 7, fsize * 3); } this.redraw();
},
drawingOnCanvas: function () {
if (this._gl == null) return;
var gl = this._gl;
gl.clear(gl.COLOR_BUFFER_BIT);
this._pixelsToWebGLMatrix.set([2 / this._canvas.width, 0, 0, 0, 0, -2 / this._canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]); //debugger;
var pointSize = 78271.5170 / Math.pow(2, this._map.getZoom() - 1);
var size = this._size;
if (size < 0.0) {
size = -size / pointSize;
if (size < 7.0) {
//size = 7.0;
size = this._cSize + 2 ; //我这里 this._cSize=5,我想设定点大小为7,所以+2了
}
} // console.log(size);
gl.vertexAttrib1f(gl.aPointSize, size); //将size传给点着色器的gl.aPointSize,从而改变到点的大小了 // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
this._mapMatrix.set(this._pixelsToWebGLMatrix);
//debugger;
var bounds = this._map.getBounds();
var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest()); var newLatlng = this.offsetFn(topLeft.lat, topLeft.lng); var offset = this.LatLongToPixelXY(topLeft.lat - newLatlng.lat + topLeft.lat, topLeft.lng - newLatlng.lng + topLeft.lng); this._offset.x = offset.x;
this._offset.y = offset.y;
this._offset.topLeft = topLeft; // -- Scale to current zoom
var scale = Math.pow(2, this._map.getZoom());
this.scaleMatrix(this._mapMatrix, scale, scale); this.translateMatrix(this._mapMatrix, -offset.x, -offset.y); // -- attach matrix value to 'mapMatrix' uniform in shader
gl.uniformMatrix4fv(this._u_matLoc, false, this._mapMatrix);
//debugger;
gl.drawArrays(gl.POINTS, 0, this._numPoints);
},
LatLongToPixelXY: function (latitude, longitude) {
var pi_180 = Math.PI / 180.0;
var pi_4 = Math.PI * 4;
var sinLatitude = Math.sin(latitude * pi_180);
var pixelY = (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (pi_4)) * 256;
var pixelX = ((longitude + 180) / 360) * 256; var pixel = { x: pixelX, y: pixelY }; return pixel;
},
translateMatrix: function (matrix, tx, ty) {
// translation is in last column of matrix
matrix[12] += matrix[0] * tx + matrix[4] * ty;
matrix[13] += matrix[1] * tx + matrix[5] * ty;
matrix[14] += matrix[2] * tx + matrix[6] * ty;
matrix[15] += matrix[3] * tx + matrix[7] * ty;
},
scaleMatrix: function (matrix, scaleX, scaleY) {
// scaling x and y, which is just scaling first two columns of matrix
matrix[0] *= scaleX;
matrix[1] *= scaleX;
matrix[2] *= scaleX;
matrix[3] *= scaleX; matrix[4] *= scaleY;
matrix[5] *= scaleY;
matrix[6] *= scaleY;
matrix[7] *= scaleY;
},

CanvasOverlayGL.js

WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值的更多相关文章

  1. 内置变量WEBGL

    gl_FragCoord是片元着色器中的只读变量,它保存了片元相对窗口的坐标位置:x, y, z, 1/w.这个值是顶点处理产生片元后固定功能内插图元的结果.组件z是用于表示片元深度的深度值. gl_ ...

  2. awk内置变量 awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

    ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 设置输入域分隔符,等价于命令行 ...

  3. 使用外部容器运行spring-boot项目:不使用spring-boot内置容器让spring-boot项目运行在外部tomcat容器中

    前言:本项目基于maven构建 spring-boot项目可以快速构建web应用,其内置的tomcat容器也十分方便我们的测试运行: spring-boot项目需要部署在外部容器中的时候,spring ...

  4. WebGL 创建和初始化着色器过程

    1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...

  5. WebGL简易教程(二):向着色器传输数据

    目录 1. 概述 2. 示例:绘制一个点(改进版) 1) attribute变量 2) uniform变量 3) varying变量 3. 结果 4. 参考 1. 概述 在上一篇教程<WebGL ...

  6. WebGL中的OpenGL着色器语言

    在webgl中,调用了OpenGL-ES-2.0的API,而在OpenGL-ES专为嵌入式设备设计,其和其它设备一样,都是使用GLSL(GL Shading Language)来编写片段程序并执行于G ...

  7. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数

    Python第七天   函数  函数参数   函数里的变量   函数返回值  多类型传值     函数递归调用   匿名函数   内置函数 目录 Pycharm使用技巧(转载) Python第一天   ...

  8. WebGL 着色器语言(GLSL ES)

    1.类型转换内置函数 转换/函数/描述 转换为整形数/int(float)/将浮点数的小数部分删去,转换为整形数(比如,将3.14转换为3) 转换为整形数/intl(bool)/true被转换为1,f ...

  9. WebGL编程指南案例解析之多数据存储于一个缓冲区以及着色器通信

    //顶点着色器往片元着色器传值 //多个参数值存于一个缓冲对象中 var vShader = ` attribute vec4 a_Position; attribute float a_PointS ...

随机推荐

  1. ELK学习笔记(五)简单搜索和DSL查询

    检索文档 现在我们有一些数据存储在Elasticsearch中,我们可以开始处理这个应用程序的业务需求. 这在Elasticsearch中很容易.我们只需执行HTTP GET请求并指定文档的地址--索 ...

  2. 兄弟连学Python-Mysql的基础知识

    ##MySQL数据库基础知识 1.数据库系统(database system) 数据库系统是计算机系统中一种专门管理数组资源的系统,数据库存储的是一组或多组经过处理后的数据,管理这个数据库的软件成为数 ...

  3. redis配置文件详解及实现主从同步切换

    原理:redis复制是怎么进行工作 如果设置了一个slave,不管是在第一次链接还是重新链接master的时候,slave会发送一个同步命令 然后master开始后台保存,收集所有对修改数据的命令.当 ...

  4. Python类中的self到底是干啥的

    Python类中的self到底是干啥的 Python编写类的时候,每个函数参数第一个参数都是self,一开始我不管它到底是干嘛的,只知道必须要写上.后来对Python渐渐熟悉了一点,再回头看self的 ...

  5. shell死循环脚本示例

    1.设计一个脚本,监控远程的一台机器(假设ip为192.168.0.28)的存活状态,当发现宕机时发一封邮件给你自己. 提示:1. 你可以使用ping命令   ping -c10 www.baidu. ...

  6. 火狐浏览器中如何删除保存的cookie

    大致分为三步即可: 打开浏览器并查看图示,按照图示操作即可完成:

  7. 外部 Storage Provider - 每天5分钟玩转 Docker 容器技术(149)

    如果 Kubernetes 部署在诸如 AWS.GCE.Azure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子: 要在 Pod 中 ...

  8. 【IntelliJ IDEA】使用idea解决新建jsp文件而找不到jsp文件模版的新建选项

    使用idea解决新建jsp文件而找不到jsp文件模版的新建选项,这样每次创建一个新的jsp文件岂不是很耗时间? 解决办法: 就是要让idea知道你需要在这个目录下创建jsp文件 左上角,file中点击 ...

  9. 【Alpha版本】冲刺阶段 - Day5 - 破浪

    今日进展 袁逸灏:解决音乐播放问题以及跳转问题.(5h) 刘伟康:大致检查了测试规范,参考了其他 alpha 阶段的博客.(1h) 刘先润:解决了敌车与障碍物溢出边界的代码问题,给用户车辆增加了火焰喷 ...

  10. 201621123040《Java程序设计》第十周学习总结

    1.本周学习总结 2.书面作业 2.1常用异常 2.1.1自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避免? 算术异常ArithmeticException(除数为0的情况) 类 ...