From 91a9e02bff0397ec9b1f55fdf61cef72eb0d8a0f Mon Sep 17 00:00:00 2001 From: hwc487 Date: Tue, 8 May 2012 15:53:35 -0700 Subject: Radial gradients to match CSS --- assets/shaders/radialGradient.vert.glsl | 4 ++- js/lib/geom/circle.js | 3 ++ js/lib/geom/rectangle.js | 13 ++----- js/lib/geom/shape-primitive.js | 27 ++++++++++++++ js/lib/rdge/materials/material.js | 4 +++ js/lib/rdge/materials/radial-gradient-material.js | 43 ++++++++++++++++++++++- 6 files changed, 81 insertions(+), 13 deletions(-) diff --git a/assets/shaders/radialGradient.vert.glsl b/assets/shaders/radialGradient.vert.glsl index c3e1b50a..7994ac12 100644 --- a/assets/shaders/radialGradient.vert.glsl +++ b/assets/shaders/radialGradient.vert.glsl @@ -18,11 +18,13 @@ attribute vec2 texcoord; // matrix uniforms uniform mat4 u_mvMatrix; uniform mat4 u_projMatrix; +uniform mat3 u_texTransform; varying vec2 v_uv; void main(void) { gl_Position = u_projMatrix * u_mvMatrix * vec4(vert,1.0) ; - v_uv = texcoord; + vec3 tmp = u_texTransform * vec3( texcoord, 1.0); + v_uv = tmp.xy; } \ No newline at end of file diff --git a/js/lib/geom/circle.js b/js/lib/geom/circle.js index 0f1f49a9..afeed449 100755 --- a/js/lib/geom/circle.js +++ b/js/lib/geom/circle.js @@ -279,6 +279,7 @@ var Circle = function GLCircle() { if (fillPrim) { fillMaterial = this.makeFillMaterial(); + fillMaterial.fitToPrimitive( fillPrim ); this._primArray.push( fillPrim ); this._materialNodeArray.push( fillMaterial.getMaterialNode() ); @@ -286,6 +287,7 @@ var Circle = function GLCircle() { if (strokePrim0) { strokeMaterial0 = this.makeStrokeMaterial(); + strokeMaterial0.fitToPrimitive( strokePrim0 ); this._primArray.push( strokePrim0 ); this._materialNodeArray.push( strokeMaterial0.getMaterialNode() ); @@ -293,6 +295,7 @@ var Circle = function GLCircle() { if (strokePrim1) { strokeMaterial2 = this.makeStrokeMaterial(); + strokeMaterial2.fitToPrimitive( strokePrim1 ); this._primArray.push( strokePrim1 ); this._materialNodeArray.push( strokeMaterial2.getMaterialNode() ); diff --git a/js/lib/geom/rectangle.js b/js/lib/geom/rectangle.js index 490a9a6f..296ed024 100755 --- a/js/lib/geom/rectangle.js +++ b/js/lib/geom/rectangle.js @@ -57,13 +57,10 @@ var Rectangle = function GLRectangle() { this._strokeStyle = strokeStyle; this._matrix = Matrix.I(4); - //this._matrix[12] = xoffset; - //this._matrix[13] = yoffset; } // the overall radius includes the fill and the stroke. separate the two based onthe stroke width // this._fillRad = this._radius - this._strokeWidth; - // var err = 0.05; var err = 0; this._fillWidth = this._width - this._strokeWidth + err; this._fillHeight = this._height - this._strokeWidth + err; @@ -116,18 +113,10 @@ var Rectangle = function GLRectangle() { return this._strokeColor; }; - //this.setStrokeColor = function(c) { - // this._strokeColor = c; - // }; - this.getFillColor = function() { return this._fillColor; }; - //this.setFillColor = function(c) { - // this._fillColor = c.slice(0); - // }; - this.getTLRadius = function() { return this._tlRadius; }; @@ -324,6 +313,7 @@ var Rectangle = function GLRectangle() { // stroke var strokeMaterial = this.makeStrokeMaterial(); var strokePrim = this.createStroke([x,y], 2*xFill, 2*yFill, strokeSize, tlRadius, blRadius, brRadius, trRadius, strokeMaterial); + strokeMaterial.fitToPrimitive( strokePrim ); this._primArray.push( strokePrim ); this._materialNodeArray.push( strokeMaterial.getMaterialNode() ); @@ -337,6 +327,7 @@ var Rectangle = function GLRectangle() { var fillMaterial = this.makeFillMaterial(); //console.log( "fillMaterial: " + fillMaterial.getName() ); var fillPrim = this.createFill([x,y], 2*xFill, 2*yFill, tlRadius, blRadius, brRadius, trRadius, fillMaterial); + fillMaterial.fitToPrimitive( fillPrim ); this._primArray.push( fillPrim ); this._materialNodeArray.push( fillMaterial.getMaterialNode() ); diff --git a/js/lib/geom/shape-primitive.js b/js/lib/geom/shape-primitive.js index 97873d32..9864a8e9 100644 --- a/js/lib/geom/shape-primitive.js +++ b/js/lib/geom/shape-primitive.js @@ -49,6 +49,33 @@ ShapePrimitive.create = function(coords, normals, uvs, indices, primType, ver return prim; }; +ShapePrimitive.getBounds = function( prim ) +{ + var verts = prim.bufferStreams[0]; + var nVerts = verts.length; + var xMin = verts[0], xMax = verts[0], + yMin = verts[1], yMax = verts[1], + zMin = verts[2], zMax = verts[2]; + + for (var index=3; index xMax) xMax = verts[index]; + + index++; + if (verts[index] < yMin) yMin = verts[index]; + else if (verts[index] > yMax) yMax = verts[index]; + + index++; + if (verts[index] < zMin) zMin = verts[index]; + else if (verts[index] > zMax) zMax = verts[index]; + + index++; + } + + return [xMin, yMin, zMin, xMax, yMax, zMax]; +}; + if (typeof exports === "object") { exports.ShapePrimitive = ShapePrimitive; } \ No newline at end of file diff --git a/js/lib/rdge/materials/material.js b/js/lib/rdge/materials/material.js index 276c7687..b96768b3 100755 --- a/js/lib/rdge/materials/material.js +++ b/js/lib/rdge/materials/material.js @@ -228,6 +228,10 @@ var Material = function GLMaterial( world ) { // animated materials should implement the update method }; + this.fitToPrimitive = function( prim ) { + // some materials need to preserve an aspect ratio - or someting else. + }; + this.registerTexture = function( texture ) { // the world needs to know about the texture map var world = this.getWorld(); diff --git a/js/lib/rdge/materials/radial-gradient-material.js b/js/lib/rdge/materials/radial-gradient-material.js index dd40d31d..a671ee42 100755 --- a/js/lib/rdge/materials/radial-gradient-material.js +++ b/js/lib/rdge/materials/radial-gradient-material.js @@ -6,6 +6,7 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot var MaterialParser = require("js/lib/rdge/materials/material-parser").MaterialParser; var Material = require("js/lib/rdge/materials/material").Material; +var ShapePrimitive = require("js/lib/geom/shape-primitive").ShapePrimitive; var RadialGradientMaterial = function RadialGradientMaterial() { /////////////////////////////////////////////////////////////////////// @@ -24,6 +25,9 @@ var RadialGradientMaterial = function RadialGradientMaterial() { this._colorStop4 = 1.0; // this._colorCount = 4; + var s = Math.sqrt( 2.0 ); + this._textureTransform = [s,0,0, 0,s,0, 0,0,1]; + /////////////////////////////////////////////////////////////////////// // Property Accessors /////////////////////////////////////////////////////////////////////// @@ -231,9 +235,45 @@ var RadialGradientMaterial = function RadialGradientMaterial() { this._shader['default'].u_colorStop3.set([s]); s = this.getColorStop4(); this._shader['default'].u_colorStop4.set([s]); + + this._shader['default'].u_texTransform.set( this._textureTransform ); } }; + this.fitToPrimitive = function( prim ) + { + var bounds = ShapePrimitive.getBounds( prim ); + if (bounds) + { + var dx = Math.abs( bounds[3] - bounds[0] ), + dy = Math.abs( bounds[4] - bounds[1] ); + if (dy == 0) dy = 1.0; + if (dx == 0) dx = 1.0; + var xScale = 2.0, yScale = 2.0; + if (dx > dy) + yScale *= dy/dx; + else + xScale *= dx/dy; + + // build the matrix - the translation to the origin, the scale, + // and the translation back to the center (hard coded at (0.5, 0.5) for now). + // the matrix is build directly instead of with matrix multiplications + // for efficiency, not to mention that the multiplication function does + // not exist for mat3's. + // the matrix as laid out below looks transposed - order is columnwise. + var xCtr = 0.5, yCtr = 0.5; + this._textureTransform = [ + xScale, 0.0, 0.0, + 0.0, yScale, 0.0, + xCtr*(1-xScale), yCtr*(1 - yScale), 1.0 + ]; + + if (this._shader && this._shader['default']) + this._shader['default'].u_texTransform.set( this._textureTransform ); + + } + }; + this.exportJSON = function () { var jObj = { @@ -316,7 +356,8 @@ var radialGradientMaterialDef = 'u_colorStop1': { 'type': 'float' }, 'u_colorStop2': { 'type': 'float' }, 'u_colorStop3': { 'type': 'float' }, - 'u_colorStop4': { 'type': 'float' } + 'u_colorStop4': { 'type': 'float' }, + 'u_texTransform': { 'type' : 'mat3' } //'u_colorCount': {'type' : 'int' } }, -- cgit v1.2.3