As of now, my code supports loading an .obj (wavefront) file and translating it into a WebGL object (GL buffers and a render function). However, I can only map one texture to the entire object right now.
My file loader reads line by line, and currently ignores the usemtl
lines of the .obj files. My object render function looks like this (adapted from the http://learningwebgl.com/blog/?page_id=1217 tutorials) - not perfect yet, but for the sake of completeness I posted the whole working function:
this.render = function(gl){
// push identity to the matrix stack (to apply changes only to this object)
mvPushMatrix();
// apply translations
mat4.translate(mvMatrix, [this.transX, this.transY, this.transZ]);
// apply scaling
mat4.scale(mvMatrix, [this.scaleX, this.scaleY, this.scaleZ]);
// apply rotations
mat4.rotate(mvMatrix, this.rotX, [1, 0, 0]);
mat4.rotate(mvMatrix, this.rotY, [0, 1, 0]);
mat4.rotate(mvMatrix, this.rotZ, [0, 0, 1]);
// load position buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
this.positionVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load normals buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.normalVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
this.normalVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load texture buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureVertexBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute,
this.textureVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load and apply the texture
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.uniform1i(shaderProgram.samplerUniform, 0);
// if blending is turned on, apply the blending and alpha value
if(this.blending || this.firstRun){
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
gl.uniform1f(shaderProgram.alphaUniform, this.alpha);
}
// otherwise, disable blending mode and render normally
else{
gl.disable(gl.BLEND);
gl.enable(gl.DEPTH_TEST);
gl.uniform1f(shaderProgram.alphaUniform, 1.0);
}
// render with indices IF indices are enabled
if(this.indicesEnabled){
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexVertexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES,
this.indexVertexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
}
// otherwise, render normally
else {
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, this.textureVertexBuffer.numItems);
}
// pop the matrix stack
mvPopMatrix();
// unflag first run after first frame rendering
this.firstRun = false;
}
What I would like to do is read in files that use multiple textures. How can I do this? My initial assumption is to read in all of the faces of one texture from the .obj, and once the texture changes, start reading a separate buffer, and then just split the object into multiple pieces (one piece per texture) and render them as if they were separate objects. But before I change my code, I wanted to see if this was correct, or if there is a particularly good way of approaching this issue?
To be honest, I'm not sure how to go about this at all. Any suggestions? Thank you.