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();
}