简体   繁体   English

OpenGL ES纹理无法正确渲染

[英]OpenGL ES Texture not rendering correctly

I am working on a Android app with openglES 3.0 and I want to create a obj loader system and display a 3D model with his texture. 我正在使用openglES 3.0开发一个Android应用,我想创建一个obj loader系统并显示带有其纹理的3D模型。 My code display correctly a 3D meshe without texture. 我的代码正确显示了没有纹理的3D网格。 If I try to add a texture, it will display the texture and some part of the texture will be empty triangles. 如果尝试添加纹理,它将显示该纹理,并且该纹理的某些部分将是空三角形。

Example : 范例:

my meshe with a texture 我的网状纹理

my meshe obj file 我的网状obj文件

my texture png file 我的纹理png文件

I can not find what is the problem. 我找不到问题所在。

My fragment shader 我的片段着色器

precision mediump float;
uniform vec4 vColor;
uniform sampler2D uTexture;
varying vec2 oTexCoordinate;

void main() {
    gl_FragColor = texture2D(uTexture, oTexCoordinate);
    //gl_FragColor = vec4(1, 0.5, 0, 1.0);

}

My vertex shader 我的顶点着色器

attribute vec4 position;
uniform mat4 matrix;

attribute vec2 vTexCoordinate;
varying vec2 oTexCoordinate;


void main() {
    oTexCoordinate = vTexCoordinate;
    gl_Position = matrix * position;

}

Thanks in advance. 提前致谢。


Update : 更新:

Thanks. 谢谢。

I have changed my code to fit your idea, I have activated the face culling and add a buffer for the normal, I do not use it for now. 我已经更改了代码以适合您的想法,我激活了脸部剔除并为法线添加了缓冲区,我暂时不使用它。 I put my new code below. 我把我的新代码放在下面。 But the problem is not entirely resolved, see the picture below. 但是问题并未完全解决,请参见下图。

I think I need to pass the normal information to the shaders but I am not sure how to do it properly or if it is the solution. 我想我需要将常规信息传递给着色器,但是我不确定如何正确执行此信息,或者不确定这是否是解决方案。

public class MeshLoader {

    private int program;

    private List<String> facesVertexList;
    private List<String> facesTextureList;
    private List<String> facesNormalList;

    private List<String> verticesList;
    private List<String> textureList;
    private List<String> normalList;

    private FloatBuffer verticesBuffer;
    private FloatBuffer verticesBufferTemp;

    private FloatBuffer facesVertexBuffer;
    private FloatBuffer facesTextureBuffer;
    private FloatBuffer facesNormalBuffer;

    private FloatBuffer textureBuffer;
    private FloatBuffer textureBufferTemp;

    private FloatBuffer normalBuffer;
    private FloatBuffer normalBufferTemp;

    private Context contextMeshLoader;
    final int[] textureHandle = new int[1];


    public MeshLoader(Context context) {
        contextMeshLoader = context;
        textureList = new LinkedList<>();
        verticesList = new LinkedList<>();
        normalList = new LinkedList<>();
        facesVertexList = new LinkedList<>();
        facesTextureList = new LinkedList<>();
        facesNormalList = new LinkedList<>();

        openObjFile(0);

        String vertexShaderCode = "";
        try{
            InputStream vertexShaderStream = context.getResources().openRawResource(R.raw.vertex_shader);
            vertexShaderCode = IOUtils.toString(vertexShaderStream, Charset.defaultCharset());
            vertexShaderStream.close();
        }
        catch (Exception e){
            Log.e("MeshReaderActivity", "Error reading vertex shader", e);
        }

        String fragmentShaderCode = "";
        try{
            InputStream fragmentShaderStream = context.getResources().openRawResource(R.raw.fragment_shader);
            fragmentShaderCode = IOUtils.toString(fragmentShaderStream, Charset.defaultCharset());
            fragmentShaderStream.close();
        }
        catch(Exception e){
            Log.e("MeshReaderActivity", "Error reading fragment shader", e);
        }

        int vertexShader = GLES30.glCreateShader(GLES30.GL_VERTEX_SHADER);
        GLES30.glShaderSource(vertexShader, vertexShaderCode);

        int fragmentShader = GLES30.glCreateShader(GLES30.GL_FRAGMENT_SHADER);
        GLES30.glShaderSource(fragmentShader, fragmentShaderCode);


        GLES30.glCompileShader(vertexShader);
        GLES30.glCompileShader(fragmentShader);


        program = GLES30.glCreateProgram();
        GLES30.glAttachShader(program, vertexShader);
        GLES30.glAttachShader(program, fragmentShader);
        GLES30.glLinkProgram(program);
        GLES30.glUseProgram(program);

    }

