javascript - Can I get a texture onto my second cube? -
i'd opinion: have following program consisting of 2 multi-colored cubes can selected via 1 html button , rotated pressing corresponding keys on keyboard.
here html file:
<html> <script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 vposition; attribute vec4 vcolor; varying vec4 fcolor; uniform vec3 theta; uniform vec4 posiz; void main() { // compute sines , cosines of theta each of 3 axes in 1 computation. vec3 angles = radians( theta ); vec3 c = cos( angles ); vec3 s = sin( angles ); // remember: these matrices column-major mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, c.x, s.x, 0.0, 0.0, -s.x, c.x, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 ry = mat4( c.y, 0.0, -s.y, 0.0, 0.0, 1.0, 0.0, 0.0, s.y, 0.0, c.y, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 rz = mat4( c.z, -s.z, 0.0, 0.0, s.z, c.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); // position matrix mat4 posmat = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, posiz[0], posiz[1], posiz[2], 1.0 ); // size matrix mat4 sizmat = mat4( posiz[3], 0.0, 0.0, 0.0, 0.0, posiz[3], 0.0, 0.0, 0.0, 0.0, posiz[3], 0.0, 0.0, 0.0, 0.0, 1.0 ); fcolor = vcolor; gl_position = sizmat * posmat * rz * ry * rx * vposition; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> precision mediump float; varying vec4 fcolor; void main() { gl_fragcolor = fcolor; } </script> <script type="text/javascript" src="../common/webgl-utils.js"></script> <script type="text/javascript" src="../common/initshaders.js"></script> <script type="text/javascript" src="../common/mv.js"></script> <script type="text/javascript" src="cubev-1.js"></script> <body> <canvas id="gl-canvas" width="512"" height="512"> oops ... browser doesn't support html5 canvas element </canvas> <br/> <input type = "button" value = "first" id = "switchbutton" ></input> </body> </html> files webgl-utils.js, initshaders.js, , mv.js can found here:
http://www.cs.unm.edu/~angel/webgl/7e/common/
and here accompanying javascript file:
var canvas; var gl; var numvertices = 36; var xaxis = 0; var yaxis = 1; var zaxis = 2; var axis1 = 0; var axis2 = 0; var rot1 = 1.0; // rate of rotation var rot2 = 1.0; var theta1 = [ 0, 0, 0 ]; var theta2 = [ 0, 0, 0 ]; // cube position along x, y, , z axis , size var posiz1 = [ 0, 0, 0, 1 ]; var posiz2 = [ 0, 0, 0, 1 ]; // used send info html, think var thetaloc; var posloc; var firstcube = true; var vertices = [ vec3( -0.5, -0.5, 0.5 ), vec3( -0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, -0.5, 0.5 ), vec3( -0.5, -0.5, -0.5 ), vec3( -0.5, 0.5, -0.5 ), vec3( 0.5, 0.5, -0.5 ), vec3( 0.5, -0.5, -0.5 ) ]; var vertexcolors = [ vec4( 0.0, 0.0, 0.0, 1.0 ), // black vec4( 1.0, 0.0, 0.0, 1.0 ), // red vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow vec4( 0.0, 1.0, 0.0, 1.0 ), // green vec4( 0.0, 0.0, 1.0, 1.0 ), // blue vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta vec4( 1.0, 1.0, 1.0, 1.0 ), // white vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan ]; // indices of 12 triangles comprise cube var indices = [ 1, 0, 3, 3, 2, 1, 2, 3, 7, 7, 6, 2, 3, 0, 4, 4, 7, 3, 6, 5, 1, 1, 2, 6, 4, 5, 6, 6, 7, 4, 5, 4, 0, 0, 1, 5 ]; 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 , initialize attribute buffers var program = initshaders( gl, "vertex-shader", "fragment-shader" ); gl.useprogram( program ); // array element buffer var ibuffer = gl.createbuffer(); gl.bindbuffer(gl.element_array_buffer, ibuffer); gl.bufferdata(gl.element_array_buffer, new uint8array(indices), gl.static_draw); // color array attribute buffer var cbuffer = gl.createbuffer(); gl.bindbuffer( gl.array_buffer, cbuffer ); gl.bufferdata( gl.array_buffer, flatten(vertexcolors), gl.static_draw ); var vcolor = gl.getattriblocation( program, "vcolor" ); gl.vertexattribpointer( vcolor, 4, gl.float, false, 0, 0 ); gl.enablevertexattribarray( vcolor ); // vertex array attribute buffer var vbuffer = gl.createbuffer(); gl.bindbuffer( gl.array_buffer, vbuffer ); gl.bufferdata( gl.array_buffer, flatten(vertices), gl.static_draw ); var vposition = gl.getattriblocation( program, "vposition" ); gl.vertexattribpointer( vposition, 3, gl.float, false, 0, 0 ); gl.enablevertexattribarray( vposition ); // connect location variable in html thetaloc = gl.getuniformlocation(program, "theta"); posizloc = gl.getuniformlocation(program, "posiz"); //event listeners buttons document.getelementbyid( "switchbutton" ).onclick = function () { firstcube = !firstcube; // switch between cubes if (firstcube) document.getelementbyid("switchbutton").value = "first"; else document.getelementbyid("switchbutton").value = "second"; }; window.onkeydown = function(event) { var key = string.fromcharcode(event.keycode); if (firstcube) { if (key == 'r') posiz1[0] += .1; else if (key == 'l') posiz1[0] -= .1; else if (key == 'u') posiz1[1] += .1; else if (key == 'd') posiz1[1] -= .1; else if (key == 'i') posiz1[2] += .1; else if (key == 'o') posiz1[2] -= .1; else if (key == 'g') posiz1[3] += .1; else if (key == 's') posiz1[3] -= .1; if (event.shiftkey == 0) { if (key == 'x' || key == 'y' || key == 'z') rot1 = -1.0; } else { if (key == 'x' || key == 'y' || key == 'z') rot1 = 1.0; } if (key == 'x') axis1 = xaxis; if (key == 'y') axis1 = yaxis; if (key == 'z') axis1 = zaxis; } else { if (key == 'r') posiz2[0] += .1; else if (key == 'l') posiz2[0] -= .1; else if (key == 'u') posiz2[1] += .1; else if (key == 'd') posiz2[1] -= .1; else if (key == 'i') posiz2[2] += .1; else if (key == 'o') posiz2[2] -= .1; else if (key == 'g') posiz2[3] += .1; else if (key == 's') posiz2[3] -= .1; if (event.shiftkey == 0) { if (key == 'x' || key == 'y' || key == 'z') rot2 = -1.0; } else { if (key == 'x' || key == 'y' || key == 'z') rot2 = 1.0; } if (key == 'x') axis2 = xaxis; if (key == 'y') axis2 = yaxis; if (key == 'z') axis2 = zaxis; } }; render(); } function render() { gl.clear( gl.color_buffer_bit | gl.depth_buffer_bit); // handle rendering of first cube theta1[axis1] += rot1; gl.uniform3fv(thetaloc, theta1); gl.uniform4fv(posizloc, posiz1); gl.drawelements( gl.triangles, numvertices, gl.unsigned_byte, 0 ); // handle rendering of second cube theta2[axis2] += rot2; gl.uniform3fv(thetaloc, theta2); gl.uniform4fv(posizloc, posiz2); gl.drawelements( gl.triangles, numvertices, gl.unsigned_byte, 0 ); requestanimframe( render ); } i have little experience webgl , trying texture mapped onto second cube without interfering colors on first. trying go following these instructions:
https://developer.mozilla.org/en-us/docs/web/webgl/using_textures_in_webgl#the_fragment_shader
which instruct me update fragment shader in html value feel interfere normal rendering of first cube.
am perhaps going wrong way? realistically possible map texture onto second cube without interfering colors of first? i'd opinion because don't want chase dead end.
by way, if run program yourself, here controls:
u - up, d - down, l - left, r - right, - in, o - out, g - grow, s - shrink
x/y/z - spin along cube's x/y/z-axis
shift + x/y/z - same above in opposite direction
and button switches between cubes.
thank , time in advance.
i think might find these tutorials helpful. in particular this 1 matrix math.
in particular it's not common matrix creation vertex shader. code rx, ry, rz, posmat & sizemat typically done in javascript , result send shader. makes shader far more flexible because can matrix math want in javascript, not 5 hardcoded things did in shader. of course there's nothing technically wrong way did it. whatever works you. i'm pointing out it's not common approach.
as texture vs current shader's vertex colors it's common have hundreds or thousands of shaders large program each different features. in fact 3d engine or game engine it's super common generate shaders depending features need particular object.
at same time particular case, instead of 2 shaders way might mix color , set 1 white
varying vec4 fcolor; varying vec2 texcoord; uniform sampler2d texture; void main(void) { gl_fragcolorl = texture2d(texture, texcoord) * fcolor; } so when want draw texture
// set attributes texcoord gl.bindbuffer(..... texcoordbuffer); gl.enablevertexattribarray(texcoordlocation); gl.vertexattribpointer(texcoordlocation, ....); // set texture gl.activetexture(gl.texture0 + unit); gl.bindtexture(...., texture); // tell shader unit put texture on gl.uniform1i(texturelocation, unit); // turn off attribute vertex colors gl.disablevertexattribarray(fcolorlocation); // set attribute returns white gl.vertexattrib4f(fcolorlocation, 1, 1, 1, 1); when want draw vertex colors can opposite
// set attributes vertex colors gl.bindbuffer(..... fcolorbuffer); gl.enablevertexattribarray(fcolorlocation); gl.vertexattribpointer(fcolorlocation, ....); // turn off attribute texcoords gl.disablevertexattribarray(texcoordlocation); // bind white texture gl.activetexture(gl.texture0 + unit); gl.bindtexture(...., white1x1pixeltexture); // tell shader unit put texture on gl.uniform1i(texturelocation, unit); at init time you'd create 1x1 white pixel texture
var white1x1pixeltexture = gl.createtexture(); gl.bindtexture(gl.texture_2d, white1x1pixeltexture); gl.teximage2d(gl.texture_2d, 0, gl.rgba, 1, 1, 0, gl.rgba, gl.unsigned_byte, new uint8array([255,255,255,255])); with style means can use texture , vertex colors @ same time common way add variety terrain map. setup both texture , vertex colors , they'll multiplied.
Comments
Post a Comment