-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] WebGL

, 18 2017 . 20:09 +


OpenGlobus, Javascript WebGL.

2D
3D ( W,S,A,D,Q,E )



. WebGL , . , . , , . , , .

, glsl , , . WebGL , !



. , , .

. (. 1):

(. 1)
, , . , (. 2):


(. 2)

, , , (. 3).

(. 3)

- (. 4):


(. 4)

, . GL_LINE_STRING, , ( ) (. 5), (. 2), .

(. 5)

, . , (. 6).
(. 6)


(. 7):

(. 7)

. , . , , , , , . , , , (. 8).

(. 8)

, , , , , .. , ( -1, 1 -2, 2 ), : , .

.. WebGL , , , vertexAttribPointer , . , (. 9):


( 9)

; 8 ( vec2) .. 24 ; Xi, Yi , B, C; Xp = Xa Xb, Yp = Y Yb, Xn = Xc Xb, Yn = Xc Xb .. . (, ) , current , previous next . 32 , (current) (previous) , 64 (next) . .. (previous) , . , 1 -1 , 2 -2 , .

:

var vb = this._verticesBuffer;
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
gl.vertexAttribPointer(sha.prev._pName, vb.itemSize, gl.FLOAT, false, 8, 0);
gl.vertexAttribPointer(sha.current._pName, vb.itemSize, gl.FLOAT, false, 8, 32);
gl.vertexAttribPointer(sha.next._pName, vb.itemSize, gl.FLOAT, false, 8, 64);

gl.bindBuffer(gl.ARRAY_BUFFER, this._ordersBuffer);
gl.vertexAttribPointer(sha.order._pName, this._ordersBuffer.itemSize, gl.FLOAT, false, 4, 0);

, , pathArr outVertices , outOrders outIndexes :


Polyline2d.createLineData = function (pathArr, outVertices, outOrders, outIndexes) {
    var index = 0;

  outIndexes.push(0, 0);

  for ( var j = 0; j < pathArr.length; j++ ) {
     path = pathArr[j];
  var startIndex = index;
  var last = [path[0][0] + path[0][0] - path[1][0], path[0][1] + path[0][1] - path[1][1]];
  outVertices.push(last[0], last[1], last[0], last[1], last[0], last[1], last[0], last[1]);
  outOrders.push(1, -1, 2, -2);

        //     4 
  for ( var i = 0; i < path.length; i++ ) {
     var cur = path[i];
  outVertices.push(cur[0], cur[1], cur[0], cur[1], cur[0], cur[1], cur[0], cur[1]);
  outOrders.push(1, -1, 2, -2);
  outIndexes.push(index++, index++, index++, index++);
  }

  var first = [path[path.length - 1][0] + path[path.length - 1][0] - path[path.length - 2][0],  path[path.length - 1][1] + path[path.length - 1][1] - path[path.length - 2][1]];
  outVertices.push(first[0], first[1], first[0], first[1], first[0], first[1], first[0], first[1]);
  outOrders.push(1, -1, 2, -2);
  outIndexes.push(index - 1, index - 1, index - 1, index - 1);

  if ( j < pathArr.length - 1 ) {
      index += 8;
  outIndexes.push(index, index);
  }
  }
};

:

var path = [[[-100, -50], [1, 2], [200, 15]]];
var vertices = [],
   orders = [],
   indexes = [];
Polyline2d.createLineData(path, vertices, orders, indexes);

:

vertices: [-201, -102, -201, -102, -201, -102, -201, -102, -100, -50, -100, -50, -100, -50, -100, -50, 1, 2, 1, 2, 1, 2, 1, 2, 200, 15, 200, 15, 200, 15, 200, 15, 399, 28, 399, 28, 399, 28, 399, 28]

orders: [1, -1, 2, -2, 1, -1, 2, -2, 1, -1, 2, -2, 1, -1, 2, -2, 1, -1, 2, -2]

indexes: [0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11]

:

attribute vec2 prev; // 
attribute vec2 current; // 
attribute vec2 next; // 
attribute float order; //
 
uniform float thickness; //
uniform vec2 viewport; // 

//   
vec2 proj(vec2 coordinates){
    return coordinates / viewport;
}
 
void main() {
    vec2 _next = next;
 vec2 _prev = prev;

    //   ,    
 if( prev == current ) {
     if( next == current ){
     _next = current + vec2(1.0, 0.0);
 _prev = current - next;
 } else {
     _prev = current + normalize(current - next);
 }
  }
 if( next == current ) {
    _next = current + normalize(current - _prev);
 }
 
 vec2 sNext = _next,
 sCurrent = current,
 sPrev = _prev;

    //   ,     
 vec2 dirNext = normalize(sNext - sCurrent);
 vec2 dirPrev = normalize(sPrev - sCurrent);
 float dotNP = dot(dirNext, dirPrev);
 
    //  
 vec2 normalNext = normalize(vec2(-dirNext.y, dirNext.x));
 vec2 normalPrev = normalize(vec2(dirPrev.y, -dirPrev.x));
 float d = thickness * 0.5 * sign(order);
 
 vec2 m; //m -  ,        
 if( dotNP >= 0.99991 ) {
     m = sCurrent - normalPrev * d;
 } else {
     vec2 dir = normalPrev + normalNext;
  
        //        (. 2)
 m = sCurrent + dir * d / (dirNext.x * dir.y - dirNext.y * dir.x);
 
        //     
 if( dotNP > 0.5 && dot(dirNext + dirPrev, m - sCurrent) < 0.0 ) {
     float occw = order * sign(dirNext.x * dirPrev.y - dirNext.y * dirPrev.x);
            //      LINE_STRING
 if( occw == -1.0 ) {
     m = sCurrent + normalPrev * d;
 } else if ( occw == 1.0 ) {
     m = sCurrent + normalNext * d;
 } else if ( occw == -2.0 ) {
     m = sCurrent + normalNext * d;
 } else if ( occw == 2.0 ) {
     m = sCurrent + normalPrev * d;
  }
         
        // ""  ,        
  } else if ( distance(sCurrent, m) > min(distance(sCurrent, sNext), distance(sCurrent, sPrev)) ) {
      m = sCurrent + normalNext * d;
 }
  }
 m = proj(m);
 gl_Position = vec4(m.x, m.y, 0.0, 1.0);
}



, , .

, , . , colors, . - , , ( ) ( ), , , , . (antialiasing), , ( ) .
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331164/

:  

: [1] []
 

:
: 

: ( )

:

  URL