    public void openObjFile(int value)
    {
        InputStream is;
        value = 0;
        if(value == 0)
           is  = contextMeshLoader.getResources().openRawResource(R.raw.objface);
        else
            is = contextMeshLoader.getResources().openRawResource(R.raw.objship);

        if(verticesBufferTemp != null)
            verticesBufferTemp.clear();
        if(facesVertexBuffer != null)
            facesVertexBuffer.clear();
        if(textureBuffer != null)
            textureBuffer.clear();
        if(verticesList != null)
            verticesList.clear();
        if(facesVertexList != null)
            facesVertexList.clear();
        if(textureList != null)
            textureList.clear();

        try{
            byte[] buffer = new byte[is.available()];
            is.read(buffer);
            String data = new String(buffer);

            parseData(data);



            ByteBuffer buffer2 = ByteBuffer.allocateDirect(facesVertexList.size() * 3 * 4);
            buffer2.order(ByteOrder.nativeOrder());
            facesVertexBuffer = buffer2.asFloatBuffer();

            ByteBuffer buffer3 = ByteBuffer.allocateDirect(facesTextureList.size() * 3 * 4);
            buffer3.order(ByteOrder.nativeOrder());
            facesTextureBuffer = buffer3.asFloatBuffer();

            ByteBuffer buffer6 = ByteBuffer.allocateDirect(facesTextureList.size() * 3 * 4);
            buffer6.order(ByteOrder.nativeOrder());
            facesNormalBuffer = buffer6.asFloatBuffer();


            for(String face: facesVertexList) {
                String vertexIndices[] = face.split("\\s+");
                float vertex1 = Float.parseFloat(vertexIndices[1]);
                float vertex2 = Float.parseFloat(vertexIndices[2]);
                float vertex3 = Float.parseFloat(vertexIndices[3]);
                facesVertexBuffer.put((vertex1 - 1));
                facesVertexBuffer.put((vertex2 - 1));
                facesVertexBuffer.put((vertex3 - 1));
            }
            facesVertexBuffer.position(0);


            for(String texture: facesTextureList){
                String textureIndice[] = texture.split("\\s+");
                float texture1 = Float.parseFloat(textureIndice[1]);
                float texture2 = Float.parseFloat(textureIndice[2]);
                float texture3 = Float.parseFloat(textureIndice[3]);
                facesTextureBuffer.put((texture1 - 1));
                facesTextureBuffer.put((texture2 - 1));
                facesTextureBuffer.put((texture3 - 1));
            }
            facesTextureBuffer.position(0);

            for(String normal: facesNormalList) {
                String normalIndice[] = normal.split("\\s+");
                float normal1 = Float.parseFloat(normalIndice[1]);
                float normal2 = Float.parseFloat(normalIndice[2]);
                float normal3 = Float.parseFloat(normalIndice[3]);
                facesNormalBuffer.put((normal1 - 1));
                facesNormalBuffer.put((normal2 - 1));
                facesNormalBuffer.put((normal3 - 1));
            }
            facesNormalBuffer.position(0);


            ByteBuffer buffer1 = ByteBuffer.allocateDirect(verticesList.size() * 3 * 4);
            buffer1.order(ByteOrder.nativeOrder());
            verticesBufferTemp = buffer1.asFloatBuffer();

            ByteBuffer buffer5 = ByteBuffer.allocateDirect(textureList.size() * 2 * 4);
            buffer5.order(ByteOrder.nativeOrder());
            textureBufferTemp = buffer5.asFloatBuffer();

            ByteBuffer buffer7 = ByteBuffer.allocateDirect(textureList.size() * 3 * 4);
            buffer7.order(ByteOrder.nativeOrder());
            normalBufferTemp = buffer7.asFloatBuffer();

            for(String vertex: verticesList) {
                String coords[] = vertex.split("\\s+");
                float x = Float.parseFloat(coords[1]);
                float y = Float.parseFloat(coords[2]);
                float z = Float.parseFloat(coords[3]);
                verticesBufferTemp.put(x);
                verticesBufferTemp.put(y);
                verticesBufferTemp.put(z);
            }
            verticesBufferTemp.position(0);

            for (String texture:textureList)
            {
                String textureIndices[] = texture.split("\\s+");
                float texture1 = Float.parseFloat(textureIndices[1]);
                float texture2 = Float.parseFloat(textureIndices[2]);
                textureBufferTemp.put(texture1);
                textureBufferTemp.put(texture2);
            }
            textureBufferTemp.position(0);

            for (String normal:normalList)
            {
                String normalIndices[] = normal.split("\\s+");
                float normal1 = Float.parseFloat(normalIndices[1]);
                float normal2 = Float.parseFloat(normalIndices[2]);
                normalBufferTemp.put(normal1);
                normalBufferTemp.put(normal2);
            }
            normalBufferTemp.position(0);


            System.out.println("size remaining " + facesVertexBuffer.remaining());

            ByteBuffer bufferV = ByteBuffer.allocateDirect(facesVertexBuffer.remaining() * 3 * 4);
            bufferV.order(ByteOrder.nativeOrder());
            verticesBuffer = bufferV.asFloatBuffer();

            ByteBuffer bufferT = ByteBuffer.allocateDirect(facesVertexBuffer.remaining() * 2 * 4);
            bufferT.order(ByteOrder.nativeOrder());
            textureBuffer = bufferT.asFloatBuffer();

            ByteBuffer bufferN = ByteBuffer.allocateDirect(facesVertexBuffer.remaining() * 3 * 4);
            bufferN.order(ByteOrder.nativeOrder());
            normalBuffer = bufferN.asFloatBuffer();

            int size = facesVertexBuffer.remaining();

            for(int i = 0; i < size;i++)
            {
                int faceVertex = Math.round(facesVertexBuffer.get(i)) ;
                int faceTexture = Math.round(facesTextureBuffer.get(i));
                int faceNormal = Math.round(facesNormalBuffer.get(i));

                float x = verticesBufferTemp.get((faceVertex)*3);
                float y = verticesBufferTemp.get(((faceVertex)*3)+1);
                float z = verticesBufferTemp.get(((faceVertex)*3)+2);
                verticesBuffer.put( i*3,   x);
                verticesBuffer.put( (i*3)+1, y);
                verticesBuffer.put( (i*3)+2, z);

                float u = textureBufferTemp.get((faceTexture)*2);
                float v = -textureBufferTemp.get(((faceTexture)*2)+1);
                textureBuffer.put( i*2,   u);
                textureBuffer.put( (i*2)+1, v);

                float xn = normalBufferTemp.get((faceNormal*3));
                float yn = normalBufferTemp.get((faceNormal*3)+1);
                float zn = normalBufferTemp.get((faceNormal*3)+2);
                normalBuffer.put(i*3,xn);
                normalBuffer.put((i*3)+1,yn);
                normalBuffer.put((i*3)+2,zn);

            }
            verticesBuffer.position(0);
            textureBuffer.position(0);
            normalBuffer.position(0);

            is.close();
            loadTexture();
        }
        catch (Exception e) {
            Log.e("MeshReaderActivity", "Error reading objfile", e);
        }
    }

