多种色彩的位图通常称为像素贴图,并且勇于图像或纹理的背景。在OpenGL中,像素贴图或者为8位颜色索引图像,或者为24位RGB图像。像素贴图也可能含有透明的信息,称为aphla通道。在OpenGL中,提供了glDrawPixels函数勇于会址像素贴图,该函数使用当前光栅位置定位图像的左下角,但该函数不能指定光栅的初始位置或移动光栅。
1) glDrawPixels(),该函数的格式为:
glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
其中,width和height指定图像的宽度和高度(注意像素贴图是上下倒置的,通过指定一个负的高度可以将图倒置过来);format参数指定像素格式,OpenGL中的像素格式如下表所示:
type参数指定像素参数的类型,OpenGL中的像素贴图类型有:
pixels参数指向图像数据。
2)glBitmap(),该函数原型为:
glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
其中,width和height表示图像的宽和高,xorig和yorig表示位图中心,xmove和ymove表示位图绘制完成后,光栅移动的位置。另外,glRasterPos2i或glRasterPos2f指定光栅的位置(类似glVertex3f指定坐标)。
3)glPixelZoon()缩放位图。
glPixelZoom(GLfloat xfactor, GLfloat yfactor); glPixelZoom(1.0, 1.0); // Don't scale the image glPixelZoom( -1.0, 1.0); // Flip the image horizontally glPixelZoom(0.33, 0.33); // Draw the image 1/3 size
4)glCopyPixels()复制图像,其原型:
glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
此函数从指定的帧缓冲区将像素数据复制到当前光栅维护。使用glRasterPos设置当前的光栅位置,还可以使用glPixelZoon设置缩放比例,其中x,y表示复制起点坐标(左下角为(0,0)),width和height复制的宽和高,type设置要复制的类型,包括GL_COLOR、GL_STENCIL(模板)、GL_DEPTH。
// Operations.cpp // OpenGL SuperBible // Demonstrates Imaging Operations // Program by Richard S. Wright Jr. #include <GL/glut.h> // OpenGL toolkit #include <cmath> using namespace std; ////////////////////////////////////////////////////////////////// // Module globals to save source image data static GLbyte *pImage = NULL; static GLint iWidth, iHeight, iComponents; static GLenum eFormat; // Global variable to store desired drawing mode static GLint iRenderMode = 1; ////////////////////////////////////////////////////////////////// // This function does any needed initialization on the rendering // context. void SetupRC_BITMAP(void) { // Black background glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Load the horse image glPixelStorei(GL_UNPACK_ALIGNMENT, 1); pImage = gltLoadTGA("horse.tga", &iWidth, &iHeight, &iComponents, &eFormat); } void ShutdownRC_BITMAP(void) { // Free the original image data free(pImage); } /////////////////////////////////////////////////////////////////////////////// // Reset flags as appropriate in response to menu selections void ProcessMenu_BITMAP(int value) { if(value == 0) // Save image gltWriteTGA("ScreenShot.tga"); else // Change render mode index to match menu entry index iRenderMode = value; // Trigger Redraw glutPostRedisplay(); } /////////////////////////////////////////////////////////////////////// // Called to draw scene void RenderScene_BITMAP(void) { GLint iViewport[4]; GLbyte *pModifiedBytes = NULL; GLfloat invertMap[256]; GLint i; // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT); // Current Raster Position always at bottom left hand corner of window glRasterPos2i(0, 0); // Do image operation, depending on rendermode index switch(iRenderMode) { case 2: // Flip the pixels glPixelZoom(-1.0f, -1.0f); glRasterPos2i(iWidth, iHeight); break; case 3: // Zoom pixels to fill window glGetIntegerv(GL_VIEWPORT, iViewport); glPixelZoom((GLfloat) iViewport[2] / (GLfloat)iWidth, (GLfloat) iViewport[3] / (GLfloat)iHeight); break; case 4: // Just Red glPixelTransferf(GL_RED_SCALE, 1.0f); glPixelTransferf(GL_GREEN_SCALE, 0.0f); glPixelTransferf(GL_BLUE_SCALE, 0.0f); break; case 5: // Just Green glPixelTransferf(GL_RED_SCALE, 0.0f); glPixelTransferf(GL_GREEN_SCALE, 1.0f); glPixelTransferf(GL_BLUE_SCALE, 0.0f); break; case 6: // Just Blue glPixelTransferf(GL_RED_SCALE, 0.0f); glPixelTransferf(GL_GREEN_SCALE, 0.0f); glPixelTransferf(GL_BLUE_SCALE, 1.0f); break; case 7: // Black & White, more tricky // First draw image into color buffer glDrawPixels(iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pImage); // Allocate space for the luminance map pModifiedBytes = (GLbyte *)malloc(iWidth * iHeight); // Scale colors according to NSTC standard glPixelTransferf(GL_RED_SCALE, 0.3f); glPixelTransferf(GL_GREEN_SCALE, 0.59f); glPixelTransferf(GL_BLUE_SCALE, 0.11f); // Read pixles into buffer (scale above will be applied) glReadPixels(0,0,iWidth, iHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pModifiedBytes); // Return color scaling to normal glPixelTransferf(GL_RED_SCALE, 1.0f); glPixelTransferf(GL_GREEN_SCALE, 1.0f); glPixelTransferf(GL_BLUE_SCALE, 1.0f); break; case 8: // Invert colors invertMap[0] = 1.0f; for(i = 1; i < 256; i++) invertMap[i] = 1.0f - (1.0f / 255.0f * (GLfloat)i); glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 255, invertMap); glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 255, invertMap); glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 255, invertMap); glPixelTransferi(GL_MAP_COLOR, GL_TRUE); break; case 1: // Just do a plain old image copy default: // This line intentially left blank break; } // Do the pixel draw if(pModifiedBytes == NULL) glDrawPixels(iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pImage); else { glDrawPixels(iWidth, iHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pModifiedBytes); free(pModifiedBytes); } // Reset everyting to default glPixelTransferi(GL_MAP_COLOR, GL_FALSE); glPixelTransferf(GL_RED_SCALE, 1.0f); glPixelTransferf(GL_GREEN_SCALE, 1.0f); glPixelTransferf(GL_BLUE_SCALE, 1.0f); glPixelZoom(1.0f, 1.0f); // No Pixel Zooming // Do the buffer Swap glutSwapBuffers(); } void ChangeSize_BITMAP(int w, int h) { // Prevent a divide by zero, when window is too short // (you cant make a window of zero width). if(h == 0) h = 1; glViewport(0, 0, w, h); // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the clipping volume gluOrtho2D(0.0f, (GLfloat) w, 0.0, (GLfloat) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } ///////////////////////////////////////////////////////////// // Main program entrypoint int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GL_DOUBLE); glutInitWindowSize(800 ,600); glutCreateWindow("OpenGL Image Operations"); glutReshapeFunc(ChangeSize_BITMAP); glutDisplayFunc(RenderScene_BITMAP); // Create the Menu and add choices glutCreateMenu(ProcessMenu_BITMAP); glutAddMenuEntry("Save Image",0); glutAddMenuEntry("Draw Pixels",1); glutAddMenuEntry("Flip Pixels",2); glutAddMenuEntry("Zoom Pixels",3); glutAddMenuEntry("Just Red Channel",4); glutAddMenuEntry("Just Green Channel",5); glutAddMenuEntry("Just Blue Channel",6); glutAddMenuEntry("Black and White", 7); glutAddMenuEntry("Invert Colors", 8); glutAttachMenu(GLUT_RIGHT_BUTTON); SetupRC_BITMAP(); // Do setup glutMainLoop(); // Main program loop ShutdownRC_BITMAP(); // Do shutdown return 0; }
关于gltLoadTGA函数,请参考:OpenGL蓝宝书中的:gltLoadTGA报错。
作者:kezunhai出处:http://blog.csdn.net/kezunhai欢迎转载或分享,但请务必声明文章出处。