Def*_*yke 8 python opengl json blender webgl
我正在为Blender 2.6x制作一个简单的导出器,用于自定义JSON格式(主要用于WebGL),因为我在网上找到的现有版本不适用于Blender 2.6.
我差点搞定了,但还有一个我无法弄清楚的错误.在一个简单的立方体上,其一侧的纹理方向错误.立方体的其余部分纹理正确.
您可以在此处看到问题的图片(左侧的左侧面朝向错误,与右侧的正确立方体相比):

是否存在一些可能导致此行为发生的常见误解或错误?
这是从Blender 2.65导出到我的自定义JSON格式的函数(错误必须在这里,但我找不到它):
def get_json(objects, scene):
    """ Currently only supports one scene. 
        Exports with -Z forward, Y up. """
    object_number = -1
    scene_data = []
    # for every object in the scene
    for object in bpy.context.scene.objects:
        # if the object is a mesh       
        if object.type == 'MESH':
            object_number += 1
            # convert all the mesh's faces to triangles
            bpy.ops.object.mode_set(mode='OBJECT')
            object.select = True
            bpy.context.scene.objects.active = object
            # triangulate using new Blender 2.65 Triangulate modifier
            bpy.ops.object.modifier_add(type='TRIANGULATE')
            object.modifiers["Triangulate"].use_beauty = False
            bpy.ops.object.modifier_apply(apply_as="DATA", modifier="Triangulate")
            bpy.ops.object.mode_set(mode='OBJECT')
            object.select = False
            # add data to scene_data structure
            scene_data.append({
                "name"          : object.name,
                "vertices"      : [],
                "indices"       : [],
                "normals"       : [],
                "tex_coords"    : []
            })
            vertex_number = -1
            # for each face in the object
            for face in object.data.polygons:
                vertices_in_face = face.vertices[:]
                # for each vertex in the face
                for vertex in vertices_in_face:
                    vertex_number += 1
                    # store vertices in scene_data structure
                    scene_data[object_number]["vertices"].append( object.data.vertices[vertex].co.x + object.location.x )
                    scene_data[object_number]["vertices"].append( object.data.vertices[vertex].co.z + object.location.z )
                    scene_data[object_number]["vertices"].append( -(object.data.vertices[vertex].co.y + object.location.y) )
                    # store normals in scene_data structure
                    scene_data[object_number]["normals"].append( object.data.vertices[vertex].normal.x )
                    scene_data[object_number]["normals"].append( object.data.vertices[vertex].normal.z )
                    scene_data[object_number]["normals"].append( -(object.data.vertices[vertex].normal.y) )
                    # store indices in scene_data structure
                    scene_data[object_number]["indices"].append(vertex_number)
            # texture coordinates
            #   bug: for a simple cube, one face's texture is warped
            mesh = object.to_mesh(bpy.context.scene, True, 'PREVIEW')
            if len(mesh.tessface_uv_textures) > 0:
                for data in mesh.tessface_uv_textures.active.data:
                    scene_data[object_number]["tex_coords"].append( data.uv1.x )
                    scene_data[object_number]["tex_coords"].append( data.uv1.y )
                    scene_data[object_number]["tex_coords"].append( data.uv2.x )
                    scene_data[object_number]["tex_coords"].append( data.uv2.y )
                    scene_data[object_number]["tex_coords"].append( data.uv3.x )
                    scene_data[object_number]["tex_coords"].append( data.uv3.y )
    return json.dumps(scene_data, indent=4)