    public void parseData(String dataToParse)
    {
        Log.i("parse data method", "parse data method");
        String[] data = dataToParse.split("\n");
        for (int i = 0;i < data.length;i++)
        {
            String line = data[i];
            if(line.startsWith("v "))
            {
                // Add vertex line to list of vertices
                verticesList.add(line);
            }
            else if(line.startsWith("vt "))
            {
                textureList.add(line);
            }
            else if(line.startsWith("vn "))
            {
                normalList.add(line);
            }
            else if(line.startsWith("f "))
            {
                // Add face line to faces list
                triangulate(line);
            }
        }

    }

    public void triangulate(String lineToTriangulate)
    {
        String lineSplit[] = lineToTriangulate.split("\\s+");
        if(lineSplit.length > 4)
        {
            String line1="";
            String line2="";
            if (lineToTriangulate.contains("/"))
            {
                line1 = lineSplit[0] + " " + lineSplit[1].split("/")[0] + " " + lineSplit[2].split("/")[0] + " " + lineSplit[3].split("/")[0];
                line2 = lineSplit[0] + " " + lineSplit[1].split("/")[0] + " " + lineSplit[2].split("/")[0] + " " + lineSplit[4].split("/")[0];
            }
            else
            {
                line1 = lineSplit[0] + " " + lineSplit[1] + " " + lineSplit[2] + " " + lineSplit[3];
                line2 = lineSplit[0] + " " + lineSplit[1] + " " + lineSplit[2] + " " + lineSplit[4];
            }
            facesVertexList.add(line1);
            facesVertexList.add(line2);
        }
        else
        {
            if(lineToTriangulate.contains("/"))
            {
                String[] splitElement1 = lineSplit[1].split("/");
                String[] splitElement2 = lineSplit[2].split("/");
                String[] splitElement3 = lineSplit[3].split("/");
                String line = lineSplit[0] + " " + splitElement1[0] + " " + splitElement2[0] + " " + splitElement3[0];
                facesVertexList.add(line);
                line = lineSplit[0] + " " + splitElement1[1] + " " + splitElement2[1] + " " + splitElement3[1];
                facesTextureList.add(line);
                line =  lineSplit[0] + " " + splitElement1[2] + " " + splitElement2[2] + " " + splitElement3[2];
                facesNormalList.add(line);

            }
            else
            {
                facesVertexList.add(lineToTriangulate);
            }
        }
    }


