0

Is it possible to convert .blend or .obj file to a float array for later use for rendering in the OpenGL? For example, Vertices:

float[] vertices = {
    -1, -1, 0,
    // some vertices
};

Texture coordinates:

float[] texCoords = {
    0, 0,
    // some texture coordinates
};

Vertices indices:

float[] indices = {
    0, 1, 2,
    // some vertices indices
};

It would also be nice to get the type of figure that we draw:

glDrawElements(GL.GL_TRIANGLES /* type */, intbuff.capacity(), GL.GL_UNSIGNED_INT, intbuff);

Is it possible? And how can this be done?

genpfault
  • 51,148
  • 11
  • 85
  • 139
congard
  • 945
  • 2
  • 10
  • 28
  • You should look at the source code of numerous WaveFront OBJ importers, it could be a good source of inspiration to write your own one based on JOGL but keep in mind that an OBJ file can contain some materials too. You can look at my source code here: https://github.com/gouessej/Ardor3D/tree/master/ardor3d-extras/src/main/java/com/ardor3d/extension/model/obj – gouessej Jan 21 '18 at 16:43
  • @gouessej : [...]"based on JOGL"[...] the library wont most likely not matter, except for materials/textures which may be referred to in the obj file. – Luatic Jan 23 '18 at 17:43
  • At first, the original poster's question is tagged "jogl". Secondly, the library matters because the bindings to the OpenGL and OpenGL-ES APIs may use a different syntax, JOGL has its own API to manipulate textures and images even though it's still possible to use the lower level calls. Moreover, each scenegraph API or framework has its own APIs to manipulate the transforms, the matrices, etc. Some engines only support the programmable pipeline, some others support only the fixed pipeline. Finally, the original poster mentions texture coordinates. – gouessej Jan 23 '18 at 21:20
  • There is an OBJ importer in JOGL-demos: https://github.com/sgothel/jogl-demos/blob/master/src/demos/util/ObjReader.java There is another one in JOGL-Utils: https://github.com/sgothel/jogl-utils/blob/master/src/net/java/joglutils/model/loader/WaveFrontLoader.java Both are less complete than mine. Pick the one that fits the best into your needs. – gouessej Jan 25 '18 at 12:42

1 Answers1

-1

Why do you want to open .blend files ? Do you need an animation ? If not, you don't have to import .blend files. For most OBJ files, it's overwhelming easy to create your own.

OBJ File Format Specifications

But this is not necessary.

Here is a complete one for OBJs : https://github.com/javagl/Obj

BTW, here's my Mesh class, only capable of loading single-group OBJs :

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

public class Mesh {
    public float[] vertices;
    public float[] texcoords;
    public float[] normals;
    public int[] indices;

    public Mesh(float[] vertices, float[] texcoords, float[] normals, int[] indices) {
        this.vertices = vertices;
        this.texcoords = texcoords;
        this.normals = normals;
        this.indices = indices;
    }

