《OpenGL超级宝典4》学习笔记——第七章(一)

绘制位图:

void glBitmap( GLsize width , GLsize height, GLfloat xorig , GLfloat yorig , GLfloat xmove , GLfloat ymove , Glubyte*bitmap);

前两个参数width和height指定位图的宽度和高度,xorig和yorig指定位图的原点,xmove和ymove指定一个偏移量,在位图被渲染之后把光栅位置在x和y方向移动这个量,最后一个参数bitmap就是一个指向位图数据的指针。

 

像素包装:

void glPixelStorei(GLenum pname , GLintparam);

void glPixelStoref(GLenum pname , GLfloatparam);

 

像素图:

void glDrawPixels( GLsizei  width , GLsizei  height ,GLenum format , GLenum type,const  void* pixels);

 

读取像素数据:

void glReadPixels( GLint x, GLint y , GLsizei  width , GLsizei  height ,GLenum format , GLenum type,const  void* pixels);


// Operations.cpp
// OpenGL SuperBible
// Demonstrates Imaging Operations
// Program by Richard S. Wright Jr.

#include "../../shared/gltools.h"	// OpenGL toolkit
#include <math.h>

//
// 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(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(void)
{
	// Free the original image data
	free(pImage);
}


///
// Reset flags as appropriate in response to menu selections
void ProcessMenu(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(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(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);
	glutDisplayFunc(RenderScene);

	// Create the Menu and add choices
	glutCreateMenu(ProcessMenu);
	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();          // Do setup

	glutMainLoop();     // Main program loop

	ShutdownRC();       // Do shutdown

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值