首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何正确加载和绘制此*.obj?

如何正确加载和绘制此*.obj?
EN

Game Development用户
提问于 2013-11-16 17:38:16
回答 1查看 5.6K关注 0票数 1

我有一个用于*.obj文件的加载器类(称为GLModel),它有两个主要方法-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public GLModel(BufferedReader ref, boolean centerit, GL gl,Texture texture)

用于加载*.obj,以及

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void opengldraw(GL gl)

用于在gl上绘制它。

到目前为止,我成功地加载和绘制了具有单个*.obj和纹理(如*.png*jpg等)的对象。

但是我怎么能画出一个有多种纹理的物体呢?

例如- 对象包含多个纹理,我尝试用合适的*.obj和其中一个纹理绘制它,得到了与上面的链接相同的形状,但它的纹理并不完全相同。

你能给我举一个如何正确使用它的例子吗?

编辑:

我在没有注册的情况下从这里下载了该模型。

到目前为止我得到的画是-

(前)-

(后)-

我说的装载机课是-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.media.opengl.GL;
import com.sun.opengl.util.texture.Texture;

// This class reads Wavefront .obj files
public class GLModel {

    private ArrayList<float[]> vertexsets;
    private ArrayList<float[]> vertexsetsnorms;
    private ArrayList<float[]> vertexsetstexs;
    private ArrayList<int[]> faces;
    private ArrayList<int[]> facestexs;
    private ArrayList<int[]> facesnorms;
    private int objectlist;
    private int numpolys;
    public float toppoint;
    public float bottompoint;
    public float leftpoint;
    public float rightpoint;
    public float farpoint;
    public float nearpoint;
    Texture texture;

    public GLModel(BufferedReader ref, boolean centerit, GL gl, 
            Texture texture){

        this.texture=texture;
        vertexsets = new ArrayList<float[]>();
        vertexsetsnorms = new ArrayList<float[]>();
        vertexsetstexs = new ArrayList<float[]>();
        faces = new ArrayList<int[]>();
        facestexs = new ArrayList<int[]>();
        facesnorms = new ArrayList<int[]>();
        numpolys = 0;
        toppoint = 0.0F;
        bottompoint = 0.0F;
        leftpoint = 0.0F;
        rightpoint = 0.0F;
        farpoint = 0.0F;
        nearpoint = 0.0F;
        loadobject(ref);
        if(centerit)
            centerit();
        opengldrawtolist(gl);
        numpolys = faces.size();
        cleanup();
    }

    public GLModel(BufferedReader ref, boolean centerit, GL gl){

        vertexsets = new ArrayList<float[]>();
        vertexsetsnorms = new ArrayList<float[]>();
        vertexsetstexs = new ArrayList<float[]>();
        faces = new ArrayList<int[]>();
        facestexs = new ArrayList<int[]>();
        facesnorms = new ArrayList<int[]>();
        numpolys = 0;
        toppoint = 0.0F;
        bottompoint = 0.0F;
        leftpoint = 0.0F;
        rightpoint = 0.0F;
        farpoint = 0.0F;
        nearpoint = 0.0F;
        loadobject(ref);
        if(centerit)
            centerit();
        numpolys = faces.size();
        cleanup();
    }

    private void cleanup(){
        vertexsets.clear();
        vertexsetsnorms.clear();
        vertexsetstexs.clear();
        faces.clear();
        facestexs.clear();
        facesnorms.clear();
    }

