opengl 입문 강좌 의 학습 노트

13871 단어 OPENGL 학습
1. 작은 공 회전
지식 포인트: 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();
}

좋은 웹페이지 즐겨찾기