Run Code Online (Sandbox Code Playgroud)
And in case this would help figure it out, here's the exported JSON data that results from running my export script (the same data used to render the cube on the left in the image above):
[
    {
        "vertices": [
            -1.0203653573989868, 
            1.0320179611444473, 
            0.669445663690567, 
            -1.0203653573989868, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            0.669445663690567, 
            -1.0203653573989868, 
            1.0320179611444473, 
            -1.330554336309433, 
            0.9796346426010132, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            1.0320179611444473, 
            -1.330554336309433, 
            0.9796346426010132, 
            1.0320179611444473, 
            0.669445663690567, 
            0.9796346426010132, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            1.0320179611444473, 
            0.669445663690567, 
            -1.0203653573989868, 
            1.0320179611444473, 
            0.669445663690567, 
            0.9796346426010132, 
            -0.9679820388555527, 
            0.669445663690567, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            0.669445663690567, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            -0.9679820388555527, 
            0.669445663690567, 
            0.9796346426010132, 
            1.0320179611444473, 
            0.669445663690567, 
            0.9796346426010132, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            1.0320179611444473, 
            0.669445663690567, 
            -1.0203653573989868, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            -1.330554336309433, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            0.669445663690567, 
            0.9796346426010132, 
            1.0320179611444473, 
            -1.330554336309433, 
            0.9796346426010132, 
            -0.9679820388555527, 
            -1.330554336309433, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            1.0320179611444473, 
            0.669445663690567, 
            0.9796346426010132, 
            -0.9679820388555527, 
            0.669445663690567, 
            0.9796346426010132, 
            -0.9679820388555527, 
            -1.330554336309433, 
            -1.0203653573989868, 
            1.0320179611444473, 
            0.669445663690567, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            0.669445663690567, 
            0.9796346426010132, 
            -0.9679820388555527, 
            0.669445663690567, 
            -1.0203653573989868, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            -0.9679820388555527, 
            -1.330554336309433, 
            0.9796346426010132, 
            -0.9679820388555527, 
            0.669445663690567, 
            0.9796346426010132, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            1.0320179611444473, 
            -1.330554336309433, 
            -1.0203653573989868, 
            1.0320179611444473, 
            0.669445663690567
        ], 
        "normals": [
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            -0.5773491859436035, 
            -0.5773491859436035, 
            0.5773491859436035, 
            0.5773491859436035
        ], 
        "indices": [
            0, 
            1, 
            2, 
            3, 
            4, 
            5, 
            6, 
            7, 
            8, 
            9, 
            10, 
            11, 
            12, 
            13, 
            14, 
            15, 
            16, 
            17, 
            18, 
            19, 
            20, 
            21, 
            22, 
            23, 
            24, 
            25, 
            26, 
            27, 
            28, 
            29, 
            30, 
            31, 
            32, 
            33, 
            34, 
            35
        ], 
        "name": "Cube", 
        "tex_coords": [
            0.008884529583156109, 
            0.6587533354759216, 
            0.3244488537311554, 
            0.3412468135356903, 
            0.32541996240615845, 
            0.657782256603241, 
            0.008884510956704617, 
            0.32541996240615845, 
            0.007913422770798206, 
            0.008884549140930176, 
            0.32541996240615845, 
            0.3244488537311554, 
            0.9920865893363953, 
            0.32444891333580017, 
            0.675551176071167, 
            0.32541996240615845, 
            0.9911155700683594, 
            0.00791349820792675, 
            0.3412467837333679, 
            0.008884538896381855, 
            0.6577821969985962, 
            0.007913422770798206, 
            0.34221789240837097, 
            0.32541996240615845, 
            0.6587532758712769, 
            0.6577821969985962, 
            0.3422178626060486, 
            0.6587533354759216, 
            0.6577821373939514, 
            0.3412468135356903, 
            0.6745801568031311, 
            0.34221789240837097, 
            0.9911155700683594, 
            0.3412468135356903, 
            0.6755512356758118, 
            0.6587533354759216, 
            0.007913460955023766, 
            0.34221789240837097, 
            0.3244488537311554, 
            0.3412468135356903, 
            0.008884529583156109, 
            0.6587533354759216, 
            0.007913422770798206, 
            0.008884549140930176, 
            0.324448823928833, 
            0.007913422770798206, 
            0.32541996240615845, 
            0.3244488537311554, 
            0.675551176071167, 
            0.32541996240615845, 
            0.6745801568031311, 
            0.008884529583156109, 
            0.9911155700683594, 
            0.00791349820792675, 
            0.6577821969985962, 
            0.007913422770798206, 
            0.6587533354759216, 
            0.3244488835334778, 
            0.34221789240837097, 
            0.32541996240615845, 
            0.3422178626060486, 
            0.6587533354759216, 
            0.3412467837333679, 
            0.34221789240837097, 
            0.6577821373939514, 
            0.3412468135356903, 
            0.9911155700683594, 
            0.3412468135356903, 
            0.99208664894104, 
            0.6577821969985962, 
            0.6755512356758118, 
            0.6587533354759216
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)
I'm not currently looking for ways to make a better more feature filled, or more efficient exporter, rather I would just like to finally squash this bug so I can get on to more interesting things, like making a WebGL game, and learning about collision detection and such. Any help or advise in regards to this problem I'm having would be greatly appreciated!
Edit:
In case it might be my rendering code, and not the exporter that's the problem, here is the part of my WebGL code related to initializing the buffers and drawing the scene (a modified version of some code found at http://learningwebgl.com):
var gl;
var current_shader_program;
var per_vertex_shader_program;
var per_fragment_shader_program;
var modelview_matrix = mat4.create();
var modelview_matrix_stack = [];
var projection_matrix = mat4.create();
var teapot_vertex_position_buffer = new Array();
var teapot_vertex_tex_coord_buffer = new Array();
var teapot_vertex_normal_buffer = new Array();
var teapot_vertex_index_buffer = new Array();
var earth_texture;
var galvanized_texture;
var teapot_angle = 180;
var last_time = 0;
function createProgram(vertex_shader_filename, fragment_shader_filename) {
    var vertex_shader_text = readFromUrl(vertex_shader_filename);
    var fragment_shader_text = readFromUrl(fragment_shader_filename);
    var vertex_shader = gl.createShader(gl.VERTEX_SHADER);
    var fragment_shader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(vertex_shader, vertex_shader_text);
    gl.shaderSource(fragment_shader, fragment_shader_text);
    gl.compileShader(vertex_shader);
    if (!gl.getShaderParameter(vertex_shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(vertex_shader));
    }
    gl.compileShader(fragment_shader);
    if (!gl.getShaderParameter(fragment_shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(fragment_shader));
    }
    var shader_program = gl.createProgram();
    gl.attachShader(shader_program, vertex_shader);
    gl.attachShader(shader_program, fragment_shader);
    gl.linkProgram(shader_program);
    if (!gl.getProgramParameter(shader_program, gl.LINK_STATUS)) {
        alert("Error: Unable to link shaders!");
    }
    shader_program.vertex_position_attribute = 
        gl.getAttribLocation(shader_program, "a_vertex_position");
    gl.enableVertexAttribArray(shader_program.vertex_position_attribute);
    shader_program.vertex_normal_attribute =
        gl.getAttribLocation(shader_program, "a_vertex_normal");
    gl.enableVertexAttribArray(shader_program.vertex_normal_attribute);
    shader_program.tex_coord_attribute = 
        gl.getAttribLocation(shader_program, "a_tex_coord");
    gl.enableVertexAttribArray(shader_program.tex_coord_attribute);
    shader_program.projection_matrix_uniform = 
        gl.getUniformLocation(shader_program, "u_projection_matrix");
    shader_program.modelview_matrix_uniform = 
        gl.getUniformLocation(shader_program, "u_modelview_matrix");
    shader_program.normal_matrix_uniform =
        gl.getUniformLocation(shader_program, "u_normal_matrix");
    shader_program.sampler_uniform = 
        gl.getUniformLocation(shader_program, "u_sampler");
    shader_program.material_shininess_uniform = 
        gl.getUniformLocation(shader_program, "u_material_shininess");
    shader_program.show_specular_highlights_uniform = 
        gl.getUniformLocation(shader_program, "u_show_specular_highlights");
    shader_program.use_textures_uniform =
        gl.getUniformLocation(shader_program, "u_use_textures");
    shader_program.use_lighting_uniform =
        gl.getUniformLocation(shader_program, "u_use_lighting");
    shader_program.ambient_color_uniform =
        gl.getUniformLocation(shader_program, "u_ambient_color");
    shader_program.point_lighting_location_uniform = 
        gl.getUniformLocation(shader_program, "u_point_lighting_location");
    shader_program.point_lighting_specular_color_uniform =
        gl.getUniformLocation(shader_program, "u_point_lighting_specular_color");
    shader_program.point_lighting_diffuse_color_uniform =
        gl.getUniformLocation(shader_program, "u_point_lighting_diffuse_color");
    return shader_program;
}
function initShaders() {
    per_fragment_shader_program = createProgram("per_fragment_lighting.vs", "per_fragment_lighting.fs");
}
function handleLoadedTexture(texture) {
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
        texture.image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.bindTexture(gl.TEXTURE_2D, null);
}
function initTextures() {
    earth_texture = gl.createTexture();
    earth_texture.image = new Image();
    earth_texture.image.onload = function() {
        handleLoadedTexture(earth_texture);
    }
    earth_texture.image.src = "earth.jpg";
    galvanized_texture = gl.createTexture();
    galvanized_texture.image = new Image();
    galvanized_texture.image.onload = function() {
        handleLoadedTexture(galvanized_texture);
    };
    galvanized_texture.image.src = "galvanized.jpg";
}
function setMatrixUniforms() {
    gl.uniformMatrix4fv(current_shader_program.projection_matrix_uniform, false, 
        projection_matrix);
    gl.uniformMatrix4fv(current_shader_program.modelview_matrix_uniform, false, 
        modelview_matrix);
    var normal_matrix = mat3.create();
    mat4.toInverseMat3(modelview_matrix, normal_matrix);
    mat3.transpose(normal_matrix);
    gl.uniformMatrix3fv(current_shader_program.normal_matrix_uniform, false, 
        normal_matrix);
}
function handleLoadedTeapot(teapot_data) {
    for (var i = 0; i < teapot_data.length; i++)
    {
        teapot_vertex_normal_buffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_normal_buffer[i]);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapot_data[i].normals), 
            gl.STATIC_DRAW);
        teapot_vertex_normal_buffer[i].item_size = 3;
        teapot_vertex_normal_buffer[i].num_items = 
            teapot_data[i].normals.length / teapot_vertex_normal_buffer[i].item_size;
        teapot_vertex_tex_coord_buffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_tex_coord_buffer[i]);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapot_data[i].tex_coords), 
            gl.STATIC_DRAW);
        teapot_vertex_tex_coord_buffer[i].item_size = 2;
        teapot_vertex_tex_coord_buffer[i].num_items = 
            teapot_data[i].tex_coords.length / teapot_vertex_tex_coord_buffer[i].item_size;
        teapot_vertex_position_buffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_position_buffer[i]);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(teapot_data[i].vertices), 
            gl.STATIC_DRAW);
        teapot_vertex_position_buffer[i].item_size = 3;
        teapot_vertex_position_buffer[i].num_items = 
            teapot_data[i].vertices.length / teapot_vertex_position_buffer[i].item_size;
        teapot_vertex_index_buffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, teapot_vertex_index_buffer[i]);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(teapot_data[i].indices), 
            gl.STATIC_DRAW)
        teapot_vertex_index_buffer[i].item_size = 1;
        teapot_vertex_index_buffer[i].num_items = 
            teapot_data[i].indices.length / teapot_vertex_index_buffer[i].item_size;
    }
    document.getElementById("loading_text").textContent = "";
}
function loadTeapot() {
    var request = new XMLHttpRequest();
    request.open("GET", "untitled.json");
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            handleLoadedTeapot(JSON.parse(request.responseText));
        }
    };
    request.send();
}
function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    if (teapot_vertex_position_buffer[0] == null    || 
        teapot_vertex_normal_buffer[0] == null      || 
        teapot_vertex_tex_coord_buffer[0] == null   || 
        teapot_vertex_index_buffer[0] == null) {
        return;
    }
    current_shader_program = per_fragment_shader_program;
    gl.useProgram(current_shader_program);
    var specular_highlights = document.getElementById("specular").checked;
    gl.uniform1i(current_shader_program.show_specular_highlights_uniform, specular_highlights);
    var lighting = document.getElementById("lighting").checked;
    gl.uniform1i(current_shader_program.use_lighting_uniform, lighting);
    if (lighting) {
        gl.uniform3f(current_shader_program.ambient_color_uniform,
            parseFloat(document.getElementById("ambient_r").value),
            parseFloat(document.getElementById("ambient_g").value),
            parseFloat(document.getElementById("ambient_b").value));
        gl.uniform3f(current_shader_program.point_lighting_location_uniform,
            parseFloat(document.getElementById("light_pos_x").value),
            parseFloat(document.getElementById("light_pos_y").value),
            parseFloat(document.getElementById("light_pos_z").value));
        gl.uniform3f(current_shader_program.point_lighting_specular_color_uniform,
            parseFloat(document.getElementById("specular_r").value),
            parseFloat(document.getElementById("specular_g").value),
            parseFloat(document.getElementById("specular_b").value));
        gl.uniform3f(current_shader_program.point_lighting_diffuse_color_uniform,
            parseFloat(document.getElementById("diffuse_r").value),
            parseFloat(document.getElementById("diffuse_g").value),
            parseFloat(document.getElementById("diffuse_b").value));
    }
    var texture = document.getElementById("texture").value;
    gl.uniform1i(current_shader_program.use_textures_uniform, texture != "none");
    mat4.identity(modelview_matrix);
    mat4.translate(modelview_matrix, [0, 0, -10]);
    mat4.rotate(modelview_matrix, degToRad(23.4), [1, 0, 0]);
    mat4.rotate(modelview_matrix, degToRad(teapot_angle), [0, 1, 0]);
    gl.activeTexture(gl.TEXTURE0);
    if (texture == "earth") {
        gl.bindTexture(gl.TEXTURE_2D, earth_texture);
    }
    else if (texture == "galvanized") {
        gl.bindTexture(gl.TEXTURE_2D, galvanized_texture);
    }
    gl.uniform1i(current_shader_program.sampler_uniform, 0);
    gl.uniform1f(current_shader_program.material_shininess_uniform, 
        parseFloat(document.getElementById("shininess").value));
    for (var i = 0; i < teapot_vertex_position_buffer.length; i++)
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_position_buffer[i]);
        gl.vertexAttribPointer(current_shader_program.vertex_position_attribute,
            teapot_vertex_position_buffer[i].item_size, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_tex_coord_buffer[i]);
        gl.vertexAttribPointer(current_shader_program.tex_coord_attribute,
            teapot_vertex_tex_coord_buffer[i].item_size, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, teapot_vertex_normal_buffer[i]);
        gl.vertexAttribPointer(current_shader_program.vertex_normal_attribute,
            teapot_vertex_normal_buffer[i].item_size, gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, teapot_vertex_index_buffer[i]);
        setMatrixUniforms();
        gl.drawElements(gl.TRIANGLES, teapot_vertex_index_buffer[i].num_items, 
            gl.UNSIGNED_SHORT, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个很难看的东西,这就是为什么我之前没有发布它,但有人提出渲染代码可能有问题.请注意,代码中提到的"茶壶"实际上是导出的模型(我正在尝试渲染的多维数据集).