VBO´s multitexturing

Hi everyone!

I have a problem. I use .obj models of Blender. I loads data of file this:

 public static Model LoadModel(String cesta){
        Model model = new Model();
        BufferedReader bf = null;
        material = null;
        
         try{
            bf = new BufferedReader(new FileReader(new File(cesta)));
            String radek;
            
            while((radek=bf.readLine()) != null){
                
                //Označení pro vrcholy
                if(radek.startsWith("v ")){
                    float x = Float.valueOf(radek.split(" ")[1]);
                    float y = Float.valueOf(radek.split(" ")[2]);
                    float z = Float.valueOf(radek.split(" ")[3]);
                    pocet++;
                    model.vertices.add(new Vector3f(x,y,z));
                    
                //Označení normál
                }else if(radek.startsWith("vn ")){
                    float x = Float.valueOf(radek.split(" ")[1]);
                    float y = Float.valueOf(radek.split(" ")[2]);
                    float z = Float.valueOf(radek.split(" ")[3]);
                    model.normals.add(new Vector3f(x,y,z));
                    
                //Označení sořadnic textur
                }else if(radek.startsWith("vt ")){
                    float x = Float.valueOf(radek.split(" ")[1]);
                    float y = Float.valueOf(radek.split(" ")[2]);
                    
                    model.textures.add(new Vector2f(x,y)); 
                    model.isTextured = true;
                    
                //Ozačení pro ploch stran
                }else if(radek.startsWith("f ")){
                    Vector3f verI = new Vector3f(
                            Float.valueOf(radek.split(" ")[1].split("/")[0]),
                            Float.valueOf(radek.split(" ")[2].split("/")[0]),
                            Float.valueOf(radek.split(" ")[3].split("/")[0]));
                    
                    Vector3f normI = new Vector3f(
                            Float.valueOf(radek.split(" ")[1].split("/")[2]),
                            Float.valueOf(radek.split(" ")[2].split("/")[2]),
                            Float.valueOf(radek.split(" ")[3].split("/")[2]));
                    
                   if(model.isTextured){                  
                    Vector3f textures = new Vector3f(
                            Float.valueOf(radek.split(" ") [1].split("/")[1]), 
                            Float.valueOf(radek.split(" ")[2].split("/")[1]), 
                            Float.valueOf(radek.split(" ")[3].split("/")[1]));
                    
                            model.faces.add(new Face(verI, normI, textures, material));                  
                   }else
                   {
                       model.faces.add(new Face(verI, normI, null, material));
                   }
                    
                    
                }else if(radek.startsWith("mtllib ")){
                    setMaterial(model, cesta.split("/")[0]+"/"+radek.split(" ")[1]);
                }else if(radek.startsWith("usemtl")){
                    material = model.materials.get(radek.split(" ")[1]);
                }      
            }
            bf.close();
            
        } catch(FileNotFoundException e){
            System.out.println(e);
        } catch(IOException e){
            e.printStackTrace();
        }

        modely.add(model);
        
        return model;
    } 
    
    public static void setMaterial(Model m, String cesta){
        material = null;
        BufferedReader bf = null;
        
        String radek = null;
        
       try{
        bf = new BufferedReader(new FileReader(new File(cesta)));
           
        while((radek = bf.readLine()) != null){  
            if(radek.startsWith("newmtl ")){
                if(material != null){                  
                    m.materials.put(material.getPath(), material);
                }
                
                material = new Material(radek.split(" ")[1]);
            }else if(radek.startsWith("Kd ")){
                float r = Float.valueOf(radek.split(" ")[1]);
                float g = Float.valueOf(radek.split(" ")[2]);
                float b = Float.valueOf(radek.split(" ")[3]);

                material.setDiffuse(new Vector3f(r, g, b));
                
            }else if(radek.startsWith("map_Kd ")){
                String c = radek.replace("\\","/");
                System.out.println(cesta.split("/")[0]+"/"+c.split(" ")[1]);
                //m.text = Texture2.loadTexture(cesta.split("/")[0]+"/"+c.split(" ")[1]);
                m.text.add(Texture2.loadTexture(cesta.split("/")[0]+"/"+c.split(" ")[1]));
                //m.text.add(TextureLoader.getTexture("JPG", new FileInputStream(new File(cesta.split("/")[0]+"/"+c.split(" ")[1]))));
            } 
            
        }
        
        m.materials.put(material.getPath(),material);
        
        bf.close();
        
       } catch(FileNotFoundException e){
            System.out.println(e);
        } catch(IOException e){
            e.printStackTrace();
        }
    }

All is correct but if I render object, which has several textures so it renders only one of texture.
Any idea how to do it?

