如何在OpenGL ES 2.0中绘制许多3d对象?

时间:2015-03-30 19:23:14

标签: android c++ android-ndk opengl-es-2.0

有许多3D对象(1000+)由三角形构成,我需要使用Android NDK和OpenGL ES 2.0绘制它。每个三角形都有顶点坐标,颜色,纹理和纹理坐标。我有两个问题:

  1. 我的片段着色器中的函数texture2D(u_Texture,v_TexCoord)会为每个三角形返回vec4(0.0, 0.0, 0.0, 1.0)
  2. 低费率框架。
  3. 这是我的代码:

    加载bmp文件并创建纹理:

    void CreateTexture(unsigned &texture, const char * fileName)
    {
        char *pFolderName = NULL;
        int width = 0;
        int height = 0;
        unsigned char *data = NULL;
        char *pExtension = NULL;
        glGenTextures(1, &texture);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        //check extension
        pExtension = new char[5];
        pExtension[4] = '\0';
        int j = strlen(fileName) - 1;
        do {
            j--;
        } while (j > 0 && fileName[j] != '.');
    
        for (int k = 0; k < 5; k++) {
            j++;
            pExtension[k] = fileName[j];
        }
        if (   0 == strcmp(pExtension, BMP_EXT)
            || 0 == strcmp(pExtension, BMP_EXT1))
        {
            FILE *f = fopen(fileName, "r");
            if(f == NULL) LOGE("Couldn't open texture file %s", fileName);
            fseek(f, 18, SEEK_SET);
            fread(&width, 4, 1, f);
            fread(&height, 4, 1, f);
            data = new unsigned char[width*height*3];
            fseek(f, 54, SEEK_SET);
            fread(data, width*height*3, 1, f);
    
            char tmp;
            //convert BGR->RGB
            for(int i=0;i<width*height*3-2;i+=3)
            {
                tmp = data[i];
                data[i] = data[i+2];
                data[i+2] = tmp;
            }
            unsigned char *reverseData = new unsigned char[width*height*3];
            for(int j1 = 0; j1 < height; ++j1)
            for(int i1 = 0; i1 < width*3; ++i1)
                reverseData[j1*(width*3)+i1] = data[(height-j1-1)*width*3+i1];
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, reverseData);
            delete []data;
            delete []pExtension;
            delete []reverseData;
        }
    }
    

    绘制功能:

    void Display(VisObject *obj)
    {
        GLint pos = shader.GetAttribLocation("a_Position");
        GLint texpos = shader.GetAttribLocation("a_TexCoord");
        GLint a_color = shader.GetAttribLocation("a_Color");
        GLint texture  = shader.GetUniformLocation("u_Texture");
        GLint textureFlag  = shader.GetUniformLocation("u_TextureFlag");
        for(int i=0; i < obj->CountTr ; i++)
        {
            if (!obj->m_visible) return;
    
            float color[12];
            if(obj->triangles[i].color[0] < 0)
            {
                color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f;color[3] = obj->m_vis_koef;
                color[4] = 1.0f; color[5] = 1.0f; color[6] = 1.0f;color[7] = obj->m_vis_koef;
                color[8] = 1.0f; color[9] = 1.0f; color[10] = 1.0f;color[11] = obj->m_vis_koef;
            }
            else
            {
                color[0]  = obj->triangles[i].color[0]; color[1]  = obj->triangles[i].color[1];
                color[2]  = obj->triangles[i].color[2]; color[3]  = obj->triangles[i].color[3];
    
                color[4]  = obj->triangles[i].color[0]; color[5]  = obj->triangles[i].color[1];
                color[6]  = obj->triangles[i].color[2]; color[7]  = obj->triangles[i].color[3];
    
                color[8]  = obj->triangles[i].color[0]; color[9]  = obj->triangles[i].color[1];
                color[10] = obj->triangles[i].color[2]; color[11] = obj->triangles[i].color[3];
            }
            glActiveTexture(GL_TEXTURE0);
            if(obj->m_num_texture > 0)
                glBindTexture(GL_TEXTURE_2D,g_Texture[obj->m_num_texture] );
            else
                glBindTexture(GL_TEXTURE_2D, obj->triangles[i].numtex );
            shader.Uniform1i(texture, 0);
            float vertices[] = {
                    obj->triangles[i].verts[0].x, obj->triangles[i].verts[0].y, obj->triangles[i].verts[0].z,
                    obj->triangles[i].verts[1].x, obj->triangles[i].verts[1].y, obj->triangles[i].verts[1].z,
                    obj->triangles[i].verts[2].x, obj->triangles[i].verts[2].y, obj->triangles[i].verts[2].z
            };
            float texcoords[] = {
                    obj->triangles[i].tex[0].U, obj->triangles[i].tex[0].V,
                    obj->triangles[i].tex[1].U, obj->triangles[i].tex[1].V,
                    obj->triangles[i].tex[2].U, obj->triangles[i].tex[2].V
            };
            glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, vertices);
            checkGlError("glVertexAttribPointer");
            glEnableVertexAttribArray(pos);
            checkGlError("glEnableVertexAttribArray");
            glVertexAttribPointer(texpos, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
            checkGlError("glVertexAttribPointer");
            glEnableVertexAttribArray(texpos);
            checkGlError("glEnableVertexAttribArray");
            shader.Uniform1f(textureFlag, 1.0f);
            glVertexAttribPointer(a_color, 4, GL_FLOAT, GL_FALSE, 0, color);
            checkGlError("glVertexAttribPointer");
            glEnableVertexAttribArray(a_color);
            checkGlError("glEnableVertexAttribArray");
            glDrawArrays(GL_TRIANGLES, 0, 3);
            checkGlError("glDrawArrays");
    }
    

    顶点着色器:

    attribute vec3 a_Position;
    attribute vec2 a_TexCoord;
    attribute vec4 a_Color;
    
    varying vec2 v_TexCoord;
    varying vec4 v_Color;
    
    uniform mat4 u_projectionMatrix;
    uniform mat4 u_modelviewMatrix;
    
    void main(void) 
    {
        mat4 mvpMatrix = u_projectionMatrix*u_modelviewMatrix;
        gl_Position = mvpMatrix*vec4(a_Position, 1.0);
        v_TexCoord = a_TexCoord;
        v_Color = a_Color;
    }
    

    片段着色器:

    precision mediump float;
    
    varying vec2 v_TexCoord;
    varying vec4 v_Color;
    uniform sampler2D u_Texture;
    uniform float u_TextureFlag;
    
    void main(void) 
    {
        gl_FragColor = u_TextureFlag*texture2D(u_Texture,v_TexCoord)*v_Color + (1.0 - u_TextureFlag)*v_Color;
    }
    

    我试图将顶点数组和其他数据声明为float vertices[3*3*obj->CountTr];,并在循环中设置数组的值。循环后我绘制三角形: glDrawArrays(GL_TRIANGLES, 0, 3*obj->CountTr); 它工作得更快,但我不明白如何在必要时为三角形设置不同的纹理。

0 个答案:

没有答案