如何在 mac 中为 openGL 背景窗口使用纹理 .jpg 图像?
Posted
技术标签:
【中文标题】如何在 mac 中为 openGL 背景窗口使用纹理 .jpg 图像?【英文标题】:How can i use a texture .jpg image for an openGL background window in mac? 【发布时间】:2012-08-23 04:47:39 【问题描述】:我想为 mac 的 openGL 窗口设置背景。背景将采用 jpg 或 png 文件。
这是我的代码..
GLuint texture; //the array for our texture
GLfloat angle = 0.0;
GLuint LoadTexture (const char * filename, int width, int height )
// GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// // when texture area is small, bilinear filter the closest mipmap
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
// GL_LINEAR_MIPMAP_NEAREST );
// // when texture area is large, bilinear filter the original
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
//
// // the texture wraps over at the edges (repeat)
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
//
// //Generate the texture
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB, GL_UNSIGNED_BYTE, data);
// select modulate to mix texture with color for shading
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// when texture area is small, bilinear filter the closest mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST );
// when texture area is large, bilinear filter the first mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// // the texture wraps over at the edges (repeat)
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
// build our texture mipmaps
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data );
free(data);
return texture; //return whether it was successful
void FreeTexture( GLuint texture )
glDeleteTextures( 1, &texture );
void cube ()
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture
glPushMatrix();
glRotatef( angle, 0.0f, 0.0f, 1.0f );
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);
glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
glEnd();
glPopMatrix();
glutSwapBuffers();
//glutSolidCube(2);
void display ()
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
texture = LoadTexture( "/Users/macbook/MatrixEngineClientSample/Fighters/Sunset03.jpg", 256, 256 ); //load the texture
glEnable( GL_TEXTURE_2D ); //enable 2D texturing
// glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
// glEnable(GL_TEXTURE_GEN_T);
cube();
FreeTexture( texture );
//glutSwapBuffers();
//angle ++;
void reshape (int w, int h)
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
//glLoadIdentity ();
gluPerspective (50, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
int main (int argc, char **argv)
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutMainLoop ();
return 0;
编辑
我想将此图像视为 openGL 窗口的背景...图像在下方..
但它显示了这个......
【问题讨论】:
你需要说的太多了。什么失败了?你期望看到什么?您在代码中哪里看到了问题? FWIW,乍一看,您的代码正在加载文件的字节并尝试将其用作纹理位图。如果文件是您所说的 PNG 或 JPG,那将不起作用;这些文件类型需要先解码成位图。 @quixoto 我已经更新了我的问题...你能告诉我我的问题在哪里吗???你能通过提供任何代码或链接给我任何帮助吗,因为我在 openGL 中有点新。 现在它正在调用LoadTexture()
。您正在传递 JPEG 文件的路径,但 LoadTexture()
假定该文件是原始文件。您需要传入原始文件的路径,或者您需要编写一些代码来加载 JPEG 文件。例如,您可以使用 NSImage
读取 JPEG。
@user1118321 你能给我任何代码吗???因为我不知道我该怎么做。
【参考方案1】:
我咨询了this Apple guide。
问题是文件被压缩并且有一个标题,并且你的代码甚至使用文件标题的一部分作为图像源。
我会替换这段代码:
// GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
有了更类似的东西:
CFURLRef urlRef = (CFURLRef)[NSURL fileURLWithPath:@"/Users/macbook/MatrixEngineClientSample/Fighters/Sunset03.jpg"];
CGImageSourceRef myImageSourceRef = CGImageSourceCreateWithURL(url, NULL);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex(myImageSourceRef, 0, NULL);
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(myImageRef));
unsigned char *data = CFDataGetBytePtr(data);
您可能需要将 Core Graphics 和 Core Foundation 添加到链接框架列表中。
【讨论】:
据我所知,您正在尝试将 Objective-C 代码添加到 C++ 项目中。我认为这行不通。 您可以混合使用 Obj-C 和 C++。 Xcode 使用文件扩展名.hh
和.mm
作为同时使用两者的源代码。
以下苹果技术问答提供了示例代码,用于了解您可以使用上述代码访问的原始像素数据的格式:developer.apple.com/library/mac/qa/qa1509/_index.html【参考方案2】:
PNG 和 JPG 图像(与大多数其他图像格式一样)需要某种形式的解压缩/解码,因此从文件中原始加载它们不会产生预期的结果。在读取文件头后,它应该可以处理 bmp 或未压缩的 tga 图像:/。无论如何,这里有一些图像加载库应该可以让加载图像变得容易:
SOIL
DevIL
FreeImage
GLI
【讨论】:
当操作系统本机支持时,无需求助于一些难以编译的 3rd 方库。只需使用 Apple 提供的工具即可。 我从来没有遇到过任何问题。苹果提供哪些工具? 操作系统内置了对图像格式的支持。如果您使用 Apple 的,您的用户将自动获得对 Apple 在操作系统更新中添加的任何新格式的支持,以及错误修复等。当您使用 3rd 方库时,您只有在重新链接应用程序时才能获得错误修复3rd 方库并重新发布它。 那么,Apple 提供了哪些工具来从文件中加载图像? 如上所述,有NSImage
,也有CGImage
。 (例如,您可以使用CGImageCreateWithJPEGDataProvider()
。)以上是关于如何在 mac 中为 openGL 背景窗口使用纹理 .jpg 图像?的主要内容,如果未能解决你的问题,请参考以下文章
找不到使用 C# 在 openGL 中将纹理应用于 3d 对象的方法