    public void draw(float scratch[],float zoom){


        int position = GLES30.glGetAttribLocation(program, "position");
        GLES30.glEnableVertexAttribArray(position);
        GLES30.glVertexAttribPointer(position, 3, GLES30.GL_FLOAT, false, 3 * 4, verticesBuffer);


        int mTextureUniformHandle = GLES30.glGetUniformLocation(program, "uTexture");
        int mTextureCoordinateHandle = GLES30.glGetAttribLocation(program, "vTexCoordinate");

        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
        GLES30.glUniform1i(mTextureUniformHandle, 0);
        GLES30.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES30.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES30.GL_FLOAT, false, 2*4, textureBuffer);

        int normalHandle = GLES30.glGetAttribLocation(program,"normal");
        GLES30.glEnableVertexAttribArray(normalHandle);
        GLES30.glVertexAttribPointer(normalHandle,3,GLES30.GL_FLOAT,false,3*4,normalBuffer);

        float[] projectionMatrix = new float[16];
        float[] viewMatrix = new float[16];
        float[] productMatrix = new float[16];

        Matrix.frustumM(projectionMatrix, 0,
                -1, 1,
                -1, 1,
                1, 11);
        Matrix.setLookAtM(viewMatrix, 0,
                0, 0, zoom,
                0, 0, 0,
                0, 1, 0);
        Matrix.multiplyMM(productMatrix, 0,
                projectionMatrix, 0,
                viewMatrix, 0);

        float[] finalMatrix = new float[16];

        Matrix.multiplyMM(finalMatrix, 0,
                productMatrix, 0,
                scratch, 0);

        Matrix.rotateM(finalMatrix, 0, 180, 0.0f, 1.0f, 0.0f);


        int matrix = GLES30.glGetUniformLocation(program, "matrix");
        GLES30.glUniform1i(matrix,0);
        //GLES30.glUniformMatrix4fv(matrix, 1, false, productMatrix, 0);
        GLES30.glUniformMatrix4fv(matrix, 1, false, finalMatrix, 0);


        int size = facesVertexBuffer.remaining();

        GLES30.glEnable(GLES30.GL_CULL_FACE);
        GLES30.glCullFace(GLES30.GL_BACK);


        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,0,size);

        GLES30.glDisableVertexAttribArray(position);
        GLES30.glDisableVertexAttribArray(mTextureCoordinateHandle);
    }

    public void loadTexture()
    {

        GLES30.glGenTextures(1, textureHandle,0);

        if (textureHandle[0] == 0)
        {
            throw new RuntimeException("Error generating texture name.");
        }


        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = true;    // No pre-scaling

        Bitmap bitmap = BitmapFactory.decodeResource(contextMeshLoader.getResources(), R.raw.pngface, options);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureHandle[0]);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);


        GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
    }

}

Thanks again. 再次感谢。


