OpenGL,改变图像颜色

时间:2014-05-16 20:49:23

标签: javascript html opengl-es webgl

我一直致力于在桌子上渲染一个雪人的形象。一切都很好,但我似乎无法让我的桌子的颜色改变为自己的颜色(黑色) - 它保持与雪人相同的颜色。

以下是javascript和html文件:

image.js:

function myscale( x, y, z )
{  
    var result = mat4();
    result[0][0] = x;
    result[1][1] = y;
    result[2][2] = z;

    return result;
}

var canvas;
var gl;

var nBuffer; 
var snBuffer; 
var vBuffer;
var svBuffer;  

var numVertices  = 36;

var pointsArray = [];
var normalsArray = [];
var spointsArray = [];
var snormalsArray = [];

var vertices = [
    vec4( -0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5,  0.5,  0.5, 1.0 ),
    vec4( 0.5,  0.5,  0.5, 1.0 ),
    vec4( 0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5, -0.5, -0.5, 1.0 ),
    vec4( -0.5,  0.5, -0.5, 1.0 ),
    vec4( 0.5,  0.5, -0.5, 1.0 ),
    vec4( 0.5, -0.5, -0.5, 1.0 )
];

var index = 0; 
var numTimesToSubdivide = 4;

var va = vec4(0.0, 0.0, -1.0,1);
var vb = vec4(0.0, 0.942809, 0.333333, 1);
var vc = vec4(-0.816497, -0.471405, 0.333333, 1);
var vd = vec4(0.816497, -0.471405, 0.333333,1);

//the sphere color (polished silver)
var lightPosition = vec4(1.0, 1.0, 1.0, 0.0 );
var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );
var lightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );
var lightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );

var materialAmbient = vec4( 0.19225, 0.19225, 0.19225);
var materialDiffuse = vec4( 0.50754, 0.50754, 0.50754);
var materialSpecular = vec4( 0.508273, 0.508273, 0.508273);
var materialShininess = 51.2;

var ctm;
var ambientColor, diffuseColor, specularColor;
var modelView, projection;
var viewerPos;
var program;

var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = 0;
var theta =[0, 0, 0];

var thetaLoc;

var flag = true;
function triangle(a, b, c) {

    var t1 = subtract(b, a);
    var t2 = subtract(c, a);
    var normal = normalize(cross(t1, t2));
    normal = vec4(normal);

    snormalsArray.push(normal);
    snormalsArray.push(normal);
    snormalsArray.push(normal);


    spointsArray.push(a);
    spointsArray.push(b);      
    spointsArray.push(c);

    index += 3;
}

function divideTriangle(a, b, c, count) {
    if ( count > 0 ) {

        var ab = mix( a, b, 0.5);
        var ac = mix( a, c, 0.5);
        var bc = mix( b, c, 0.5);

        ab = normalize(ab, true);
        ac = normalize(ac, true);
        bc = normalize(bc, true);

        divideTriangle( a, ab, ac, count - 1 );
        divideTriangle( ab, b, bc, count - 1 );
        divideTriangle( bc, c, ac, count - 1 );
        divideTriangle( ab, bc, ac, count - 1 );
    }
    else { 
        triangle( a, b, c );
    }
}


function tetrahedron(a, b, c, d, n) {
    divideTriangle(a, b, c, n);
    divideTriangle(d, c, b, n);
    divideTriangle(a, d, b, n);
    divideTriangle(a, c, d, n);
}

function quad(a, b, c, d) {

    var t1 = subtract(vertices[b], vertices[a]);
    var t2 = subtract(vertices[c], vertices[b]);
    var normal = cross(t1, t2);
    var normal = vec3(normal);
    normal = normalize(normal);

    pointsArray.push(vertices[a]); 
    normalsArray.push(normal); 
    pointsArray.push(vertices[b]); 
    normalsArray.push(normal); 
    pointsArray.push(vertices[c]); 
    normalsArray.push(normal);   
    pointsArray.push(vertices[a]);  
    normalsArray.push(normal);      
    pointsArray.push(vertices[c]); 
    normalsArray.push(normal); 
    pointsArray.push(vertices[d]); 
    normalsArray.push(normal);    
}