    @SuppressWarnings("unused")
    private void loadobject(BufferedReader br){
        int linecounter = 0;
        int facecounter = 0;
        try{
            boolean firstpass = true;
            String newline;
            while((newline = br.readLine()) != null){
                linecounter++;
                if(newline.length() > 0){
                    newline = newline.trim();

                    //LOADS VERTEX COORDINATES
                    if(newline.startsWith("v ")){
                        float coords[] = new float[4];
                        newline = newline.substring(2, newline.length());
                        StringTokenizer st = new StringTokenizer(newline, " ");
                        for(int i = 0; st.hasMoreTokens(); i++)
                            coords[i] = Float.parseFloat(st.nextToken());

                        if(firstpass){
                            rightpoint = coords[0];
                            leftpoint = coords[0];
                            toppoint = coords[1];
                            bottompoint = coords[1];
                            nearpoint = coords[2];
                            farpoint = coords[2];
                            firstpass = false;
                        }
                        if(coords[0] > rightpoint)
                            rightpoint = coords[0];
                        if(coords[0] < leftpoint)
                            leftpoint = coords[0];
                        if(coords[1] > toppoint)
                            toppoint = coords[1];
                        if(coords[1] < bottompoint)
                            bottompoint = coords[1];
                        if(coords[2] > nearpoint)
                            nearpoint = coords[2];
                        if(coords[2] < farpoint)
                            farpoint = coords[2];
                        vertexsets.add(coords);
                    }
                    else

                    //LOADS VERTEX TEXTURE COORDINATES
                    if(newline.startsWith("vt")){
                        float coords[] = new float[4];
                        newline = newline.substring(3, newline.length());
                        StringTokenizer st = new StringTokenizer(newline, " ");
                        for(int i = 0; st.hasMoreTokens(); i++)
                            coords[i] = Float.parseFloat(st.nextToken());

                        vertexsetstexs.add(coords);
                    }
                    else

                    //LOADS VERTEX NORMALS COORDINATES
                    if(newline.startsWith("vn")){
                        float coords[] = new float[4];
                        newline = newline.substring(3, newline.length());
                        StringTokenizer st = new StringTokenizer(newline, " ");
                        for(int i = 0; st.hasMoreTokens(); i++)
                            coords[i] = Float.parseFloat(st.nextToken());

                        vertexsetsnorms.add(coords);
                    }
                    else

                    //LOADS FACES COORDINATES
                    if(newline.startsWith("f ")){
                        facecounter++;
                        newline = newline.substring(2, newline.length());
                        StringTokenizer st = new StringTokenizer(newline, " ");
                        int count = st.countTokens();
                        int v[] = new int[count];
                        int vt[] = new int[count];
                        int vn[] = new int[count];
                        for(int i = 0; i < count; i++){
                            char chars[] = st.nextToken().toCharArray();
                            StringBuffer sb = new StringBuffer();
                            char lc = 'x';
                            for(int k = 0; k < chars.length; k++){
                                if(chars[k] == '/' && lc == '/')
                                    sb.append('0');
                                lc = chars[k];
                                sb.append(lc);
                            }

                            StringTokenizer st2 = new StringTokenizer
                            (sb.toString(), "/");
                            int num = st2.countTokens();
                            v[i] = Integer.parseInt(st2.nextToken());
                            if(num > 1)
                                vt[i] = Integer.parseInt(st2.nextToken());
                            else
                                vt[i] = 0;
                            if(num > 2)
                                vn[i] = Integer.parseInt(st2.nextToken());
                            else
                                vn[i] = 0;
                        }

                        faces.add(v);
                        facestexs.add(vt);
                        facesnorms.add(vn);
                    }
                    else
                        //LOADS MATERIALS
                        if (newline.charAt(0) == 'm' && newline.charAt(1) == 't' && newline.charAt(2) == 'l' && newline.charAt(3) == 'l' && newline.charAt(4) == 'i' && newline.charAt(5) == 'b') {}
                        else
                            //USES MATERIALS
                            if (newline.charAt(0) == 'u' && newline.charAt(1) == 's' && newline.charAt(2) == 'e' && newline.charAt(3) == 'm' && newline.charAt(4) == 't' && newline.charAt(5) == 'l') {}
                }
            }
        }
        catch(IOException e){
            System.out.println("Failed to read file: " + br.toString());
        }
        catch(NumberFormatException e){
            System.out.println("Malformed OBJ file: " + br.toString() + "\r \r"+ e.getMessage());
        }
    }

