纹理不适用于glBindTexture

时间:2013-12-08 01:22:46

标签: c++ opengl texture-mapping

我有一个纹理工作,但我无法弄清楚如何在2之间切换,或glBindTexture实际上是如何工作的。

我从某个地方复制了它并且它有效,我相信我理解它的大部分内容。问题是,我可以取消注释glBindTexture(GL_TEXTURE_2D, texture[0].texID);并且它有效。我不明白。这段代码不应该成为一个问题,我认为这是一个很简单的问题。

bool LoadTGA(TextureImage *texture, char *filename)         // Loads A TGA File Into Memory
{    
    GLubyte     TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};    // Uncompressed TGA Header
    GLubyte     TGAcompare[12];                             // Used To Compare TGA Header
    GLubyte     header[6];                                  // First 6 Useful Bytes From The Header
    GLuint      bytesPerPixel;                              // Holds Number Of Bytes Per Pixel Used In The TGA File
    GLuint      imageSize;                                  // Used To Store The Image Size When Setting Aside Ram
    GLuint      temp;                                       // Temporary Variable
    GLuint      type=GL_RGBA;                               // Set The Default GL Mode To RBGA (32 BPP)

    system("cd");

    FILE *file = fopen(filename, "r");                      // Open The TGA File

    if( file==NULL ||                                       // Does File Even Exist?
        fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) ||  // Are There 12 Bytes To Read?
        memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0               ||  // Does The Header Match What We Want?
        fread(header,1,sizeof(header),file)!=sizeof(header))                // If So Read Next 6 Header Bytes
    {

        if (file == NULL)                                   // Did The File Even Exist? *Added Jim Strong*
        {
            perror("Error");
            return false;                                   // Return False
        }
        else
        {
            fclose(file);                                   // If Anything Failed, Close The File
            perror("Error");
            return false;                                   // Return False
        }

    }

    texture->width  = header[1] * 256 + header[0];          // Determine The TGA Width  (highbyte*256+lowbyte)
    texture->height = header[3] * 256 + header[2];          // Determine The TGA Height (highbyte*256+lowbyte)

    if( texture->width  <=0 ||                              // Is The Width Less Than Or Equal To Zero
        texture->height <=0 ||                              // Is The Height Less Than Or Equal To Zero
        (header[4]!=24 && header[4]!=32))                   // Is The TGA 24 or 32 Bit?
    {
        fclose(file);                                       // If Anything Failed, Close The File
        return false;                                       // Return False
    }

    texture->bpp    = header[4];                            // Grab The TGA's Bits Per Pixel (24 or 32)
    bytesPerPixel   = texture->bpp/8;                       // Divide By 8 To Get The Bytes Per Pixel
    imageSize       = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data

    texture->imageData=(GLubyte *)malloc(imageSize);        // Reserve Memory To Hold The TGA Data

    if( texture->imageData==NULL ||                         // Does The Storage Memory Exist?
        fread(texture->imageData, 1, imageSize, file)!=imageSize)   // Does The Image Size Match The Memory Reserved?
    {
        if(texture->imageData!=NULL)                        // Was Image Data Loaded
            free(texture->imageData);                       // If So, Release The Image Data

        fclose(file);                                       // Close The File
        return false;                                       // Return False
    }

    for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel)     // Loop Through The Image Data
    {                                                       // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
        temp=texture->imageData[i];                         // Temporarily Store The Value At Image Data 'i'
        texture->imageData[i] = texture->imageData[i + 2];  // Set The 1st Byte To The Value Of The 3rd Byte
        texture->imageData[i + 2] = temp;                   // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
    }

    fclose (file);                                          // Close The File

    // Build A Texture From The Data
    glGenTextures(1, &texture[0].texID);                    // Generate OpenGL texture IDs

    //glBindTexture(GL_TEXTURE_2D, texture[0].texID);           // Bind Our Texture
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   // Linear Filtered
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   // Linear Filtered
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    if (texture[0].bpp==24)                                 // Was The TGA 24 Bits
    {
        type=GL_RGB;                                        // If So Set The 'type' To GL_RGB
    }

    glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);

    return true;

现在,当我画画时,我有这个:

glEnable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, texturesList[0].texID);
glColor4f(1, 1, 1, 1);
glBegin(GL_POLYGON);
    glTexCoord2f(0.0f, 0.0f);
    glVertex4f(-50, 0, 50, 1);
    glTexCoord2f(50.0f, 0.0f);
    glVertex4f(-50, 0, -50, 1);
    glTexCoord2f(50.0f, 50.0f);
    glVertex4f(50, 0, -50, 1);
    glTexCoord2f(0.0f, 50.0f);
    glVertex4f(50, 0, 50, 1);
glEnd();

glDisable(GL_TEXTURE_2D); 

这是在计划开始时:

LoadTGA(&texturesList[0], "\snow.tga");
LoadTGA(&texturesList[1], "\snow2.tga");

因此在加载之后,texturesList包含2个纹理,其中ID为1和2。 所以,在绘制选择合适的纹理之前,我不会调用glBindTexture(GL_TEXTURE_2D, texturesList[0].texID);吗?因为我必须告诉glTexCoord2f要操作什么?

如果我在抽奖中从不打电话给glBind,它会很有效,但如果我什么都不做就会出现。我更困惑的是,glBind并不需要被调用才能工作。

但我创建的最后一个纹理会显示出来(snow2.tga)。

如果我能清除任何事情,请告诉我。

1 个答案:

答案 0 :(得分:3)

  

所以在绘制之前我不能调用 glBindTexture(GL_TEXTURE_2D,texturesList [0] .texID); 来选择合适的纹理?因为我必须告诉 glTexCoord2f 操作什么?

glTexCoord2f (...)以每顶点级别运行。它与你加载的纹理无关,实际上就是整点。您可以通过更改绘制时绑定的纹理来映射所需的任何纹理。


  

如果我在抽奖中从不打电话给 glBind ,它会很有效,但如果我什么都不做就会出现。我更困惑的是, glBind 不需要被调用才能工作。

您需要在LoadTGA (...)中绑定纹理,因为单独生成“名称”是不够的。

glGenTextures (...)所做的就是从OpenGL对纹理的名称列表中返回一个或多个未使用的名称并保留它们,以便后续调用不会给出相同的名称。

实际上没有创建纹理,返回的名称在绑定之前不会成为纹理。在此之前,该名称仅处于 保留 状态。 glTexParameterf (...)glTexImage2D (...)等命令对当前绑定纹理进行操作,因此除了生成纹理之外,还必须在进行这些调用之前绑定一个纹理。


现在,处理与OpenGL无关的其他一些严重问题:

尽一切可能摆脱你的system ("cd");行。有更好的方法可以更改工作目录。

  1. SetCurrentDirectory (...)(Windows)中
  2. chdir (...)(Linux / OS X / BSD / POSIX)
  3. 不要将文件名“\ snow.tga”用作字符串文字,因为C编译器可能会看到“\”并将其后面的内容解释为逃脱序列的一部分。考虑“\\ snow.tga”“/ snow.tga”(是的,这甚至适用于Windows - “\”是一个可怕的角色用作路径分隔符。)

    “\ s”实际上并不是C编译器识别的转义序列,但是使用“\”来开始你的路径是因为有少数人在玩火保留字符的实际重要性。例如,“\ fire.tga”实际上是 {0x0c}“ire.tga”的简写。编译器会用你的字节序列替换你的字符串文字,这会让你摸不着头脑,试图弄清楚出了什么问题。