function colorCube()
{
    quad( 1, 0, 3, 2 );
    quad( 2, 3, 7, 6 );
    quad( 3, 0, 4, 7 );
    quad( 6, 5, 1, 2 );
    quad( 4, 5, 6, 7 );
    quad( 5, 4, 0, 1 );
}

window.onload = function init() {
    canvas = document.getElementById( "gl-canvas" );

    gl = WebGLUtils.setupWebGL( canvas );
    if ( !gl ) { alert( "WebGL isn't available" ); }

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

    gl.enable(gl.DEPTH_TEST);

//
//  Load shaders and initialize attribute buffers
//
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );

    colorCube();
    tetrahedron(va, vb, vc, vd, numTimesToSubdivide);

    nBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, nBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW );


    vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );

    thetaLoc = gl.getUniformLocation(program, "theta"); 

    projection = ortho(-1, 1, -1, 1, -100, 100);

    ambientProduct = mult(lightAmbient, materialAmbient);
    diffuseProduct = mult(lightDiffuse, materialDiffuse);
    specularProduct = mult(lightSpecular, materialSpecular);

    gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"),
   flatten(ambientProduct));
    gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"),
   flatten(diffuseProduct) );
    gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"), 
   flatten(specularProduct) );  
    gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"), 
   flatten(lightPosition) );

    gl.uniform1f(gl.getUniformLocation(program, 
   "shininess"),materialShininess);

    gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"),
   false, flatten(projection));
    snBuffer = gl.createBuffer();

    gl.bindBuffer( gl.ARRAY_BUFFER, snBuffer);
    gl.bufferData( gl.ARRAY_BUFFER, flatten(snormalsArray), gl.STATIC_DRAW );

    svBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, svBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(spointsArray), gl.STATIC_DRAW);

    render();
}

var render = function(){
var vNormal = gl.getAttribLocation( program, "vNormal" );
    var vPosition = gl.getAttribLocation(program, "vPosition");

    gl.bindBuffer( gl.ARRAY_BUFFER, nBuffer );
    gl.vertexAttribPointer( vNormal, 3, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vNormal );

    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0); 
    gl.enableVertexAttribArray(vPosition);


    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    var eye = vec3(1,3,7);
    var at = vec3(0.0, 0.0, 0.0);
    var up = vec3(0.0, 1.0, 0.0);  
    view = lookAt(eye, at , up);
    model = mat4();        
    modelView = mat4();

   //Tabletop
    modelView = mult(translate(.0010, 0.09, 0.0), myscale(6.5, 0.10, 3.5));
    gl.uniformMatrix4fv( gl.getUniformLocation(program, "modelViewMatrix"), false, flatten(modelView) );
    gl.drawArrays( gl.TRIANGLES, 0, numVertices );


    //leg #1 - first from the left
    modelView = mult(translate(-.8, -.33, 0.0) , myscale(.12, .9, 2.2));
    gl.uniformMatrix4fv( gl.getUniformLocation(program,"modelViewMatrix"), false, flatten(modelView) );
    gl.drawArrays( gl.TRIANGLES, 0, numVertices ); 

    //leg #2 - 4th from the left
    modelView = mult(translate(.8, -.33, 0.0) , myscale(.12, .9, 2.2));
    gl.uniformMatrix4fv( gl.getUniformLocation(program, "modelViewMatrix"), false, flatten(modelView) );
    gl.drawArrays( gl.TRIANGLES, 0, numVertices ); 

    //leg #3 - 2nd from the left
    modelView = mult(translate(-.63, -.248, -0.9) , myscale(.1, .6, -4.6));
    gl.uniformMatrix4fv( gl.getUniformLocation(program, "modelViewMatrix"), false, flatten(modelView) );
    gl.drawArrays( gl.TRIANGLES, 0, numVertices ); 

    //leg #4 - 3rd from the left
    modelView = mult(translate(.63, -.248, -0.9) , myscale(.1, .6, -4.6));
    gl.uniformMatrix4fv( gl.getUniformLocation(program,"modelViewMatrix"), false, flatten(modelView) );
    gl.drawArrays( gl.TRIANGLES, 0, numVertices );             