Update 更新资料

For the float, it was an error of copy/paste. 对于浮动,这是复制/粘贴的错误。 For my problem of display I have find the solution. 对于我的显示问题,我找到了解决方案。 I just need to add in the onDrawFrame method. 我只需要添加onDrawFrame方法。

GLES30.glEnable(GLES30.GL_DEPTH_TEST);

Now, My meshe and his texture is correctly displayed. 现在,“我的网格”及其纹理已正确显示。

Thanks for your help. 谢谢你的帮助。

Your assumption is wrong. 您的假设是错误的。 The same vertex coordinate can be associated to different texture coordinates. 相同的顶点坐标可以关联到不同的纹理坐标。

It the following code you create a new texture coordinate array, that has as many items as the array of vertex coordinate. 在下面的代码中,您将创建一个新的纹理坐标数组,该数组具有与顶点坐标数组一样多的项目。 That would work only, if each vertex coordinate is associated to exactly 1 texture coordinate. 仅当每个顶点坐标与1个纹理坐标精确关联时,该方法才有效。 In the file are 7536 texture coordinates and 7366 vertex cooodinates. 该文件中有7536个纹理坐标和7366个顶点cooodinates。

 public void parseTexture() { int size = facesVertexBuffer.remaining(); System.out.println("size " + size); for(int i = 0; i < size;i++) { int faceVertex = facesVertexBuffer.get(i); int faceTexture = facesTextureBuffer.get(i); float a = textureBufferTemp.get((faceTexture)*2); float b = -textureBufferTemp.get(((faceTexture)*2)+1); textureBuffer.put((faceVertex*2),a); textureBuffer.put(((faceVertex)*2)+1,b); } textureBuffer.position(0); System.out.println("end parse texture"); } 

If there are different indices for vertex coordinates and texture coordinates, then vertex positions have to be "duplicated". 如果顶点坐标和纹理坐标的索引不同,则必须“复制”顶点位置。 The vertex coordinate and its attributes (like texture coordinate) form a data reocord. 顶点坐标及其属性(如纹理坐标)形成数据记录。 You can imagine a 3D vertex coordinate and a 2D texture coordinate as a single 5D coordinate. 您可以将3D顶点坐标和2D纹理坐标想象为一个5D坐标。 See Rendering meshes with multiple indices . 请参见渲染具有多个索引的网格

The vertex attributes for each vertex position form a set of data. 每个顶点位置的顶点属性形成一组数据。 This means you have to create tuples of vertex coordinate, and texture coordiantes. 这意味着您必须创建顶点坐标和纹理坐标的元组。

Let's assume that you have a .obj file like this: 假设您有一个.obj文件,如下所示:

v -1 -1 -1
v  1 -1 -1
v -1  1 -1
v  1  1 -1
v -1 -1  1
v  1 -1  1
v -1  1  1
v  1  1  1

vt 0 0
vt 0 1
vt 1 0
vt 1 1

vn -1  0  0
vn  0 -1  0
vn  0  0 -1
vn  1  0  0
vn  0  1  0
vn  0  0  1

f 3/1/1 1/2/1 5/4/1 7/3/1
f 1/1/2 2/2/2 3/4/2 6/3/2
f 3/1/3 4/2/3 2/4/3 1/3/3
f 2/1/4 4/2/4 8/4/4 6/3/4
f 4/1/5 3/2/5 7/4/5 8/3/5
f 5/1/6 6/2/6 8/4/6 7/3/6

From this you have to find all the combinations of vertex coordinate, texture texture coordinate and normal vector indices, which are used in the face specification: 由此,您必须找到顶点规范,纹理纹理坐标和法向矢量索引的所有组合,这些组合在面部规范中使用:

 0 : 3/1/1
 1 : 1/2/1
 2 : 5/4/1
 3 : 7/3/1
 4 : 1/1/2
 5 : 2/2/2
 6 : 3/4/2
 7 : 6/3/2
 8 : ...