    public Mesh(String filename) throws FileNotFoundException, IOException {
        File f=new File(filename);
        FileInputStream fis=new FileInputStream(f);
        int c=fis.read();
        String s="";
        while (c != -1) {
            s+=(char)c;
            c=fis.read();
        }
        String[] lines=s.split("\n");
        ArrayList<Float> vertices2=new ArrayList<Float>();
        ArrayList<Float> normals2=new ArrayList<Float>();
        ArrayList<Float> texcoords2=new ArrayList<Float>();
        ArrayList<Integer> normalindices=new ArrayList<Integer>();
        ArrayList<Integer> uvindices=new ArrayList<Integer>();
        ArrayList<Integer> indices2=new ArrayList<Integer>();
        for (String line:lines) {
            String[] parts=line.split(" ");
            if (parts[0].equals("v")) {
                vertices2.add(Float.parseFloat(parts[1]));
                vertices2.add(Float.parseFloat(parts[2]));
                vertices2.add(Float.parseFloat(parts[3]));
            }
            else if (parts[0].equals("vt")) {
                texcoords2.add(Float.parseFloat(parts[1]));
                texcoords2.add(Float.parseFloat(parts[2]));
            }
            else if (parts[0].equals("vn")) {
                normals2.add(Float.parseFloat(parts[1]));
                normals2.add(Float.parseFloat(parts[2]));
                normals2.add(Float.parseFloat(parts[3]));
            }
            else if (parts[0].equals("f")) {
                for (int i=1; i < parts.length; i++) {
                    String part=parts[i];
                    String[] byslash=part.split("/");
                    int indi=Integer.parseInt(byslash[0]);
                    indices2.add(indi-1);
                    if (byslash.length > 1) {
                    indi=Integer.parseInt(byslash[1]);
                    uvindices.add(indi-1);
                    indi=Integer.parseInt(byslash[2]);
                    normalindices.add(indi-1);
                    }
                    else {
                        uvindices.add(indi-1);
                        normalindices.add(indi-1);
                    }
                }                
            }
        }
        indices=new int[indices2.size()];
        vertices=new float[indices2.size()*3];
        texcoords=new float[indices2.size()*2];
        normals=new float[indices2.size()*3];
        for (int i=0; i < indices.length; i++) {
            indices[i]=i;
            int vuvi=indices2.get(i)*3;
            int fuvi=uvindices.get(i)*2;
            int nuvi=normalindices.get(i)*3;
            vertices[i*3]=vertices2.get(vuvi);
            vertices[i*3+1]=vertices2.get(vuvi+1);
            vertices[i*3+2]=vertices2.get(vuvi+2);
            texcoords[i*2]=texcoords2.get(fuvi);
            texcoords[i*2+1]=texcoords2.get(fuvi+1);
            normals[i*3]=normals2.get(nuvi);
            normals[i*3+1]=normals2.get(nuvi+1);
            normals[i*3+2]=normals2.get(nuvi+2);
        }
    }
}

It does not support Materials, which makes it library(JOGL/LWJGL) independent. Hope it helps you.

gouessej
  • 3,640
  • 3
  • 33
  • 67
Luatic
  • 8,513
  • 2
  • 13
  • 34
  • The question is tagged "jogl" and the original poster mentions texture coordinates in his source code which seems to indicate that he needs texture support. Why reading texture coordinates if you can't draw the textures? There are tons of more complete and more tested OBJ importers available online. There is no need to reinvent the wheel in worse. elect86 on Github works on jassimp, there are importers for this format in JMonkeyEngine, LibGDX, Unlicense, ... There are an importer and an exporter both in jReality and in JogAmp's Ardor3D Continuation. – gouessej Jan 23 '18 at 21:31
  • @gouessej Ill explain it to you : **some** OBJ files have usemtl. This defines the required textures' sources. But most likely, you'll texture it with any texture in your application. And texture loading is much different from OBJ loading – Luatic Jan 24 '18 at 14:05
  • Specifying the texture map(s) in the Material Template Library file is a non ambiguous way of indicating which texture(s) to use even though you can override this indication by using other textures in your software. Sorry but when I look at the source code of a free software, I don't want to have to guess which image files are used as textures. When you want to use a completely different set of textures with the mesh(es) of the same OBJ file, you can still write several MTL files and load them or create several material libraries programmatically. – gouessej Jan 25 '18 at 12:20
  • Yes some OBJ files have usemtl, some others don't. Using OBJ files with texture coordinates without material or loading OBJ files with texture coordinates without loading their materials is a possible solution but a poor one to me. That's the main reason why I'm not satisfied by your source code above and I talked about reinventing the wheel in worse because I have seen lots of importers not handling line continuation markers and not indicating clearly which keywords aren't handled. – gouessej Jan 25 '18 at 12:25
  • @gouessej Yes, and that reason for I posted a link to a better one. I just wanted to show some source of mine, because this may help him understanding it. – Luatic Jan 25 '18 at 14:05