博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值
阅读量:4669 次
发布时间:2019-06-09

本文共 7004 字,大约阅读时间需要 23 分钟。

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

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

学习准备:

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

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

  (可以跟着搞起来的实例教程)  http://www.cnblogs.com/bsman/p/6128447.html

(看了这篇才找到答案的)   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" %>
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

 

转载于:https://www.cnblogs.com/GuliGugaLiz/p/8578199.html

你可能感兴趣的文章
UE4 打包C++项目到win32平台报错 could not find mspdbcore.dll
查看>>
sed系列:行或者模式匹配删除特定行
查看>>
python常见面试题(三)
查看>>
回文日期(NOIP2016 普及组第二题)
查看>>
[jQuery]回到顶部
查看>>
用Github做一个静态网页(GithubPages)
查看>>
Win7下修改Hosts文件
查看>>
Linq to sql并发与事务
查看>>
2017-06-27
查看>>
Convert DataTable to Html Table
查看>>
JavaEE复习三
查看>>
全局ajax事件
查看>>
javascript二维数组
查看>>
JavaScript 字符串属性和方法
查看>>
opencv新手注意
查看>>
Source InSight context 窗口丢失的解决办法
查看>>
cut point and bridge总结
查看>>
(5)Oracle基础--约束
查看>>
vmware vcenter orchestrator configuration提示“用户名密码错误或登录失败超过次数被锁定”...
查看>>
【Nginx】磁盘文件写入飞地发
查看>>