OpenGL 中的纹理渲染

Texture Rendering in OpenGL

我正在尝试在 openGL 中渲染纹理。我的代码是:

void startupDemo()
{
//  int x, y, z, i;

    time=0;
    timebase=0;
    frame=0;
    sprintf( fps_glut, "FPS:init in progress" );
    fpssss = 0.0;

    glClearColor(0.0, 0.0, 0.0, 0.9) ;
    //loadTextures();

    glShadeModel(GL_SMOOTH);
    //glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    // Enable lighting //////////////
    //glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0,GL_POSITION, g_lightPosition);
    glLightfv(GL_LIGHT0, GL_AMBIENT, g_lightAmbient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, g_lightDiffuse);

    // Mesh texture loading ////////////////////////////////////////////////////////////
    if( g_texture_pixmap = BMP_Loader("dididj.jpg" ) )
    {
        glGenTextures( 1, &mesh.textureId );

        // Creation d'un nouvel objetde texture //////////////
        glBindTexture(GL_TEXTURE_2D, mesh.textureId);

        // Stockage des data dans le nouvel objetde texture .
        glTexImage2D( GL_TEXTURE_2D, 0, 3, g_texture_width, g_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, g_texture_pixmap );
        printf( "\nLoading texture 1 on board ok." );

    }
    else
    {
        printf( "\nLoading texture 1 failed!" );
    }

    if( g_texture_pixmap )
    {
        delete [] g_texture_pixmap;
        g_texture_pixmap=NULL;
    }

    // Mesh texture loading ////////////////////////////////////////////////////////////
    if( g_texture_pixmap = BMP_Loader( "data/virus.bmp" ) )
    //if( g_texture_pixmap = BMP_Loader( "data/texture01.bmp" ) )
    {
        glGenTextures( 1, &g_texID );

        // Creation d'un nouvel objetde texture //////////////
        glBindTexture(GL_TEXTURE_2D, g_texID );

        // Stockage des data dans le nouvel objetde texture .
        glTexImage2D( GL_TEXTURE_2D, 0, 3, g_texture_width, g_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, g_texture_pixmap );
        printf( "\nLoading texture 2 on board ok." );

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

        // S et T : coordonnes du texel (texture element) ////////////////
        // GL_REPEAT:repetition du motif dans le sens des S (GL_TEXTURE_WRAP_S)
        // ou des T (GL_TEXTURE_WRAP_T) ///////////////////////////////////////
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        // Positionne la fonction de texture active (cioe les valeurs des texels
        // peuvent moduler la couleur dans laquelle le polygone serait rendu en
        // l'absence de texture, ou plus simplement comment sont combinees les
        // valeurs des texels avec les valeurs chromatiques du fragment traite)... ouf!
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
        //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    }
    else
    {
        printf( "\nLoading texture 2 failed!" );
    }

    if( g_texture_pixmap )
    {
        delete [] g_texture_pixmap;
        g_texture_pixmap=NULL;
    }

/*
    if( mesh.load( "data/chrome_logo.asc" ) )
    {
        shutdownDemo();
        exit(0);
    }

    mesh.preProcess();

*/



    glEnable(GL_DEPTH_TEST);                            // Turn depth testing on

    // This is where we initialize our empty texture to be rendered too.
    // We pass in the texture array to store it, the texture size,
    // the channels (3 for R G B), the type of texture (RGB) and texture ID.
    CreateBlankRenderTexture( &g_tex_0_ID, 512, 3, GL_RGB);

    // Create the texture map for the spinning cube and assign it to texture ID 1
    //CreateTexture(g_Texture, "Brick.bmp", 1);
    g_tex_1_ID = g_texID;

}

我是 OpenGL 的新手,我已经尝试调试代码但仍然没有得到结果。尽管收到以下警告,但我已验证函数的参数是否正确:

C:\Users\HP\Desktop\cg\project\main.cpp||In function 'void startupDemo()':|
C:\Users\HP\Desktop\cg\project\main.cpp|744|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|
C:\Users\HP\Desktop\cg\project\main.cpp|768|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|

我之前也看到过这个警告,我认为它是无害的,所以不会成为错误的来源。

WRT Weather Vane 的评论:使用此功能的程序有效,除了纹理加载失败和在终端上时不会崩溃 "Texture loading failed" 打印出来。

正如其名称所示,您的函数 BMP_Loader() 适用于位图文件。

它的实现包含对位图结构的引用

data = (Byte_ *)(fileBuffer + sizeof(sBMP_header) + sizeof(sBMP_info) );

但您要求它处理 JPG 文件。

您上面的评论说即使是位图文件也不起作用。也许它们是错误的格式(你测试一下)。也许位图 struct 声明是错误的(没有贴出来,但我看到字段名称已被翻译成法语。也许它们应该是 packed。也许数字字段的字节顺序是错误的。

使用调试器,找出哪一行从函数BMP_Loader().

返回NULL

UPDATE - 此示例显示打包 struct 的不同之处。没有它,您的声明将不符合 header 格式。

#include <stdio.h>

typedef unsigned int Dword_;    // 32 bits
typedef unsigned short Word_;   // 16 bits
typedef unsigned char Byte_;    // 8 bits

#pragma pack(push, 1)
typedef struct tagBITMAPFILEHEADER {      // my struct
    Word_  bfType;
    Dword_ bfSize;
    Word_  bfReserved1;
    Word_  bfReserved2;
    Dword_ bfOffBits;
} BITMAPFILEHEADER;
#pragma pack(pop)

struct sBMP_header                        // your struct
{
    Word_ codmag;
    Dword_ taille;
    Word_ reserv1;
    Word_ reserv2;
    Dword_ offsetImage;
};

int main(int argc, char const *argv[])
{
    printf ("My struct size %d\n", sizeof(BITMAPFILEHEADER));
    printf ("Your struct size %d\n", sizeof(struct sBMP_header));
    return 0;
}

程序输出:

My struct size 14
Your struct size 16

我不知道你的编译器会对pack结构使用什么语法(我的是 MSVC)。没有它,第一个 Word_ 字段之后的下一个字段对齐到 32 位,并且相邻的一对 Word_ 字段一起占用 32 位,这解释了 16 位大小的差异。

另一个structs也是如此。