DJ's WebGL Tutorial 006--模型加载、显示

来源:互联网 发布:随机森林算法入门 编辑:程序博客网 时间:2024/06/10 23:58

本节将加载并显示一个3D模型,
从渲染方法上讲,和上一节的立方体没有本质区别,只是顶点数据不一样。
立方体是我们自己定义顶点数据,
而3D模型,是从资源文件读取顶点数据,
所以这一节的重点在于数据读取。


从指定url加载文件二进制数据

DataLoader.LoadAsync = function(url, callback, obj) {    var req = new XMLHttpRequest();    req.open("GET", url, true);    req.responseType = 'arraybuffer';    req.onreadystatechange = function() {        if(req.readyState == 4) {            if(req.status == 200 || req.status == 0) {                callback(new DataView(req.response), obj);            } else {                alert('Could not load ' + url + ' (' + req.status + ')');            }        }    };    req.send(null);};

加载mesh文件

Mesh.Load = function(url, onload) {    var m = new Mesh();    m.onload = onload;    DataLoader.LoadAsync(url, on_mesh_data_load, m);    return m;};

读取mesh数据

function on_mesh_data_load(data, mesh) {    var offset = [0];    read_string(data, offset);    var mesh_count = DataLoader.ReadInt32(data, offset);    for(var i=0; i<mesh_count; i++) {        var name = read_string(data, offset);        var position = read_vector3(data, offset);        var rotation = read_quaternion(data, offset);        var scale = read_vector3(data, offset);        var vertex_count = DataLoader.ReadInt32(data, offset);        var vertices = new Float32Array(vertex_count * 3);        for(var j=0; j<vertex_count; j++) {            var v = read_vector3(data, offset);            vertices.set(v, j*3);        }        mesh.vertices = vertices;        var color_count = DataLoader.ReadInt32(data, offset);        var colors = new Float32Array(color_count * 4);        for(var j=0; j<color_count; j++) {            //read color            var v = read_quaternion(data, offset);            colors.set(v, j*4);        }        var uv_count = DataLoader.ReadInt32(data, offset);        var uvs = new Float32Array(uv_count * 2);        for(var j=0; j<uv_count; j++) {            var x = DataLoader.ReadFloat32(data, offset);            var y = 1 - DataLoader.ReadFloat32(data, offset);            uvs.set([x, y], j*2);        }        mesh.uv = uvs;        var uv2_count = DataLoader.ReadInt32(data, offset);        var uv2s = new Float32Array(uv2_count * 2);        for(var j=0; j<uv2_count; j++) {            var x = DataLoader.ReadFloat32(data, offset);            var y = 1 - DataLoader.ReadFloat32(data, offset);            uv2s.set([x, y], j*2);        }        var normal_count = DataLoader.ReadInt32(data, offset);        var normals = new Float32Array(normal_count * 3);        for(var j=0; j<normal_count; j++) {            var v = read_vector3(data, offset);            normals.set(v, j*3);        }        var tangent_count = DataLoader.ReadInt32(data, offset);        var tangents = new Float32Array(tangent_count * 4);        for(var j=0; j<tangent_count; j++) {            //read vector4            var v = read_quaternion(data, offset);            tangents.set(v, j*4);        }        var index_count = DataLoader.ReadInt32(data, offset);        var indices = new Uint16Array(index_count);        for(var j=0; j<index_count; j++) {            var v = DataLoader.ReadUint16(data, offset);            indices[j] = v;        }        mesh.indices = indices;        var submeshs = [];        var submesh_count = DataLoader.ReadInt32(data, offset);        for(var j=0; j<submesh_count; j++) {            var sub_count = DataLoader.ReadInt32(data, offset);            var sub_indices = new Uint16Array(index_count);            for(var k=0; k<sub_count; k++) {                var v = DataLoader.ReadUint16(data, offset);                sub_indices[k] = v;            }            submeshs[j] = sub_indices;        }        break;    }    mesh.loaded = true;    mesh.onload(mesh);};

创建顶点buffer

function create_buffer() {    mesh = Mesh.Load("ranger.mesh", function(m) {        vertex_buffer = gl.createBuffer();        gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(m.vertices), gl.STATIC_DRAW);        uv_buffer = gl.createBuffer();        gl.bindBuffer(gl.ARRAY_BUFFER, uv_buffer);        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(m.uv), gl.STATIC_DRAW);        index_buffer = gl.createBuffer();        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(m.indices), gl.STATIC_DRAW);    });}

初始化:

function init_gl() {    gl.clearColor(0.0, 0.0, 1.0, 1.0);    gl.enable(gl.DEPTH_TEST);    gl.enable(gl.CULL_FACE);    gl.frontFace(gl.CW);    create_shader();    create_buffer();    create_texture();}

这里新加了gl.frontFace(gl.CW)修改三角形正面的顶点顺序为CW顺时针。
因为mesh数据是我从Unity3D导出的,Unity3D引擎使用的顶点顺序是CW,
而gl默认是使用CCW逆时针。


渲染的时候,调整一下模型的位置和角度,其它的和上一节立方体渲染完全一样:

var mat_m = Matrix4x4.TRS([0, -1.1, 0], [0, rot, 0], [1, 1, 1]);

运行结果:


代码下载

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 绿萝中间太密了怎么办 苹果mac密码忘了怎么办 mac锁屏密码忘了怎么办 剑三头发飞起来怎么办 苹果6p开不了机怎么办 苹果6p黑屏了怎么办 肚子胀反胃想吐怎么办 脸上干皮特别多怎么办 月光足还不了款怎么办 孩子不爱和小朋友玩怎么办 不知道怀孕抽烟了怎么办 校园欺凌来了该怎么办 拉的屎是绿色的怎么办 生完孩子痔疮痛怎么办 生过孩子脱肛该怎么办 生完宝宝有痔疮怎么办 毎次大便都脱肛怎么办 怀孕快生了便秘怎么办 35周孕晚期便秘怎么办 怀孕了老公出轨了怎么办 婆婆跟老公睡了怎么办 婆婆和老公互黏怎么办 15岁就掉头发怎么办 24岁经常掉头发怎么办 舍友打游戏太吵怎么办 家里的地砖想换怎么办 墙上的瓷砖掉了怎么办 瓷砖掉了一块瓷怎么办 白色裙子太透了怎么办 剑三石头插错了怎么办 四六级证书丢了怎么办 当月发票冲红了怎么办 当月发票红冲了怎么办 作废的发票扔了怎么办 发票公章盖错了怎么办 发票章盖的模糊怎么办 下的电影没字幕怎么办 荣耀8下载东西慢怎么办 考科目二下大雨怎么办 不求上进的人怎么办 连锁经营投的钱怎么办