现在的位置: 首页 > 综合 > 正文

学习OpenGL(六)光栅图形

2017年10月04日 ⁄ 综合 ⁄ 共 6104字 ⁄ 字号 评论关闭

        

学习OpenGL(六)光栅图形

kezunhai@gmail.com

http://blog.csdn.net/kezunhai

         多种色彩的位图通常称为像素贴图,并且勇于图像或纹理的背景。在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欢迎转载或分享,但请务必声明文章出处。

抱歉!评论已关闭.