//bind the buffers to create the snowman
    gl.bindBuffer( gl.ARRAY_BUFFER, snBuffer);
    gl.vertexAttribPointer( vNormal, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vNormal );

    gl.bindBuffer(gl.ARRAY_BUFFER, svBuffer);
    gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosition);

//draw the snowman

    lightPosition = vec4(1.0, 1.0, 1.0, 0.0 );
lightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );
lightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );
lightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );

materialAmbient = vec4( 1.0, 0.0, 1.0, 1.0 );
materialDiffuse = vec4( 1.0, 0.8, 0.0, 1.0);
materialSpecular = vec4( 1.0, 0.8, 0.0, 1.0 );
materialShininess = 100.0;

    ambientProduct = mult(lightAmbient, materialAmbient);
    diffuseProduct = mult(lightDiffuse, materialDiffuse);
    specularProduct = mult(lightSpecular, materialSpecular);

   gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"),
   flatten(ambientProduct));
   gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"),
   flatten(diffuseProduct) );
   gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"), 
   flatten(specularProduct) );  
   gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"), 
   flatten(lightPosition) );

    gl.uniform1f(gl.getUniformLocation(program, 
   "shininess"),materialShininess);
    model = mult(translate(0,.35,0), myscale(0.2,0.2,0.2));
    modelView = mult(view,model);
    gl.uniformMatrix4fv( gl.getUniformLocation(program,
        "modelViewMatrix"), false, flatten(modelView) );

    for( var i=0; i<index; i+=3) 
        gl.drawArrays( gl.TRIANGLES, i, 3 ); 

    model = mult(translate(0,.65, 0), myscale(0.17,0.17,0.17));
    modelView = mult(view,model);
    gl.uniformMatrix4fv( gl.getUniformLocation(program,
        "modelViewMatrix"), false, flatten(modelView) );

    for( var i=0; i<index; i+=3) 
        gl.drawArrays( gl.TRIANGLES, i, 3 ); 

model = mult(translate(0,.90, 0), myscale(0.12,0.12,0.12));
    modelView = mult(view,model);
    gl.uniformMatrix4fv( gl.getUniformLocation(program,
        "modelViewMatrix"), false, flatten(modelView) );

    for( var i=0; i<index; i+=3) 
        gl.drawArrays( gl.TRIANGLES, i, 3 ); 

    requestAnimFrame(render);
}

html文件:

<!DOCTYPE html>

<html>
<head> 
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">

</head>

<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec3 vNormal;
varying vec4 fColor;

uniform vec4 ambientProduct, diffuseProduct, specularProduct;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 lightPosition;
uniform float shininess;
varying vec3 N, L, E;

void main()
{  
    vec3 pos = -(modelViewMatrix * vPosition).xyz;
    vec3 light = lightPosition.xyz;
    vec3 L = normalize( light - pos );


    vec3 E = normalize( -pos );
    vec3 H = normalize( L + E );

    vec4 NN = vec4(vNormal,0);

    // Transform vertex normal into eye coordinates

    vec3 N = normalize( (modelViewMatrix*NN).xyz);

    // Compute terms in the illumination equation
    vec4 ambient = ambientProduct;

    float Kd = max( dot(L, N), 0.0 );
    vec4  diffuse = Kd*diffuseProduct;

    float Ks = pow( max(dot(N, H), 0.0), shininess );
    vec4  specular = Ks * specularProduct;

    if( dot(L, N) < 0.0 ) {
        specular = vec4(0.0, 0.0, 0.0, 1.0);
    } 

    gl_Position = projectionMatrix * modelViewMatrix * vPosition;
    fColor = ambient + diffuse +specular;

    fColor.a = 1.0;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

#ifdef GL_ES
precision highp float;
#endif


varying vec4 fColor;

void
main()
{
    gl_FragColor = fColor;
}
</script>

<script type="text/javascript" src="./Scripts/webgl-utils.js"></script>
<script type="text/javascript" src="./Scripts/initShaders.js"></script>
<script type="text/javascript" src="./Scripts/MV.js"></script>
<script type="text/javascript" src="./Scripts/image.js"></script>

<body>
<canvas id="gl-canvas" width="600" height="600">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

0 个答案:

没有答案