Init code:

   FloatBuffer norm = reserveData(faces.size() * 9);
        FloatBuffer vert = reserveData(faces.size() * 9);
        FloatBuffer tex = reserveData(faces.size() * 6);
        FloatBuffer col = reserveData(faces.size() * 9);
        

        for (Face face : faces) {    //Cyklus foreach, který prochází celý List 
            
            Material material = face.material;
            
            System.out.println(material);
            
            vert.put(asFloats3f(vertices.get((int) face.vertex.x - 1)));
            vert.put(asFloats3f(vertices.get((int) face.vertex.y - 1)));
            vert.put(asFloats3f(vertices.get((int) face.vertex.z - 1)));
            col.put(material.getDiffuse().x).put(material.getDiffuse().y).put(material.getDiffuse().z);

            norm.put(asFloats3f(normals.get((int) face.normal.x - 1)));
            norm.put(asFloats3f(normals.get((int) face.normal.y - 1)));
            norm.put(asFloats3f(normals.get((int) face.normal.z - 1)));
            
            if(isTextured){
                tex.put(asFloats2f(textures.get((int) face.textures.x - 1)));
                tex.put(asFloats2f(textures.get((int) face.textures.y - 1)));
                tex.put(asFloats2f(textures.get((int) face.textures.z - 1)));
            }
        } 

         vert.flip();
         norm.flip();
         tex.rewind();

         vboVertex = glGenBuffers();         
         vertexBufferObjectIDs.add(vboVertex);
         
         vboNormal= glGenBuffers();
         normalBufferObjectIDs.add(vboNormal);
         
         vboTexture = glGenBuffers();
         textureBufferObjectsIDs.add(vboTexture);
         
         vboColor = glGenBuffers();
         
         
         glBindBuffer(GL_ARRAY_BUFFER, vboColor);
         glBufferData(GL_ARRAY_BUFFER, col, GL_STATIC_DRAW);
         glBindBuffer(GL_ARRAY_BUFFER, 0);
         
         
         glBindVertexArray(vboVertex);
         glBindBuffer(GL_ARRAY_BUFFER, vboVertex);
         glBufferData(GL_ARRAY_BUFFER, vert, GL_STATIC_DRAW);
         glBindBuffer(GL_ARRAY_BUFFER, 0);
        
         glBindVertexArray(vboNormal);
         glBindBuffer(GL_ARRAY_BUFFER, vboNormal);
         glBufferData(GL_ARRAY_BUFFER, norm, GL_STATIC_DRAW);
         glBindBuffer(GL_ARRAY_BUFFER, 0);
         
         if(isTextured){
            glBindBuffer(GL_ARRAY_BUFFER, vboTexture);
            glBufferData(GL_ARRAY_BUFFER, tex, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
         }
        
         glBindVertexArray(0);
         
         vert.clear();
         norm.clear();
         tex.clear();

Render code:


     glBindBuffer(GL_ARRAY_BUFFER, vboVertex);
            glVertexPointer(3, GL_FLOAT, 0, 0);

            glBindBuffer(GL_ARRAY_BUFFER, vboNormal);
            glNormalPointer(GL_FLOAT, 0, 0);
            
            glBindBuffer(GL_ARRAY_BUFFER, vboColor);
            glColorPointer(3, GL_FLOAT, 0, 0);
            
        

            
            if(isTextured){
                
                // I dont know how to render it!!
                
                
            }
            
             
            
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_NORMAL_ARRAY);
            glEnableClientState(GL_COLOR_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
           

            
            glMaterialf(GL_BACK, GL_SHININESS, 1f);
       
            glDrawArrays(GL_TRIANGLES, 0, this.faces.size() * 3);
            
            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_NORMAL_ARRAY);
            glDisableClientState(GL_COLOR_ARRAY);
            
            if(isTextured){
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            }
            
            glBindBuffer(GL_ARRAY_BUFFER, 0);

Thanks for the advices…

I’ve understood you were following my tutorial series, thanks for using them. For simplicity, I’ve kept the tutorial simple, there will be only one Texture field in the Model class. If you want to get multiple textures, you can, for example, do in two ways.

  • Creating a ModelBatcher and optimizing the Model class to use the batcher, drawing the faces that use one texture at a time and the faces that use other another time. I’ll be doing a ModelBatcher tutorial soon (Having exams this whole month, so it’s gonna take time)
  • Simply create a larger texture that includes both the textures in a single image and use blender to adjust the UV mapping. This is the simplest possible solution and is preferred by most game programmers.

Hope this helps.

Yep, your tutorials are very useful for me :slight_smile: I just do a little school project about 3D programming in Java and missing me only texture of model so i will use second (easy):smiley: method, thank you. And so you will have complete tutorial about ModelBatcher so I want to see him! Good luck with your exams:)

Thanks. I will be posting it soon I’ve completed the exams. Thanks for wishing me luck.