2012-12-31 48 views
1

我正在写一个原生应用程序,应该只显示一个带纹理的小三角形。
但不幸的是,它每次只显示一个白色的三角形。
我的代码很简单。android本地应用程序opengl es白色纹理

首先加载TGA图片

static const GLenum gl_format[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; 


unsigned int LoadTGATextureFromFile(const char* filename) 
{ 
    unsigned int handle; 
    unsigned char hdr[18]; 
    unsigned char file_id[256 + 1]; 
    int file; 

    file = open(filename, O_RDONLY); 
    if(file < 0) 
    { 
     Log(LOGLEVEL_ERROR, APPNAME, "Error: Failed to open tga file '%s' for read ing\n", filename); 
     return 0; 
    } 

    if(read(file, hdr, 18) != 18 || read(file, file_id, hdr[0]) != hdr[0]) 
    { 
     Log(LOGLEVEL_ERROR, APPNAME, "Error: Unexpected EOF while reading header of '%s'\n", filename); 
     close(file); 
     return 0; 
    } 
    file_id[hdr[0]] = 0; 
    if(hdr[1] != 0 || (hdr[2] != 2 && hdr[2] != 3) || (hdr[16] != 8 && hdr[16] != 16 && hdr[16] != 24 && hdr[16] != 32)) 
    { 
     Log(LOGLEVEL_ERROR, APPNAME, "Error: File '%s' has invalid format\n", filename); 
     close(file); 
     return 0; 
    } 
    int width = *(short*)(hdr + 12); 
    int height = *(short*)(hdr + 14); 
    if((width & (width - 1)) != 0 || (height & (height - 1)) != 0) 
    { 
     Log(LOGLEVEL_ERROR, APPNAME, "Error: File '%s' has invalid resolution %dx%d\n", filename, width, height); 
     close(file); 
     return 0; 
    } 
    int components = hdr[16]/8; 

    unsigned char* data = new unsigned char [width * height * components]; 
    if (read(file, data, width * height * components) != width * height * components) 
    { 
     Log(LOGLEVEL_ERROR, APPNAME, "Error: Unexpected EOF while reading image data of '%s'\n", filename); 
    close(file); 
     return 0; 
    } 
    close(file); 

    char dummy; 
    if(read(file, &dummy, 1) == 1) 
     Log(LOGLEVEL_ERROR, APPNAME, "Warning: TGA file '%s' has overlength\n", filename); 

    switch (components - 1) 
    { 
     char tmp; 
     case 2: 
      for (int i = 0; i < width * height; i += 3) 
      { 
       tmp = data[i]; 
       data[i] = data[i + 2]; 
       data[i + 2] = tmp; 
      } 
      break; 

     case 3: 
      for (int i = 0; i < width * height; i += 4) 
      { 
       tmp = data[i]; 
       data[i] = data[i + 2]; 
       data[i + 2] = tmp; 
      } 
      break; 

     default: 
      break; 
    } 

    glGenTextures(1, &handle); 
    glBindTexture(GL_TEXTURE_2D, handle); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glBindTexture(GL_TEXTURE_2D, 0); 

    delete [] data; 
    Log(LOGLEVEL_ERROR, APPNAME, "'%s' successfully loaded [handle = %d, FILE_ID = \"%s\", width = %d, height = %d, depth = %d] :)\n", filename, handle, file_id, width, height, components * 8); 

    return handle; 
} 

加载纹理

int texture = LoadTextureFormFile("/sdcard/test.tga"); 

然后绘制

float tricoords[6] = { 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 }; 
    float texcoords[6] = { 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 }; 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glVertexPointer(2, GL_FLOAT, 0, tricoords); 
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_VERTEX_ARRAY); 

我知道,这个代码没有经过优化,但它仅用于调试。

我的应用程序打印的logcat的:
成功加载TGA [手柄= 1,FILE_ID = “”,宽度= 64,高度= 128,深度= 32] :)

但质地保持白色。

回答

1

刚刚发现错误,纹理mipmapping为已加载的纹理启用了mipmaps从未创建。

更改该行:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

这将禁用的贴图的纹理。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
+2

你是什么意思“Android本身不支持它”?你不是简单地忽略了glGenerateMipMaps所需的(在ES 2.0中)吗? –

+1

我使用的是GLES 1.1,我刚才看到在“glext.h”中支持mipmap,你说得对,谢谢! – bricklore

+1

但它呢!在java-speak中:'gl.glTexParameterf(GL11.GL_TEXTURE_2D,GL11.GL_GENERATE_MIPMAP,GL11.GL_TRUE)'。只有ES1.0运气不好......也就是说,如果你的目标是旧硬件,你现在的解决方案是不使用mipmaps,可能会更好。 –