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中的纹理渲染的主要内容,如果未能解决你的问题,请参考以下文章