The original blog link: https://glumes.com/post/opengl/opengl-tutorial-import-3d-object/

In the use of OpenGL drawing, we draw the most is some simple graphics, such as triangles, circles, cubes, etc., because the number of vertices of these graphics is not much, or you can manually write those vertices, but if drawing some complex graphics how to do?

At this point you can use OpenGL to load the 3D model. Objects are first built using 3D modeling tools, then exported to a specific file format, and finally rendered using OpenGL.

For example, the following 3D model file image:

Obj model file

Obj model file is one of the many 3D model files, its format is relatively simple, essentially is a text file, but the format is fixed format.

Obj files represent vertex coordinates, triangular faces, texture coordinates, and other information as fixed-format text strings.

Excerpt from obj file:

# Max2Obj Version 4.0 Mar 10th, 2001
#
# object (null) to come ...
#
v  0.052045 11.934561 0.071060
v  0.052045 11.728649 1.039199.# 288 vertices
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000. vt1.000000 1.000000 0.000000
# 122 texture vertices
vn 0.000000 0.000000 1.570796
vn 0.000000 0.000000 1.570796. vn0.000000 0.000000 1.570796
# 8 vertex normals
g (null)
f 1/10/1 14/12/11 13/4/11 
f 1/11/4 2/12/3 14/12/11. f5/4/5 7/3/7 3/1/3
# 576 faces
g
Copy the code
  • Lines beginning with “#” indicate comments and can be ignored during loading
  • The lines beginning with “v” are used to hold the vertex coordinates, and the following three numbers represent the x, y, and z coordinates of a vertex as follows:
v  -0.052045 11.934561 -0.071060
Copy the code
  • The line starting with “vt” represents the storage of vertex texture coordinates, and the following three numbers represent the S, T, and P components of texture coordinates. P refers to the depth texture sampling, which is mainly used for 3D texture sampling, but rarely used as follows:
vt 0.000000 0.000000 0.000000
Copy the code
  • The line beginning with “vn” is used to store the vertex normal vector, and the following three numbers represent the x, y, and z components of a vertex’s normal vector. Such as:
vn 0.000000 0.000000 1.570796
Copy the code
  • The line beginning with “G” indicates the beginning of a group, followed by the string name of the group. A group is a set of faces made up of vertices, and rows containing only “G” indicate the end of the group, corresponding to rows starting with “G”.
  • The lines beginning with “f” represent one face in the group, and in the case of triangle figures are followed by three groups of space-separated data representing the three vertices of the triangle. Each set of data contains 3 values, using/Delimited, represented in turnIndex of vertex coordinate data,Vertex texture coordinate data index,Vertex normal vector data index, the index refers to the coordinate corresponding to a specific row, such as:
f 1/10/1 14/12/11 13/4/12 
Copy the code

The data above represents three vertices, of which three vertex coordinates of the triangle are from lines 1, 14, 13 starting with “V”, three vertex texture coordinates are from lines 10, 12, 4 starting with “vt”, and three vertex normal vectors are from lines 1, 11, 12 starting with “vn”.

If the vertex coordinates do not have normal and texture coordinates, they can be ignored by separating the three vertex coordinates with Spaces

f 1 3 4
Copy the code

Finally, OpenGL uses GL_TRIANGLES, using triangles ABC and DEF using six points ABCDEF. Therefore, the lines starting with “f” represent an independent triangle. The final image is made up of triangles joined together, and the points can be separated.

Load the Obj model file

Now that you understand what the Obj model file represents, load it and render it in OpenGL.

The Obj model file is essentially a text file, which can be loaded by reading each line. Assuming that the loaded model file only has vertex coordinates, the actual code is as follows:

		// Load all vertex coordinates as the index of the List
        ArrayList<Float> alv = new ArrayList<>();
        // represents the coordinates of each small triangle used to draw the image
        ArrayList<Float> alvResult = new ArrayList<>();
        // The final array to pass into OpenGL
        float[] vXYZ;
        try {
            InputStream in = context.getResources().getAssets().open(fname);
            InputStreamReader isr = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(isr);
            String temps = null;
			// Iterate over each line to read the contents
            while((temps = br.readLine()) ! =null) {
	            // Regular expressions are separated by Spaces
                String[] tempsa = temps.split("[the] +");
                // Add all the vertex coordinates to the List first, so that there is an index
                if (tempsa[0].trim().equals("v")) {
                    alv.add(Float.parseFloat(tempsa[1]));
                    alv.add(Float.parseFloat(tempsa[2]));
                    alv.add(Float.parseFloat(tempsa[3]));
                } else if (tempsa[0].trim().equals("f")) {
                // Find the corresponding vertex coordinates according to the index indicated by f,
                // The -1 operation here is because the List starts at 0 and the index of the f line starts at 1
                // *3 because multiples of 3 are skipped
                    int index = Integer.parseInt(tempsa[1].split("/") [0]) - 1;
                    alvResult.add(alv.get(3 * index));
                    alvResult.add(alv.get(3 * index + 1));
                    alvResult.add(alv.get(3 * index + 2));

                    index = Integer.parseInt(tempsa[2].split("/") [0]) - 1;
                    alvResult.add(alv.get(3 * index));
                    alvResult.add(alv.get(3 * index + 1));
                    alvResult.add(alv.get(3 * index + 2));

                    index = Integer.parseInt(tempsa[3].split("/") [0]) - 1;
                    alvResult.add(alv.get((3 * index)));
                    alvResult.add(alv.get((3 * index + 1)));
                    alvResult.add(alv.get((3 * index + 2))); }}// Convert the coordinates of the faces to the array that will eventually be passed to OpenGL
            // Use this array, and say say, Using GL_TRIANGLES
            int size = alvResult.size();
            vXYZ = new float[size];
            for (int i = 0; i < size; i++) {
                vXYZ[i] = alvResult.get(i);
            }
            return vXYZ;
        } catch (IOException e) {
            return null;
        }
Copy the code

Using the above function, we can calculate the final vertex coordinate position, and pass this vertex coordinate position to the GPU, which is converted by FloatBuffer, etc. This is the same as the previous article.

If you simply import all the vertices and decide what color to draw, you will have a situation similar to the single color above, and you can actually modify the fragment shader to add a stripe color effect to the 3D model.

Add a stripe shader effect using shaders

Add stripe effects to 3D shapes by modifying fragment shaders.

precision mediump float;
varying  vec3 vPosition;  // Vertex position
void main() {
   vec4 bColor=vec4(0.678.0.231.0.129.0);// The stripe color
   vec4 mColor=vec4(0.763.0.657.0.614.0);// The spacing color
   float y=vPosition.y;
   y=mod((y+100.0) *4.0.4.0);
   if(y>1.8) {
     gl_FragColor = bColor;// Give this element a color value
   } else {
     gl_FragColor = mColor;// Give this element a color value
   }
// Use a single color by default
// vec4 white = vec4(1,1,1,1);
// gl_FragColor = white;
}
Copy the code

The way to do this is to determine whether the segment is the color of the sampling fringe or the color of the interval based on the y-coordinate position of the segment.

If you want to load more effects, you can dig deeper, but without the MAC version of 3ds Max, it’s a little less fun

Specific code details, can refer to my Github project, for a wave of star~~

Github.com/glumes/Andr…

Welcome to pay attention to wechat public number: [paper talk], get the latest article push ~~