    private void centerit(){
        float xshift = (rightpoint - leftpoint) / 2.0F;
        float yshift = (toppoint - bottompoint) / 2.0F;
        float zshift = (nearpoint - farpoint) / 2.0F;
        for(int i = 0; i < vertexsets.size(); i++){
            float coords[] = new float[4];
            coords[0] = ((float[])vertexsets.get(i))[0] - leftpoint - xshift;
            coords[1] = ((float[])vertexsets.get(i))[1] - bottompoint - yshift;
            coords[2] = ((float[])vertexsets.get(i))[2] - farpoint - zshift;
            vertexsets.set(i, coords);
        }
    }

    public float getXWidth(){
        float returnval = 0.0F;
        returnval = rightpoint - leftpoint;
        return returnval;
    }

    public float getYHeight(){
        float returnval = 0.0F;
        returnval = toppoint - bottompoint;
        return returnval;
    }

    public float getZDepth(){
        float returnval = 0.0F;
        returnval = nearpoint - farpoint;
        return returnval;
    }

    public int numpolygons(){
        return numpolys;
    }

    public void opengldrawtolist(GL gl){
        // retrieving object list
        this.objectlist = gl.glGenLists(1);

        gl.glNewList(objectlist, GL.GL_COMPILE);
        texture.enable();
        texture.bind();
        gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);

        for (int i=0;i<faces.size();i++) {

            int[] tempfaces = (int[])(faces.get(i));
            int[] tempfacesnorms = (int[])(facesnorms.get(i));
            int[] tempfacestexs = (int[])(facestexs.get(i));

            //// Quad Begin Header ////
            int polytype;
            if (tempfaces.length == 3) {
                    polytype = GL.GL_TRIANGLES;
            } else if (tempfaces.length == 4) {
                    polytype = GL.GL_QUADS;
            } else {
                    polytype = GL.GL_POLYGON;
            }
            gl.glBegin(polytype);

            for (int w=0;w<tempfaces.length;w++) {
                if (tempfacesnorms[w] != 0) {
                    float normtempx = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[0];
                    float normtempy = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[1];
                    float normtempz = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[2];
                    gl.glNormal3f(normtempx, normtempy, normtempz);
                }

                if (tempfacestexs[w] != 0) {
                    float textempx = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[0];
                    float textempy = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[1];
                    float textempz = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[2];
                    gl.glTexCoord3f(textempx,1f-textempy,textempz);
                }

                float tempx = ((float[])vertexsets.get(tempfaces[w] - 1))[0];
                float tempy = ((float[])vertexsets.get(tempfaces[w] - 1))[1];
                float tempz = ((float[])vertexsets.get(tempfaces[w] - 1))[2];
                gl.glVertex3f(tempx,tempy,tempz);
            }
            // Quad End

            gl.glEnd();
        }

        gl.glEndList();
    }

    public void opengldraw(GL gl) {
        gl.glCallList(objectlist);
    }

    public boolean collision(float[] position) {
            return false;
    }

    public void setTexature(Texture tex) {
            this.texture = tex;
    }
}

我使用的*.obj是- Zero.obj (在将其转换为BufferedReader之后),我使用的图像是- AssassinBody_Dif.jpg (在将其转换为Texture之后)。

我要找的是-如何使用附加的GLModel类获得该模型的完整绘图?

EN

回答 1

Game Development用户

回答已采纳

发布于 2013-11-17 00:29:21

波前obj文件通常与定义所用纹理的材料文件(.mat)相结合。模型的网格划分为不同的材料组。每种材料都告诉你要使用的纹理和网格的其他信息。

在您的例子中,模型上有单独的网格。这些网格是头部,身体和手。他们都有自己的纹理,这将需要应用到正确的网格,以使它看起来正确。网格最有可能在网格组、材料组或照明组中在.obj文件中分离。您需要在单独的网格实例中读取它们,以便能够以不同的纹理呈现它们。

您还遇到了名为正规映射的东西,它本质上是将一些高聚模型的网格数据保存在纹理中,以便与低聚模型一起使用。

票数 3
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/65956

复制
相关文章

相似问题

添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文