Then you have to create a vertex coordinate, texture coordinate and normal vector array corresponding to the array of combinations indices. 然后,您必须创建与组合索引数组相对应的顶点坐标,纹理坐标和法线矢量数组。 The vertex coordinates and its attributes can either be combined in one array to data sets, or to three arrays with equal number of attributes: 顶点坐标及其属性可以在一个数组中组合成数据集,或者在三个数组中组合成相等数量的属性:

 index   vx vy vz     u v     nx ny nz
 0 :     -1  1 -1     0 0     -1  0  0
 1 :     -1 -1 -1     0 1     -1  0  0
 2 :     -1 -1  1     1 1     -1  0  0
 3 :     -1  1  1     1 0     -1  0  0
 4 :     -1 -1 -1     0 0      0 -1  0
 5 :      1 -1 -1     0 1      0 -1  0
 6 :     -1  1 -1     1 1      0 -1  0
 7 :      1 -1  1     1 0      0 -1  0
 8 : ...

Further be aware, the the data type short , which is used for the indices in your application, has a range of [-32768, 32767]. 还要注意,用于应用程序中索引的数据类型short的范围为[-32768,32767]。 This my be large enough for this model, but the number of indices of larger models will exceed this limit. 对于该模型,这足够大,但是较大模型的索引数将超过此限制。


The easiest workaround, is, to create an array of triangle primitives. 最简单的解决方法是创建一个三角形基元数组。 Completely skip the index buffer and use GLES30.glDrawArrays() to draw the mesh. 完全跳过索引缓冲区,并使用GLES30.glDrawArrays()绘制网格。

Red the vertex coordinates and texture coordinates in a temporary buffer. 在临时缓冲区中将顶点坐标和纹理坐标变为红色。

ByteBuffer bufferVTemp = ByteBuffer.allocateDirect(verticesList.size() * 2 * 4);
bufferVTemp.order(ByteOrder.nativeOrder());
verticesBufferTemp = bufferVTemp.asFloatBuffer();

ByteBuffer bufferTTemp = ByteBuffer.allocateDirect(textureList.size() * 2 * 4);
bufferTTemp.order(ByteOrder.nativeOrder());
textureBufferTemp = bufferTTemp.asFloatBuffer();

for(String vertex: verticesList) {
    String coords[] = vertex.split(" "); // Split by space
    float x = Float.parseFloat(coords[1]);
    float y = Float.parseFloat(coords[2]);
    float z = Float.parseFloat(coords[3]);
    verticesBufferTemp.put(x);
    verticesBufferTemp.put(y);
    verticesBufferTemp.put(z);
}
verticesBufferTemp.position(0);

for (String texture: textureList)
{
    String textureIndices[] = texture.split("\\s+");
    float texture1 = Float.parseFloat(textureIndices[1]);
    float texture2 = Float.parseFloat(textureIndices[2]);
    textureBufferTemp.put(texture1);
    textureBufferTemp.put(texture2);
}
textureBufferTemp.position(0);

Then create an array of tringles 然后创建一个数组

ByteBuffer bufferV = ByteBuffer.allocateDirect(facesVertexBuffer.size() * 3 * 4);
bufferV.order(ByteOrder.nativeOrder());
verticesBuffer = bufferV.asFloatBuffer();

ByteBuffer bufferT = ByteBuffer.allocateDirect(facesVertexBuffer.size() * 2 * 4);
bufferT.order(ByteOrder.nativeOrder());
textureBuffer = bufferT.asFloatBuffer();

int size = facesVertexBuffer.remaining();
System.out.println("size " + size);
for(int i = 0; i < size;i++)
{
    int faceVertex = facesVertexBuffer.get(i);
    int faceTexture = facesTextureBuffer.get(i);

    float x = verticesBufferTemp.get((faceVertex)*2);
    float y = verticesBufferTemp.get(((faceVertex)*2)+1);
    float z = verticesBufferTemp.get(((faceVertex)*2)+1);
    verticesBuffer.put( i*3,    x);
    verticesBuffer.put( i*3+1,  y);
    verticesBuffer.put( i*3+2), z);

    float u = textureBufferTemp.get((faceTexture)*2);
    float v = -textureBufferTemp.get(((faceTexture)*2)+1);
    textureBuffer.put( i*2,   u);
    textureBuffer.put( i*2+1, v);
}
verticesBuffer.position(0);
textureBuffer.position(0);

Draw the mesh by GLES30.glDrawArrays() : 通过GLES30.glDrawArrays()绘制网格:

GLES30.glDrawElements(GLES30.GL_TRIANGLES, 0, facesVertexBuffer.size());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM