mirror of
https://github.com/gpujs/gpu.js.git
synced 2026-01-18 16:04:10 +00:00
455 lines
18 KiB
JavaScript
455 lines
18 KiB
JavaScript
/**
|
|
* WebCLGLVertexFragmentProgram Object
|
|
* @class
|
|
* @constructor
|
|
*/
|
|
WebCLGLVertexFragmentProgram = function(gl, vertexSource, vertexHeader, fragmentSource, fragmentHeader) {
|
|
this.gl = gl;
|
|
var highPrecisionSupport = this.gl.getShaderPrecisionFormat(this.gl.FRAGMENT_SHADER, this.gl.HIGH_FLOAT);
|
|
this.precision = (highPrecisionSupport.precision != 0) ? 'precision highp float;\n\nprecision highp int;\n\n' : 'precision lowp float;\n\nprecision lowp int;\n\n';
|
|
|
|
this.utils = new WebCLGLUtils();
|
|
|
|
this.vertexSource;
|
|
this.fragmentSource;
|
|
this.in_vertex_values = [];
|
|
this.in_fragment_values = [];
|
|
|
|
this.vertexAttributes = []; // {location,value}
|
|
this.vertexUniforms = []; // {location,value}
|
|
this.fragmentSamplers = []; // {location,value}
|
|
this.fragmentUniforms = []; // {location,value}
|
|
|
|
if(vertexSource != undefined) this.setVertexSource(vertexSource, vertexHeader);
|
|
if(fragmentSource != undefined) this.setFragmentSource(fragmentSource, fragmentHeader);
|
|
};
|
|
|
|
/**
|
|
* Update the vertex source
|
|
* @type Void
|
|
* @param {String} vertexSource
|
|
* @param {String} vertexHeader
|
|
*/
|
|
WebCLGLVertexFragmentProgram.prototype.setVertexSource = function(vertexSource, vertexHeader) {
|
|
this.vertexHead =(vertexHeader!=undefined)?vertexHeader:'';
|
|
this.in_vertex_values = [];//{value,type,name,idPointer}
|
|
// value: argument value
|
|
// type: 'buffer_float4_fromKernel'(4 packet pointer4), 'buffer_float_fromKernel'(1 packet pointer4), 'buffer_float4'(1 pointer4), 'buffer_float'(1 pointer1)
|
|
// name: argument name
|
|
// idPointer to: this.vertexAttributes or this.vertexUniforms (according to type)
|
|
|
|
var argumentsSource = vertexSource.split(')')[0].split('(')[1].split(','); // "float* A", "float* B", "float C", "float4* D"
|
|
//console.log(argumentsSource);
|
|
for(var n = 0, f = argumentsSource.length; n < f; n++) {
|
|
if(argumentsSource[n].match(/\*kernel/gm) != null) {
|
|
if(argumentsSource[n].match(/float4/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'buffer_float4_fromKernel',
|
|
name:argumentsSource[n].split('*kernel')[1].trim()};
|
|
} else if(argumentsSource[n].match(/float/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'buffer_float_fromKernel',
|
|
name:argumentsSource[n].split('*kernel')[1].trim()};
|
|
}
|
|
} else if(argumentsSource[n].match(/\*/gm) != null) {
|
|
if(argumentsSource[n].match(/float4/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'buffer_float4',
|
|
name:argumentsSource[n].split('*')[1].trim()};
|
|
} else if(argumentsSource[n].match(/float/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'buffer_float',
|
|
name:argumentsSource[n].split('*')[1].trim()};
|
|
}
|
|
} else {
|
|
if(argumentsSource[n].match(/float4/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'float4',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
} else if(argumentsSource[n].match(/float/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'float',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
} else if(argumentsSource[n].match(/mat4/gm) != null) {
|
|
this.in_vertex_values[n] = { value:undefined,
|
|
type:'mat4',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
}
|
|
}
|
|
}
|
|
//console.log(this.in_vertex_values);
|
|
|
|
//console.log('original source: '+vertexSource);
|
|
this.vertexSource = vertexSource.replace(/\r\n/gi, '').replace(/\r/gi, '').replace(/\n/gi, '');
|
|
this.vertexSource = this.vertexSource.replace(/^\w* \w*\([\w\s\*,]*\) {/gi, '').replace(/}(\s|\t)*$/gi, '');
|
|
//console.log('minified source: '+this.vertexSource);
|
|
|
|
this.vertexSource = this.parseVertexSource(this.vertexSource);
|
|
|
|
if(this.fragmentSource != undefined) this.compileVertexFragmentSource();
|
|
};
|
|
/** @private **/
|
|
WebCLGLVertexFragmentProgram.prototype.parseVertexSource = function(source) {
|
|
//console.log(source);
|
|
for(var n = 0, f = this.in_vertex_values.length; n < f; n++) { // for each in_vertex_values (in argument)
|
|
var regexp = new RegExp(this.in_vertex_values[n].name+'\\[\\w*\\]',"gm");
|
|
var varMatches = source.match(regexp);// "Search current "in_vertex_values.name[xxx]" in source and store in array varMatches
|
|
//console.log(varMatches);
|
|
if(varMatches != null) {
|
|
for(var nB = 0, fB = varMatches.length; nB < fB; nB++) { // for each varMatches ("A[x]", "A[x]")
|
|
var regexpNativeGL = new RegExp('```(\s|\t)*gl.*'+varMatches[nB]+'.*```[^```(\s|\t)*gl]',"gm");
|
|
var regexpNativeGLMatches = source.match(regexpNativeGL);
|
|
if(regexpNativeGLMatches == null) {
|
|
var name = varMatches[nB].split('[')[0];
|
|
var vari = varMatches[nB].split('[')[1].split(']')[0];
|
|
var regexp = new RegExp(name+'\\['+vari.trim()+'\\]',"gm");
|
|
|
|
if(this.in_vertex_values[n].type == 'buffer_float4_fromKernel')
|
|
source = source.replace(regexp, 'buffer_float4_fromKernel_data('+name+','+vari+')');
|
|
if(this.in_vertex_values[n].type == 'buffer_float_fromKernel')
|
|
source = source.replace(regexp, 'buffer_float_fromKernel_data('+name+','+vari+')');
|
|
if(this.in_vertex_values[n].type == 'buffer_float4')
|
|
source = source.replace(regexp, name);
|
|
if(this.in_vertex_values[n].type == 'buffer_float')
|
|
source = source.replace(regexp, name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
source = source.replace(/```(\s|\t)*gl/gi, "").replace(/```/gi, "").replace(/;/gi, ";\n").replace(/}/gi, "}\n").replace(/{/gi, "{\n");
|
|
//console.log('%c translated source:'+source, "background-color:#000;color:#FFF");
|
|
return source;
|
|
};
|
|
/**
|
|
* Update the fragment source
|
|
* @type Void
|
|
* @param {String} fragmentSource
|
|
* @param {String} fragmentHeader
|
|
*/
|
|
WebCLGLVertexFragmentProgram.prototype.setFragmentSource = function(fragmentSource, fragmentHeader) {
|
|
this.fragmentHead =(fragmentHeader!=undefined)?fragmentHeader:'';
|
|
this.in_fragment_values = [];//{value,type,name,idPointer}
|
|
// value: argument value
|
|
// type: 'buffer_float4'(RGBA channels), 'buffer_float'(Red channel)
|
|
// name: argument name
|
|
// idPointer to: this.fragmentSamplers or this.fragmentUniforms (according to type)
|
|
|
|
var argumentsSource = fragmentSource.split(')')[0].split('(')[1].split(','); // "float* A", "float* B", "float C", "float4* D"
|
|
//console.log(argumentsSource);
|
|
for(var n = 0, f = argumentsSource.length; n < f; n++) {
|
|
if(argumentsSource[n].match(/\*/gm) != null) {
|
|
if(argumentsSource[n].match(/float4/gm) != null) {
|
|
this.in_fragment_values[n] = { value:undefined,
|
|
type:'buffer_float4',
|
|
name:argumentsSource[n].split('*')[1].trim()};
|
|
} else if(argumentsSource[n].match(/float/gm) != null) {
|
|
this.in_fragment_values[n] = { value:undefined,
|
|
type:'buffer_float',
|
|
name:argumentsSource[n].split('*')[1].trim()};
|
|
}
|
|
} else {
|
|
if(argumentsSource[n].match(/float4/gm) != null) {
|
|
this.in_fragment_values[n] = { value:undefined,
|
|
type:'float4',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
} else if(argumentsSource[n].match(/float/gm) != null) {
|
|
this.in_fragment_values[n] = { value:undefined,
|
|
type:'float',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
} else if(argumentsSource[n].match(/mat4/gm) != null) {
|
|
this.in_fragment_values[n] = { value:undefined,
|
|
type:'mat4',
|
|
name:argumentsSource[n].split(' ')[1].trim()};
|
|
}
|
|
}
|
|
}
|
|
//console.log(this.in_fragment_values);
|
|
|
|
//console.log('original source: '+source);
|
|
this.fragmentSource = fragmentSource.replace(/\r\n/gi, '').replace(/\r/gi, '').replace(/\n/gi, '');
|
|
this.fragmentSource = this.fragmentSource.replace(/^\w* \w*\([\w\s\*,]*\) {/gi, '').replace(/}(\s|\t)*$/gi, '');
|
|
//console.log('minified source: '+this.fragmentSource);
|
|
|
|
this.fragmentSource = this.parseFragmentSource(this.fragmentSource);
|
|
|
|
if(this.vertexSource != undefined) this.compileVertexFragmentSource();
|
|
};
|
|
/** @private **/
|
|
WebCLGLVertexFragmentProgram.prototype.parseFragmentSource = function(source) {
|
|
//console.log(source);
|
|
for(var n = 0, f = this.in_fragment_values.length; n < f; n++) { // for each in_fragment_values (in argument)
|
|
var regexp = new RegExp(this.in_fragment_values[n].name+'\\[\\w*\\]',"gm");
|
|
var varMatches = source.match(regexp);// "Search current "in_fragment_values.name[xxx]" in source and store in array varMatches
|
|
//console.log(varMatches);
|
|
if(varMatches != null) {
|
|
for(var nB = 0, fB = varMatches.length; nB < fB; nB++) { // for each varMatches ("A[x]", "A[x]")
|
|
var regexpNativeGL = new RegExp('```(\s|\t)*gl.*'+varMatches[nB]+'.*```[^```(\s|\t)*gl]',"gm");
|
|
var regexpNativeGLMatches = source.match(regexpNativeGL);
|
|
if(regexpNativeGLMatches == null) {
|
|
var name = varMatches[nB].split('[')[0];
|
|
var vari = varMatches[nB].split('[')[1].split(']')[0];
|
|
var regexp = new RegExp(name+'\\['+vari.trim()+'\\]',"gm");
|
|
|
|
if(this.in_fragment_values[n].type == 'buffer_float4')
|
|
source = source.replace(regexp, 'buffer_float4_data('+name+','+vari+')');
|
|
if(this.in_fragment_values[n].type == 'buffer_float')
|
|
source = source.replace(regexp, 'buffer_float_data('+name+','+vari+')');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
source = source.replace(/```(\s|\t)*gl/gi, "").replace(/```/gi, "").replace(/;/gi, ";\n").replace(/}/gi, "}\n").replace(/{/gi, "{\n");
|
|
//console.log('%c translated source:'+source, "background-color:#000;color:#FFF");
|
|
return source;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @private **/
|
|
WebCLGLVertexFragmentProgram.prototype.compileVertexFragmentSource = function() {
|
|
lines_vertex_attrs = (function() {
|
|
str = '';
|
|
for(var n = 0, f = this.in_vertex_values.length; n < f; n++) {
|
|
if(this.in_vertex_values[n].type == 'buffer_float4_fromKernel' || this.in_vertex_values[n].type == 'buffer_float_fromKernel') {
|
|
str += 'uniform sampler2D '+this.in_vertex_values[n].name+';\n';
|
|
} else if(this.in_vertex_values[n].type == 'buffer_float4') {
|
|
str += 'attribute vec4 '+this.in_vertex_values[n].name+';\n';
|
|
} else if(this.in_vertex_values[n].type == 'buffer_float') {
|
|
str += 'attribute float '+this.in_vertex_values[n].name+';\n';
|
|
} else if(this.in_vertex_values[n].type == 'float') {
|
|
str += 'uniform float '+this.in_vertex_values[n].name+';\n';
|
|
} else if(this.in_vertex_values[n].type == 'float4') {
|
|
str += 'uniform vec4 '+this.in_vertex_values[n].name+';\n';
|
|
} else if(this.in_vertex_values[n].type == 'mat4') {
|
|
str += 'uniform mat4 '+this.in_vertex_values[n].name+';\n';
|
|
}
|
|
}
|
|
return str;
|
|
}).bind(this);
|
|
|
|
lines_fragment_attrs = (function() {
|
|
str = '';
|
|
for(var n = 0, f = this.in_fragment_values.length; n < f; n++) {
|
|
if(this.in_fragment_values[n].type == 'buffer_float4' || this.in_fragment_values[n].type == 'buffer_float') {
|
|
str += 'uniform sampler2D '+this.in_fragment_values[n].name+';\n';
|
|
} else if(this.in_fragment_values[n].type == 'float') {
|
|
str += 'uniform float '+this.in_fragment_values[n].name+';\n';
|
|
} else if(this.in_fragment_values[n].type == 'float4') {
|
|
str += 'uniform vec4 '+this.in_fragment_values[n].name+';\n';
|
|
} else if(this.in_fragment_values[n].type == 'mat4') {
|
|
str += 'uniform mat4 '+this.in_fragment_values[n].name+';\n';
|
|
}
|
|
}
|
|
return str;
|
|
}).bind(this);
|
|
|
|
|
|
var sourceVertex = this.precision+
|
|
'uniform float uOffset;\n'+
|
|
'uniform float uBufferWidth;'+
|
|
'uniform float uGeometryLength;'+
|
|
|
|
lines_vertex_attrs()+
|
|
|
|
this.utils.unpackGLSLFunctionString()+
|
|
|
|
'vec4 buffer_float4_fromKernel_data(sampler2D arg, vec2 coord) {\n'+
|
|
'vec4 textureColor = texture2D(arg, coord);\n'+
|
|
'return textureColor;\n'+
|
|
'}\n'+
|
|
'float buffer_float_fromKernel_data(sampler2D arg, vec2 coord) {\n'+
|
|
'vec4 textureColor = texture2D(arg, coord);\n'+
|
|
'return textureColor.x;\n'+
|
|
'}\n'+
|
|
|
|
'vec2 get_global_id() {\n'+
|
|
'return vec2(0.0, 0.0);\n'+
|
|
'}\n'+
|
|
|
|
'vec2 get_global_id(float id) {\n'+
|
|
'float num = (id*uGeometryLength)/uBufferWidth;'+
|
|
'float column = fract(num)*uBufferWidth;'+
|
|
'float row = floor(num);'+
|
|
|
|
'float ts = 1.0/(uBufferWidth-1.0);'+
|
|
'float xx = column*ts;'+
|
|
'float yy = row*ts;'+
|
|
|
|
'return vec2(xx, yy);'+
|
|
'}\n'+
|
|
|
|
this.vertexHead+
|
|
|
|
'void main(void) {\n'+
|
|
|
|
this.vertexSource+
|
|
|
|
'}\n';
|
|
//console.log(sourceVertex);
|
|
var sourceFragment = this.precision+
|
|
|
|
lines_fragment_attrs()+
|
|
|
|
'vec4 buffer_float4_data(sampler2D arg, vec2 coord) {\n'+
|
|
'vec4 textureColor = texture2D(arg, coord);\n'+
|
|
'return textureColor;\n'+
|
|
'}\n'+
|
|
'float buffer_float_data(sampler2D arg, vec2 coord) {\n'+
|
|
'vec4 textureColor = texture2D(arg, coord);\n'+
|
|
'return textureColor.x;\n'+
|
|
'}\n'+
|
|
|
|
'vec2 get_global_id() {\n'+
|
|
'return vec2(0.0, 0.0);\n'+
|
|
'}\n'+
|
|
|
|
this.fragmentHead+
|
|
|
|
'void main(void) {\n'+
|
|
|
|
this.fragmentSource+
|
|
|
|
'}\n';
|
|
//console.log(sourceFragment);
|
|
|
|
this.vertexFragmentProgram = this.gl.createProgram();
|
|
this.utils.createShader(this.gl, "WEBCLGL VERTEX FRAGMENT PROGRAM", sourceVertex, sourceFragment, this.vertexFragmentProgram);
|
|
|
|
|
|
this.vertexAttributes = []; // {location,value}
|
|
this.vertexUniforms = []; // {location,value}
|
|
this.fragmentSamplers = []; // {location,value}
|
|
this.fragmentUniforms = []; // {location,value}
|
|
|
|
this.uOffset = this.gl.getUniformLocation(this.vertexFragmentProgram, "uOffset");
|
|
this.uBufferWidth = this.gl.getUniformLocation(this.vertexFragmentProgram, "uBufferWidth");
|
|
this.uGeometryLength = this.gl.getUniformLocation(this.vertexFragmentProgram, "uGeometryLength");
|
|
|
|
// vertexAttributes & vertexUniforms
|
|
for(var n = 0, f = this.in_vertex_values.length; n < f; n++) {
|
|
if(this.in_vertex_values[n].type == 'buffer_float_fromKernel' || this.in_vertex_values[n].type == 'buffer_float4_fromKernel') {
|
|
this.vertexAttributes.push({ location: [this.gl.getUniformLocation(this.vertexFragmentProgram, this.in_vertex_values[n].name)],
|
|
value: this.in_vertex_values[n].value,
|
|
type: this.in_vertex_values[n].type,
|
|
name: this.in_vertex_values[n].name});
|
|
|
|
this.in_vertex_values[n].idPointer = this.vertexAttributes.length-1;
|
|
} else if(this.in_vertex_values[n].type == 'buffer_float4' || this.in_vertex_values[n].type == 'buffer_float') {
|
|
this.vertexAttributes.push({ location: [this.gl.getAttribLocation(this.vertexFragmentProgram, this.in_vertex_values[n].name)],
|
|
value: this.in_vertex_values[n].value,
|
|
type: this.in_vertex_values[n].type,
|
|
name: this.in_vertex_values[n].name});
|
|
|
|
this.in_vertex_values[n].idPointer = this.vertexAttributes.length-1;
|
|
} else if(this.in_vertex_values[n].type == 'float' || this.in_vertex_values[n].type == 'float4' || this.in_vertex_values[n].type == 'mat4') {
|
|
this.vertexUniforms.push({ location: [this.gl.getUniformLocation(this.vertexFragmentProgram, this.in_vertex_values[n].name)],
|
|
value: this.in_vertex_values[n].value,
|
|
type: this.in_vertex_values[n].type,
|
|
name: this.in_vertex_values[n].name});
|
|
|
|
this.in_vertex_values[n].idPointer = this.vertexUniforms.length-1;
|
|
}
|
|
}
|
|
|
|
// fragmentSamplers & fragmentUniforms
|
|
for(var n = 0, f = this.in_fragment_values.length; n < f; n++) {
|
|
if(this.in_fragment_values[n].type == 'buffer_float4' || this.in_fragment_values[n].type == 'buffer_float') {
|
|
this.fragmentSamplers.push({ location: [this.gl.getUniformLocation(this.vertexFragmentProgram, this.in_fragment_values[n].name)],
|
|
value: this.in_fragment_values[n].value,
|
|
type: this.in_fragment_values[n].type,
|
|
name: this.in_fragment_values[n].name});
|
|
|
|
this.in_fragment_values[n].idPointer = this.fragmentSamplers.length-1;
|
|
} else if(this.in_fragment_values[n].type == 'float' || this.in_fragment_values[n].type == 'float4' || this.in_fragment_values[n].type == 'mat4') {
|
|
this.fragmentUniforms.push({ location: [this.gl.getUniformLocation(this.vertexFragmentProgram, this.in_fragment_values[n].name)],
|
|
value: this.in_fragment_values[n].value,
|
|
type: this.in_fragment_values[n].type,
|
|
name: this.in_fragment_values[n].name});
|
|
|
|
this.in_fragment_values[n].idPointer = this.fragmentUniforms.length-1;
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Bind float, mat4 or a WebCLGLBuffer to a vertex argument
|
|
* @param {Int|String} argument Id of argument or name of this
|
|
* @param {Float|Int|Array<Float4>|Array<Mat4>|WebCLGLBuffer} data
|
|
*/
|
|
WebCLGLVertexFragmentProgram.prototype.setVertexArg = function(argument, data) {
|
|
if(data == undefined) alert("Error: setVertexArg("+argument+", undefined)");
|
|
|
|
var numArg;
|
|
if(typeof argument != "string") {
|
|
numArg = argument;
|
|
} else {
|
|
for(var n=0, fn = this.in_vertex_values.length; n < fn; n++) {
|
|
if(this.in_vertex_values[n].name == argument) {
|
|
numArg = n;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.in_vertex_values[numArg] == undefined) {
|
|
console.log("argument "+argument+" not exist in this vertex program");
|
|
return;
|
|
}
|
|
this.in_vertex_values[numArg].value = data;
|
|
|
|
if( this.in_vertex_values[numArg].type == 'buffer_float4_fromKernel' ||
|
|
this.in_vertex_values[numArg].type == 'buffer_float_fromKernel' ||
|
|
this.in_vertex_values[numArg].type == 'buffer_float4' ||
|
|
this.in_vertex_values[numArg].type == 'buffer_float') {
|
|
this.vertexAttributes[this.in_vertex_values[numArg].idPointer].value = this.in_vertex_values[numArg].value;
|
|
} else if(this.in_vertex_values[numArg].type == 'float' || this.in_vertex_values[numArg].type == 'float4' || this.in_vertex_values[numArg].type == 'mat4') {
|
|
this.vertexUniforms[this.in_vertex_values[numArg].idPointer].value = this.in_vertex_values[numArg].value;
|
|
}
|
|
};
|
|
/**
|
|
* Bind float or a WebCLGLBuffer to a fragment argument
|
|
* @param {Int|String} argument Id of argument or name of this
|
|
* @param {Float|Int|Array<Float4>|Array<Mat4>|WebCLGLBuffer} data
|
|
*/
|
|
WebCLGLVertexFragmentProgram.prototype.setFragmentArg = function(argument, data) {
|
|
if(data == undefined) alert("Error: setFragmentArg("+argument+", undefined)");
|
|
|
|
var numArg;
|
|
if(typeof argument != "string") {
|
|
numArg = argument;
|
|
} else {
|
|
for(var n=0, fn = this.in_fragment_values.length; n < fn; n++) {
|
|
if(this.in_fragment_values[n].name == argument) {
|
|
numArg = n;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.in_fragment_values[numArg] == undefined) {
|
|
console.log("argument "+argument+" not exist in this fragment program");
|
|
return;
|
|
}
|
|
this.in_fragment_values[numArg].value = data;
|
|
|
|
if(this.in_fragment_values[numArg].type == 'buffer_float4' || this.in_fragment_values[numArg].type == 'buffer_float') {
|
|
this.fragmentSamplers[this.in_fragment_values[numArg].idPointer].value = this.in_fragment_values[numArg].value;
|
|
} else if(this.in_fragment_values[numArg].type == 'float' || this.in_fragment_values[numArg].type == 'float4' || this.in_fragment_values[numArg].type == 'mat4') {
|
|
this.fragmentUniforms[this.in_fragment_values[numArg].idPointer].value = this.in_fragment_values[numArg].value;
|
|
}
|
|
};
|