opengl 입문 강좌 의 학습 노트
                                            
 13871 단어  OPENGL 학습
                    
지식 포인트: 1. 빛, 시각, 재질, 행렬 변환 의 기본 용법
2. FPS 계산
#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
#define WIDTH 400
#define HEIGHT 400
//#define ColoredVertex(c,v) do{glColor3fv(c);glVertex3fv(v);}while(0)
GLfloat angle=0.0f;
static int day =200;
double CalFrequency()
{
	static int count;
	static double save;
	static clock_t last,current;
	double timegap;
	++count;
	if(count<=50)
		return save;
	count = 0;
	last = current;
	current = clock();
	timegap = (current-last)/(double)CLK_TCK;
	save = 50.0/timegap;
	return save;
}
void myDisplay(void)
{
	double FPS=CalFrequency();
	printf("FPS=%f
",FPS);
	
	
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.0f,1.0f,1.0f,20.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0,5.0,-10.0,0,0,0,0,1,0);
	
	{
		GLfloat sun_light_position[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat sun_light_ambient[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat sun_light_diffuse[]={1.0f,1.0f,1.0f,1.0f};
		GLfloat sun_light_specular[]={1.0f,1.0f,1.0f,1.0f};
		glLightfv(GL_LIGHT0,GL_POSITION,sun_light_position);
		glLightfv(GL_LIGHT0,GL_AMBIENT,sun_light_ambient);
		glLightfv(GL_LIGHT0,GL_DIFFUSE,sun_light_diffuse);
		glLightfv(GL_LIGHT0,GL_SPECULAR,sun_light_specular);
		glEnable(GL_LIGHT0);
		glEnable(GL_LIGHTING);
		glEnable(GL_DEPTH_TEST);
	}
	
	{
		GLfloat sun_mat_ambient[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat sun_mat_diffuse[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat sun_mat_specular[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat sun_mat_emission[]={0.5f,0.0f,0.0f,1.0f};
		GLfloat sun_mat_shininess = 0.0f;
		glMaterialfv(GL_FRONT,GL_AMBIENT,sun_mat_ambient);
		glMaterialfv(GL_FRONT,GL_DIFFUSE,sun_mat_diffuse);
		glMaterialfv(GL_FRONT,GL_SPECULAR,sun_mat_specular);
		glMaterialfv(GL_FRONT,GL_EMISSION,sun_mat_emission);
		glMaterialfv(GL_FRONT,GL_SHININESS,&sun_mat_shininess);
		glutSolidSphere(2.0,40,32);
	}
	
	{
		GLfloat earth_mat_ambient[]={0.0f,0.0f,0.5f,1.0f};
		GLfloat earth_mat_diffuse[]={0.0f,0.0f,0.5f,1.0f};
		GLfloat earth_mat_specular[]={0.0f,0.0f,1.0f,1.0f};
		GLfloat earth_mat_emission[]={0.0f,0.0f,0.0f,1.0f};
		GLfloat earth_mat_shininess = 30.0f;
		glMaterialfv(GL_FRONT,GL_AMBIENT,earth_mat_ambient);
		glMaterialfv(GL_FRONT,GL_DIFFUSE,earth_mat_diffuse);
		glMaterialfv(GL_FRONT,GL_SPECULAR,earth_mat_specular);
		glMaterialfv(GL_FRONT,GL_EMISSION,earth_mat_emission);
		glMaterialfv(GL_FRONT,GL_SHININESS,&earth_mat_shininess);
		
		glRotatef(angle,0.0f,1.0f,0.0f);
		glTranslatef(5.0f,0.0f,0.0f);
		glutSolidSphere(2.0,40,32);
	}
	
	//glFlush();
	glutSwapBuffers();
}
void myIdle(void)
{
	angle+=1.0f;
	if(angle>=360.0f)
		angle=0.0f;
	myDisplay();
}
int _tmain(int argc, char* argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
	glutInitWindowPosition(200,200);
	glutInitWindowSize(WIDTH,HEIGHT);
	glutCreateWindow("tanrunj");
	glutDisplayFunc(myDisplay);
	glutIdleFunc(myIdle);
	
	glutMainLoop();
	
	return 0;
}
     2. 그림 읽 기
지식 포인트: 1. BMP 파일 의 정확 한 읽 기
2. glReadPixels 의 정확 함
#define BMP_Header_Length 54
void grab(void)
{
	FILE* pDummyFile;
	FILE* pWritingFile;
	GLubyte* pPixelData;
	GLubyte BMP_Header[BMP_Header_Length];
	GLint i,j;
	GLint PixelDataLength;
	i=WindowWidth*3;
	while(i%4!=0)
		i++;
	PixelDataLength=i*WindowHeight;
	//    ,   
	pPixelData=(GLubyte*)malloc(PixelDataLength);
	if(pPixelData==0)
		exit(0);
	fopen_s(&pDummyFile,"dummy.bmp","rb");
	if(pDummyFile==0)
		exit(0);
	fopen_s(&pWritingFile ,"grab.bmp","wb");
	if(pWritingFile==0)
		exit(0);
	//    
	glPixelStorei(GL_UNPACK_ALIGNMENT,4);
	glReadPixels(0,0,WindowWidth,WindowHeight,
		GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData);
	// dummy.bmp           
	//pDummy->bmp_header
	fread(BMP_Header,sizeof(BMP_Header),1,pDummyFile);
	//bmp_header->pwriting
	fwrite(BMP_Header,sizeof(BMP_Header),1,pWritingFile);
	fseek(pWritingFile,0x0012,SEEK_SET);
	i=WindowWidth;
	j=WindowHeight;
	//      
	fwrite(&i,sizeof(i),1,pWritingFile);
	fwrite(&j,sizeof(j),1,pWritingFile);
	//    
	fseek(pWritingFile,0,SEEK_END);
	fwrite(pPixelData,PixelDataLength,1,pWritingFile);
	//    ,   
	fclose(pDummyFile);
	fclose(pWritingFile);
	free(pPixelData);
}
3. 스티커
지식 포인트: 1. 텍 스 처 불 러 오기
2. 스티커 사용법
// ConsoleApplication1.cpp : ¶¨Òå¿ØÖÆÌ¨Ó¦ÓóÌÐòµÄÈë¿Úµã¡£
//
#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
#define WIDTH 400
#define HEIGHT 400
#define WindowWidth 400
#define WindowHeight 400
//grab      
#define BMP_Header_Length 54
void grab(void)
{
	FILE* pDummyFile;
	FILE* pWritingFile;
	GLubyte* pPixelData;
	GLubyte BMP_Header[BMP_Header_Length];
	GLint i,j;
	GLint PixelDataLength;
	i=WindowWidth*3;
	while(i%4!=0)
		i++;
	PixelDataLength=i*WindowHeight;
	//    ,   
	pPixelData=(GLubyte*)malloc(PixelDataLength);
	if(pPixelData==0)
		exit(0);
	fopen_s(&pDummyFile,"dummy.bmp","rb");
	if(pDummyFile==0)
		exit(0);
	fopen_s(&pWritingFile ,"grab.bmp","wb");
	if(pWritingFile==0)
		exit(0);
	//    
	glPixelStorei(GL_UNPACK_ALIGNMENT,4);
	glReadPixels(0,0,WindowWidth,WindowHeight,
		GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData);
	// dummy.bmp           
	//pDummy->bmp_header
	fread(BMP_Header,sizeof(BMP_Header),1,pDummyFile);
	//bmp_header->pwriting
	fwrite(BMP_Header,sizeof(BMP_Header),1,pWritingFile);
	fseek(pWritingFile,0x0012,SEEK_SET);
	i=WindowWidth;
	j=WindowHeight;
	//      
	fwrite(&i,sizeof(i),1,pWritingFile);
	fwrite(&j,sizeof(j),1,pWritingFile);
	//    
	fseek(pWritingFile,0,SEEK_END);
	fwrite(pPixelData,PixelDataLength,1,pWritingFile);
	//    ,   
	fclose(pDummyFile);
	fclose(pWritingFile);
	free(pPixelData);
}
//    2   
int power_of_two(int n)
{
	if(n<=0)
		return 0;
	return (n&(n-1))==0;
}
GLfloat angle=0.0f;
GLuint load_texture(const char* file_name)
{
	GLint width,height,total_bytes;
	GLubyte* pixels = 0;
	GLint last_texture_ID;
	GLuint texture_ID = 0;
	//    
	FILE* pFile ;
	fopen_s(&pFile,file_name,"rb");
	if(pFile==0)
		return 0;
	//    
	fseek(pFile,0x0012,SEEK_SET);
	fread(&width,4,1,pFile);
	fread(&height,4,1,pFile);
	fseek(pFile,BMP_Header_Length,SEEK_SET);
	//         
	{
		GLint line_bytes = width*3;
		while (line_bytes%4!=0)
			++line_bytes;
		total_bytes = line_bytes*height;
	}
	pixels = (GLubyte*)malloc(total_bytes);
	if(pixels==0)
	{
		fclose(pFile);
		return 0;
	}
	if(fread(pixels,total_bytes,1,pFile)<=0)
	{
		free(pixels);
		fclose(pFile);
		return 0;
	}
	//   ,                
	{
		GLint max;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max);
		if(!power_of_two(width)||
			!power_of_two(height)||
			width>max||height>>max)
		{
			const GLint new_width = 256;
			const GLint new_height = 256;
			GLint new_line_bytes,new_total_bytes;
			GLubyte* new_pixels = 0;
			//    
			new_line_bytes =new_width*3;
			while (new_line_bytes%4!=0)
				++new_line_bytes;
			new_total_bytes=new_line_bytes*new_height;
			//    
			new_pixels=(GLubyte*)malloc(new_total_bytes);
			//    
			if(new_pixels==0)
			{
				free(pixels);
				fclose(pFile);
				return 0;
			}
			//    
			gluScaleImage(GL_RGB,width,height,GL_UNSIGNED_BYTE,pixels,
				new_width,new_height,GL_UNSIGNED_BYTE,new_pixels);
			//  ,     ,    
			free(pixels);
			pixels = new_pixels;
			width = new_width;
			height = new_height;
		}
		}
		//      
		glGenTextures(1,&texture_ID);
		if(texture_ID ==0)
		{
			free(pixels);
			fclose(pFile);
			return 0;
		}
		//        
		//    ,    
		//   ,      ,    
		glGetIntegerv(GL_TEXTURE_BINDING_2D,&last_texture_ID);
		glBindTexture(GL_TEXTURE_2D,texture_ID);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
		glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,
			GL_BGR_EXT,GL_UNSIGNED_BYTE,pixels);
		glBindTexture(GL_TEXTURE_2D,last_texture_ID);
		//pixels   glteximage2d     ,          
		free(pixels);
		return texture_ID;
		
}
//  FPS
double CalFrequency()
{
	static int count;
	static double save;
	static clock_t last,current;
	double timegap;
	++count;
	if(count<=50)
		return save;
	count = 0;
	last = current;
	current = clock();
	timegap = (current-last)/(double)CLK_TCK;
	save = 50.0/timegap;
	return save;
}
//    
GLuint texGround;
GLuint texWall;
void myDisplay(void)
{
	double FPS=CalFrequency();
	printf("FPS=%f
",FPS);
	
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	//  
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(75,1,1,21);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(1,5,5,0,0,0,0,0,1);
	
	//   
	glBindTexture(GL_TEXTURE_2D,texGround);
	glBegin(GL_QUADS);
	glTexCoord2f(0,0); glVertex3f(-8,-8,0);
	glTexCoord2f(0,5); glVertex3f(-8,8,0);
	glTexCoord2f(5,5); glVertex3f(8,8,0);
	glTexCoord2f(5,0); glVertex3f(8,-8,0);
	glEnd();
	//  
	glBindTexture(GL_TEXTURE_2D,texWall);
	glBegin(GL_QUADS);
	glTexCoord2d(0,0); glVertex3f(-6,-3,0);
	glTexCoord2d(0,1); glVertex3f(-6,-3,1.5);
	glTexCoord2f(5,1); glVertex3f(6,-3,1.5);
	glTexCoord2f(5,0); glVertex3f(6,-3,0);
	glEnd();
	//      
	glRotatef(-90,0,0,1);
	glBegin(GL_QUADS);
	glTexCoord2f(0,0); glVertex3f(-6,-3,0);
	glTexCoord2f(0,1); glVertex3f(-6,-3,1.5);
	glTexCoord2f(5,1); glVertex3f(6,-3,1.5);
	glTexCoord2f(5,0); glVertex3f(6,-3,0);
	glEnd();
	
	glutSwapBuffers();
	grab();
}
//    
void myIdle(void)
{
	angle+=1.0f;
	if(angle>=360.0f)
		angle=0.0f;
	myDisplay();
}
int _tmain(int argc, char* argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
	glutInitWindowPosition(200,200);
	glutInitWindowSize(WIDTH,HEIGHT);
	glutCreateWindow("tanrunj");
	glutDisplayFunc(myDisplay);
	
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	texGround = load_texture("ground.bmp");
	texWall = load_texture("wall.bmp");
	glutIdleFunc(myIdle);
	
	glutMainLoop();
	
	return 0;
}
     4. 색 혼합 (반투명 형성, 불투명 먼 곳 의 물건 을 먼저 그 려 야 함)
glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	setLight();
	//ÒÔ£¨0,0£¬0.5£©ÎªÖÐÐÄ£¬»æÖÆÒ»¸ö°ë¾¶Îª.3µÄ²»Í¸Ã÷ºìÇò£¬¾àÀë×îÔ¶
	setMatirial(red_color,30.0);
	glPushMatrix();
	glTranslatef(0,0,0.5);
	//°ë¾¶£¬¾Î³¶ÎÊý
	glutSolidSphere(0.3,30,30);
	glPopMatrix();
	//»æÖưë͸Ã÷£¬Éî¶È»º³åΪֻ¶Á
	//glDepthMask(GL_FALSE);
	//ÒÔ(0.2,0,-0.5)ΪÖÐÐÄ£¬»æÖÆ.2µÄ°ë͸Ã÷À¶Çò£¨×î½ü£©
	setMatirial(blue_color,30);
	glPushMatrix();
	glTranslatef(0.2,0,-0.5);
	glutSolidSphere(0.2,30,30);
	glPopMatrix();
	//ÒÔ(0.1,0,0)ΪÖÐÐÄ£¬»æÖÆ.15°ë͸Ã÷ÂÌÇò£¨Öм䣩
	setMatirial(green_color,30);
	glPushMatrix();
	glTranslatef(0.1,0,0);
	glutSolidSphere(0.15,30,30);
	glPopMatrix();
	//Íê³É°ë͸Ã÷£¬Éî¶È»Ö¸´¿É¶Á¿Éд
	glDepthMask(GL_TRUE);5. ALPHA 와 템 플 릿 테스트
void display(void)
{
    static int initialized   = 0;
    static GLuint texWindow  = 0;
    static GLuint texPicture = 0;
    //        ,  :    ,    ,    BGR     BGRA,      
    if( !initialized )
    {
        texPicture = load_texture("pic.bmp");
        texWindow  = load_texture("window.bmp");
        glBindTexture(GL_TEXTURE_2D, texWindow);
        texture_colorkey(255, 255, 255, 10);
        glEnable(GL_TEXTURE_2D);
        initialized = 1;
    }
    //     
    glClear(GL_COLOR_BUFFER_BIT);
    //     ,       Alpha  ,          
    glBindTexture(GL_TEXTURE_2D, texPicture);
    glDisable(GL_ALPHA_TEST);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0);     glVertex2f(-1.0f, -1.0f);
        glTexCoord2f(0, 1);     glVertex2f(-1.0f,  1.0f);
        glTexCoord2f(1, 1);     glVertex2f( 1.0f,  1.0f);
        glTexCoord2f(1, 0);     glVertex2f( 1.0f, -1.0f);
    glEnd();
    //     ,    Alpha  ,           
    glBindTexture(GL_TEXTURE_2D, texWindow);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.5f);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0);     glVertex2f(-1.0f, -1.0f);
        glTexCoord2f(0, 1);     glVertex2f(-1.0f,  1.0f);
        glTexCoord2f(1, 1);     glVertex2f( 1.0f,  1.0f);
        glTexCoord2f(1, 0);     glVertex2f( 1.0f, -1.0f);
    glEnd();
    //     
    glutSwapBuffers();
}void display(void)
{
    //     
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //      
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, 1, 5, 25);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5, 0, 6.5, 0, 0, 0, 0, 1, 0);
    glEnable(GL_DEPTH_TEST);
    //     
    glDisable(GL_STENCIL_TEST);
    draw_sphere();
    //        。              。
    //   ,                  ,                     。
    //             
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glEnable(GL_STENCIL_TEST);
    glDisable(GL_LIGHTING);
    glColor3f(0.5f, 0.5f, 0.5f);
    glDepthMask(GL_FALSE);
    glRectf(-1.5f, -1.5f, 1.5f, 1.5f);
    glDepthMask(GL_TRUE);
    //                    ,               
    //        X  Y       ,    Z          
    //                     ,      
    glStencilFunc(GL_EQUAL, 1, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glScalef(1.0f, 1.0f, -1.0f);
    draw_sphere();
    //     
    glutSwapBuffers();
    //   
    grab();
}