OpenGL中的纹理渲染

Posted

技术标签:

【中文标题】OpenGL中的纹理渲染【英文标题】:Texture Rendering in OpenGL 【发布时间】:2015-04-19 18:50:16 【问题描述】:

我正在尝试在 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 的评论:使用此功能的程序有效,除了纹理加载失败和终端“纹理加载失败”外不会崩溃 被打印出来。

【问题讨论】:

这是一个“有些东西不起作用”的问题。程序是否运行但没有纹理?它会崩溃吗?它会给出错误消息吗? 可以通过将BMP_Loader的函数签名从BMP_Loader( char *name )更改为BMP_Loader( const char *name )来修复警告。当且仅当BMP_Loader 不尝试修改字符串时,警告才是无害的。 @user3386109 是的警告消失了。但是纹理仍然不起作用。 @WeatherVane 我在最后编辑了问题。 @Novak007:好吧,也许BMP_Loader() 不处理JPEG? 【参考方案1】:

顾名思义,您的函数BMP_Loader() 适用于位图文件。

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

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

但您要求它处理 JPG 文件。

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

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

UPDATE - 此示例显示了打包 struct 的区别。没有它,您的声明将与标题格式不匹配。

#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也是如此。

【讨论】:

请看头文件。 我再说一遍:结构必须打包并且它们是小端格式。 struct sBMP_header 是 16 号,应该是 14 号。 所以我应该把它设为 14 号。请详细说明一下。非常感谢。 结构 sBMP_header Dword_taille; dword_offsetImage; word_codmag; word_reserv1; word_reserv2; ;这样好吗?

以上是关于OpenGL中的纹理渲染的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL(FBO)中的普通后台缓冲区+渲染到深度纹理

无法使用 OpenGL 渲染 FBX 导入的纹理模型

如何为 OpenGL 文本渲染计算字符映射中的最佳字形边界

opengl:纹理删除

OpenGL渲染纹理全白

OpenGL渲染白色纹理错误