[Ityran Original]iphone medium OpenGL ES display 3DS max model two: LIB3DS load model
U0u0-ityran
In the previous section, we analyzed the obj format.
The advantages of the obj format are textual, readable, and obvious, and the computer parsing the text process is much slower than parsing the binary file. One problem with obj is that the layout formats exported by various 3D modeling tools are not the same, and face has polygons (more than three-sided), which is not conducive to loading in OpenGL es.
The. 3ds file is a binary form of obj and much more information. There is a C language written in the open source library can be used to add. 3ds files, this is lib3ds. The license of the GPL may not be ideal for direct use in commercial applications. This does not hinder our analysis of this article.
Tutorial:
The demo inherits from my other tutorial: Xcode creates the default iOS OpenGL ES 2.0 Project Code Analysis
Openglstart, remove the Glkit shader code, add lib3ds and load the display.
Project: http://ityran.com/thread-765-1-1.html
Principle
I used Google SketchUp to build a simple triangular cone and box, exported as TRIANGLE.3DS and SQUARE.3DS, respectively. To show the model in OpenGL ES, we need two basic information about the model: vertex coordinates and vertex normals.
The. 3ds file holds vertex coordinates, and face sequences, while vertex normals require self-calculation.
The LIB3DS provides an interface to read vertex coordinates and face sequences, and provides an interface to compute vertex normals.
All we have to do is read this data and convert it into the data form that OpenGL ES accepts.
tt3ds Load Class
To facilitate loading the model, my LIB3DS interface is encapsulated within a class.
This class is responsible for loading parsing. 3DS and converting it to OpenGL ES accepted data.
Note: A. 3ds may contain more than one model, TT3DS can only process a single file.
First look at the TT3ds.h file.
#import #import
#import "Lib3ds.h"
@interface tt3ds:nsobject { char*name;//model name & nbsp gluintnvertices;//vertices glsizeiptrverticessize ;//vertex array size glfloat*vertices;//vertex array pointer gluintnfaces;//The number of faces glsizeiptrfacessize;/ /Polygon Data size glubyte*faces;//polygon data pointer  //VBO Related data definition, OpenGL ES accept data GLuintvertexArray; GLuintvertexArrayBuffer; gluintvertexelementbuffer; glenumerror;} -(ID) Initwithfilename: (NSString *) filename;-(void) bindvertexarray;-(void) draw;
@end
Three interfaces, Initwithfilename is obviously used for initialization, using the following:
Testobject = [[tt3ds alloc]initwithfilename:@ "triangle"];
The parameter is triangle and not triangle.3ds,oftype specifies that only 3DS files are recognized.
NSString *dspathname = [[NSBundle mainbundle]pathforresource:filename oftype:@ "3DS"];
The following 2 interfaces are for the OpenGL ES framework
-(void) Glkview: (Glkview *) Viewdrawinrect: (cgrect) rect
Called by the.
LIB3DS documentation is quite small, only the code inside the demo can refer to.
The entire process is referenced by 3ds2obj, the demo code.
The Lib3dsfile returned by Lib3ds_file_open contains a node series.
Find the NODE with the Lib3ds_node_mesh_instance attribute in the sequence,
A lib3ds_node_mesh_instance NODE is a model.
A. 3DS can contain multiple models.
The Parsemeshnode function converts 3DS data to VBO data.
The VBO data organization looks like this:
The VBO code for this is as follows:
glgenvertexarraysoes (1, &vertexarray); Glbindvertexarrayoes (Vertexarray);
Glgenbuffers (1, &vertexarraybuffer); Glbindbuffer (Gl_array_buffer, Vertexarraybuffer); GlBufferData (GL_ARRAY_ BUFFER, Verticessize, Vertices,gl_static_draw); Glenablevertexattribarray (glkvertexattribposition); Glvertexattribpointer (Glkvertexattribposition, 3,gl_float, Gl_false,
sizeof (GL FLOAT) * 3, Buffer_offset (0)); Glenablevertexattribarray (Glkvertexattribnormal); Glvertexattribpointer ( Glkvertexattribnormal, 3,gl_float, Gl_false, sizeof (glfloat ) * 3, Buffer_offset (VERTICESSIZE/2));
Glgenbuffers (1, &vertexelementbuffer); Glbindbuffer (Gl_element_array_buffer,vertexelementbuffer); Glbufferdata (Gl_element_array_buffer, facessize,faces, Gl_static_draw);
Glbindvertexarrayoes (0);
Bindvertexarray
Before calling Gldrawelements to display the model, we need to tell OpenGL to use that data to display it.
Bindvertexarray is a method of tt3ds that is called in TTVIEWCONTROLLER.M and is currently encapsulated to avoid returning a vertexarray pointer to the outside.
-(void) Bindvertexarray {glbindvertexarrayoes (vertexarray);}
Draw
Since the. 3ds file provides a face sequence, it is necessary to use gldrawelements to display the model instead of gldrawarrays.
We have set the element information through VBO, and the Tt3ds draw method is as follows:
-(void) Draw {gldrawelements (gl_triangles,facessize, gl_unsigned_byte, 0);}
Gldrawelements the 4th parameter is set to 0 instead of faces, here are two uses of gldrawelements: one is set directly here as the faces pointer, and the other is to set the element information in the VBO in advance, The 4th parameter is set to 0 when gldrawelements.
TTVIEWCONTROLLER.M the load display model in
The first step is to initialize the model in SETUPGL
Glenable (gl_depth_test); testobject = [[tt3ds alloc]initwithfilename:@ "triangle"];
Then modify the draw-related code in the Red section.
-(void) Glkview: (Glkview *) Viewdrawinrect: (cgrect) rect{ glclearcolor (0.65f, 0.65f, 0.65f, 1.0f); glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit); //glbindvertexarrayoes (_vertexarray ); [Testobject Bindvertexarray]; //Renderthe object again with es2 gluseprogram (_program);  GLUNIFORMM ATRIX4FV (Uniforms[uniform_modelviewprojection_matrix], 1, 0,
_MODELVIEWPROJECTIONMATRIX.M);  GLUNIFORMMATRIX3FV (Uniforms[uniform_normal_matrix], 1, 0,_norm ALMATRIX.M); //gldrawelements (gl_triangles,sizeof (gfaces)
/sizeof (Glubyte), Gl_unsigned_byte, 0); [Testobject draw]; }
Try the next project and you'll see the beginning of the article.
Conclusion:
TT3DS function is not perfect, do not deal with the situation of multi-model, no optimization data, no exception processing, the correctness of the calculation of vertex normals I do not guarantee that the display color of the cube is a bit wrong.
I think the direct use of LIB3DS in the project may not be ideal,. 3DS data has not been optimized, too many duplicate point data. The ideal way is: People lib3ds write a PC-side tool, convert. 3DS is another optimized data format, and then put the optimized data directly into OpenGL, so that the efficiency of high memory consumption is also small.
[Ityran original]iphone in OpenGL ES display 3DS max model two: LIB3DS load model