OpenGL Texturing Texture Mapping 31190 01 년봄학기 5/31/01 박경신 OpenGL에서텍스쳐맵핑 (texture mapping) 을위한 3 단계 텍스쳐활성화 glenable(gl_texture_d) 텍스쳐맵핑방법 ( 랩핑, 필터등 ) 정의 gltexparameteri(gl_texture_d, GL_TEXTURE_WRAP_S, GL_REPEAT) gltexparameteri(gl_texture_d, GL_TEXTURE_WRAP_T, GL_REPEAT) gltexparameteri(gl_texture_d, TEXTURE GL_TEXTURE_MAG_FILTER, GL_LINEAR) LINEAR) gltexparameteri(gl_texture_d, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glteximaged(gl_texture_d, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imagedata) 텍스쳐좌표 (texture coordinates) 지정 gltexcoordf(0, 0); glvertex3f(-1.0, 10-1.0, 10 0.0); 00); gltexcoordf(1, 0); glvertex3f(1.0, -1.0, 0.0); OpenGL Texture Names 텍스쳐의이름 (name) 지정하기 (textureid) GLuint textureid; glgentextures(1, &textureid); glbindtexture(gl_texture_d, TEXTURE textureid); t glteximaged( ); glbindtexture(gl_texture_d, TEXTURE 0); glbindtexture(gl_texture_d, textureid); glteximaged glteximaged(glenum target, GLint level, GLint internalformat, t GLsizei GLi iwidth, GLsizei GLi ihi height, ht GLint tborder, GLenum format, GLenum type, const GLvoid *pixels); target: GL_TEXTURE_D level: 텍스쳐맵의다양한해상도를지원하기위해설정. 1개의해상도를지정하려면 1로설정. 밉맵 (mipmapping) 에사용 각텍스쳐를위한다수의크기를가지고있는이미지를사용하지않는다면 0으로지정 internalformat: 일반적으로 format 과같음. RGB 라면 3, RGBA 라면 4로설정 width, height: 텍스쳐이미지의너비와높이는 의자승으로되어야함 ( 즉,, 4, 8, 16, 3, 64, 18, 56, 51, etc) border: 텍스쳐의경계선너비를지정. 보통 0이고이미지데이터가 border를가지고있으면 1로지정. type: 텍스쳐이미지데이터의형식을설정.
glteximage1d glteximage1d(glenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); glteximaged() 함수는 차원텍스처이미지를정의하고 glteximage1d() 함수는 1차원텍스처이미지를정의한다. glteximage1d() 함수와 glteximaged() 함수의사용방법과인자의의미는거의동일하며 glteximaged() g 함수에만이미지텍스처의 height( 높이 ) 인자가추가된다. gltexsubimaged 텍스쳐크기가 의승수 (e.g., 64x64, 18x56,..) 가아닌경우텍스쳐이미지의일부분만읽어들일때사용함 gltexsubimaged(glenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei i width, GLsizei i height, h GLenum format, GLenum type, const GLvoid *pixels); OpenGL Texture Coordinates 텍스쳐맵핑이사용되려면객체에텍스쳐좌표를정의해야한다. GLUT teapot은텍스쳐좌표를포함하고있다. GLU quadrics도텍스쳐좌표를옵션으로정의할수있다. gluquadrictexture(quadric, GL_TRUE) 를사용하여텍스쳐맵핑활성화 OpenGL Texture Coordinates OpenGL에서텍스쳐좌표는텍스쳐이미지의각방향 (S, T) 의 0부터 1의영역으로형성됨. OpenGL에서각정점별로텍스쳐좌표를지정해야함. 정점의텍스쳐좌표가객체의표면에보간되어나타남. t (1,1) (.5,5.0,0.0) (0,1) (0.0,0.0,0.0) (0,0) 0) s (1,0) Texture space Object space (3.0,-.0,0.0)
OpenGL Texture Coordinates 텍스쳐는다각형에고르게입힐필요는없음. 기하하적모델이나텍스쳐좌표사용에따라서, 이미지가때론왜곡되게나타날수도있음. glbegin(gl_quads); gltexcoordi(0,0); 0); glvertex3f(-1.0, -1.0, 0.0); gltexcoordi(1,0); glvertex3f(1.0, -1.0, 0.0); gltexcoordi(1,1); glvertex3f(x1, y1, 0.0); gltexcoordi(0,1); glvertex3f(x0, y0, 0.0); glend(); OpenGL Texture Filtering OpenGL에서텍스쳐좌표가 [0, 1] 영역을벗어날경우에 texture wrapping방법으로정의함 : Repeat, Clamp 사각형에 4개의텍스쳐좌표를 (0,0), (0,3.5), (3.5,0), (3535) (3.5,3.5) 로정의한예 Repeat Clamp Repeat &Clamp OpenGL Texture Filtering Mipmap은이전 mipmap 너비와폭의절반크기임. 텍스쳐가작아질수록, 보다많은텍셀이한픽셀에적용되야하므로 GL_NEAREST나 GL_LINEAR 필터가정확한계산결과를만들지않을수있음. 따라서객체가움직일때텍스쳐가 flickering하게나타날수있음. 밉맵은이런 flickering문제를줄여줄수있음. 그러나일반적으로희미하게보임. OpenGL Texture Filtering 텍스쳐맵핑을위한필터링방법 최근점필터 (nearest neighbor filter) GL_NEAREST 이선형필터 (bilinear interpolation filter) GL_LINEAR 삼선형필터 (trilinear interpolation filter) mipmap p filter GL_LINEAR_MIPMAP_LINEAR 혼합필터 (hybrid filter) GL_NEAREST_MIPMAP_LINEAR LINEAR GL_LINEAR_MIPMAP_NEAREST GL_NEAREST_MIPMAP_NEAREST GL_LINEAR GL_LINEAR_MIPMAP_LINEAR
OpenGL Texture Filtering gltexparameter{if}v(glenum target, GLenum pname, TYPE *param); GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T GL_ CLAMP, GL_ REPEAT GL_TEXTURE_MAG_FILTER GL_NEAREST, GL_LINEAR GL_TEXTURE_MIN_FILTER GL_NEAREST, GL_LINEAR (Mipmap을사용하지않는경우 ) GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, LINEAR NEAREST GL_NEAREST_MIPMAP_NEAREST GL_TEXTURE_BORDER_COLOR [0.0, 1.0] 영역의값 GL_TEXTURE_PRIORITY 0 또는 1 Texture Environment Parameters gltexenv{fi}[v](..) 를사용하여텍스쳐의색 (C t, A t ) 과현재처리하는프레임버퍼의픽셀색 (C f, A f ) 을어떻게혼합할지설정함 GL_TEXTURE_ENV_MODE ENV 의모드 : GL_MODULATE: 텍스쳐의색성분과음영에서주어지는색성분을곱함으로써텍스쳐맵핑없이할당될음영을변조가능 GL_DECAL: 텍스쳐의색이객체의색을완전히결정 GL_BLEND: 환경색과합성함 GL_REPLACE: 텍스쳐색만사용함 GL_BLEND 의합성색은 GL_TEXTURE_ENV_COLOR ENV 으로지정함 GLfloat blendcolor[] = {0.0, 1.0, 0.0, 0.5}; gltexenvfv(gl_texture_env, GL_TEXTURE_ENV_COLOR, blendcolor); Texture Environment Parameters OpenGL Texture Transformations 텍스쳐좌표의변환 기하물체의정점에변환하듯이텍스쳐좌표에이동 (translation), 회전 (rotate), 크기변환 (scaling) 을적용함 glmatrixmode(gl_texture) 를사용하여정점이아닌텍스쳐좌표에변환을적용함을지시함 glmatrixmode(gl_texture); glloadidentity(); gltranslatef(0.1, 0.05, 05 0); glrotatef(30.0, 0, 0, 1); glmatrixmode(gl_modelview); // geometry with ihtexture coordinates
OpenGL Texture Transformations 텍스쳐좌표의변환 텍스쳐좌표에크기변환 (scaling) 을적용할때물체도또한같은크기변환을해야함 glmatrixmode(gl_texture); glloadidentity(); glscalef(size, 1, 1); glmatrixmode(gl_modelview); glscalef(size, 1, 1); // geometry with texture coordinates OpenGL Texture Movies 텍스쳐이미지 sequence를이용하여 flipbook 애니메이션제작 inittexture() 함수에서전체텍스쳐이미지를읽어들임 idle() 함수에서 currenttextureid t 를 update 함 drawtexture() 함수에서는동일한정점좌표와텍스쳐좌표에 glbindtexture(gl_texture_d, _ currenttextureid); 를사용하여프레임당한텍스쳐를 binding함 애니메이션효과를줌 image1 image image3 image4 image5 image6 OpenGL Compressed Textures glcompressedteximagedarb 를사용하여압축한텍스쳐를생성할수있음. 너비와높이의 RGB 값을가진일반텍스쳐보다압축한텍스쳐는메모리사용량을줄이고빨리그릴수있음 glcompressedteximagedarb(gl_texture_d, 0, format, width, height, 0, size, imagebuffer); OpenGL Texture Coordinate Generation OpenGL에서는텍스쳐좌표를자동적으로생성할수있음 S, T 방향으로텍스쳐좌표자동생성을활성화해야함 glenable(gl_texture_gen_s), glenable(gl_texture_gen_t) GL_ TEXTURE_ GEN_ MODE 모드 : GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP 평면 (plane) 을지정해야함 - 평면으로부터의거리에바탕을둔텍스쳐좌표를생성 gltexgenfv(gl_s, GL_OBJECT_PLANE, planecoefficients) planecoefficients = { 1, 0, 0, 0 }; gltexgeni(gl_s, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR) ; gltexgenfv(gl_s, GL_OBJECT_PLANE, planecoefficients); glenable(gl_texture_gen_s) GEN ; glbegin(gl_quads) ; glvertex3f(-3.5, -1, 0); glvertex3f(-1.5, -1, 0) ; glvertex3f(-1.5, 1, 0); glvertex3f(-3.5, glvertex3f(-35 1, 0) ; glend() ;
OpenGL Sphere Mapping OpenGL 에서는구형맵핑 (sphere mapping) 지원 구형맵핑텍스쳐좌표는 view 벡터가구표면의법선벡터에반사된 reflection 벡터로계산됨. 반사벡터를 차원텍스쳐좌표로맵핑하는것이간단하고하드웨어, 소프트웨어로도구현이가능. 그러나원형이미지를구하는것이어려움 (360도의주변환경을담은이미지여야함 ). 아주넓은광학렌즈에의한원근투영을구하거나, 입방체투영을이용하여근사한값을얻음. gltexgeni(gl_s, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ; gltexgeni(gl_t, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ; glenable(gl_texture_gen_s) ; glenable(gl_texture_gen_t) ; OpenGL Box Mapping OpenGL에서는입방체맵핑 (box mapping) 지원 입방체맵은반사맵핑 (reflection mapping) 의하나임 그러나입방체맵은 3차원텍스쳐좌표를사용해야함 반사텍스쳐는환경을둘러싸고있는입방체의 6 면 차원텍스쳐 gltexgeni(gl_s, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP) ; gltexgeni(gl_t, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP) ; gltexgeni(gl_r, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP) ; glenable(gl_texture_gen_s) ; glenable(gl_texture_gen_t) ; glenable(gl_texture_gen_r) ; glenable(gl_texture_cube_map); Multitexturing 멀티텍스쳐 (Multitexturing) 하나이상의텍스쳐를객체에적용해서렌더링효과를높이는경우 + = OpenGL 1..1 revision (ARB_multitexture extension) Multitexturing Single-Pass vs. Multi-Pass Multitexturing 싱글패스다중텍스쳐링은하나의렌더링패스안에서텍스쳐를여러개입히는것 다중패스다중텍스쳐링은블렌딩으로장면이나다각형자체를여러번렌더링하는것 라이트매핑 (Light Mapping) 물체면의밝기를계산하는대신텍스쳐와조명결과를혼합하여결과적으로영상을직접물체면에입힘 (e.g. Quake 등게임 ) Incoming Fragment Color Texture 0 Environme nt Texture 1 Environme nt Resulting Color + = Texture 0 Color Texture 1 Color
확장지원헤더포함 #include <GL/glext.h> PFNGLACTIVETEXTUREARBPROC glactivetexturearb = NULL; PFNGLMULTITEXCOORDFARBPROC glmultitexcoordfarb = NULL; PFNGLCLIENTACTIVETEXTUREARBPROC glclientactivetexturearb = NULL; 확장지원여부확인및함수포인터설정 char *ext = (char*) glgetstring(gl_extensions); if(strstr(ext, "GL_ARB_multitexture") == NULL) { printf("gl GL_ARB_multitexture extension was not found\n"); return; } else { glactivetexturearb = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglgetprocaddress("glactivetexturearb"); g glmultitexcoordfarb = (PFNGLMULTITEXCOORDFARBPROC) wglgetprocaddress("glmultitexcoordfarb"); glmultitexcoordfarb if(!glactivetexturearb!glmultitexcoordfarb) { printf("one or more GL_ARB_multitexture functions were not found\n"); return; } } glactivetexturearb (texture); texture is GL_TEXTUREn_ARB GL_TEXTUREn_ARB == GL_TEXTURE0_ARB+n n = 0.. numtextureunits - 1, maximum 3 query number of texture t units: glgetintegerv(gl_number_of_texture_units_arb, &numtextureunits); Bind and enable two D multitextures // stage 0 glactivetexturearb(gl_texture0_arb); TEXTURE0 ARB); glbindtexture(gl_texture_d, tex0); glenable(gl_texture_d); // stage 1 glactivetexturearb(gl_texture1_arb); glbindtexture(gl_texture_d, _ tex1); glenable(gl_texture_d); // set texture environment gltexenvi(gl_texture_env, TEXTURE ENV GL_TEXTURE_ENV_MODE, ENV GL_ADD);
y (1,1) v (1,1) glmultitexcoordfvarb(texture,...); v: indicates vector format, if present data type: f single precision float d double precision float s signed short tinteger i signed integer number of components: 1,,4 texture is GL_TEXTUREn_ARB 멀티텍스쳐사각형렌더링 glbegin(gl_quads); (-1,-1) glmultitexcoordfarb( GL_TEXTURE0_ARB, 0.0f, 0.0f ); glmultitexcoordfarb( GL_TEXTURE1_ARB, 0.0f, 0.0f ); glvertex3f(-1.0f, -1.0f, 0.0f); glmultitexcoordfarb( ltit GL_TEXTURE0_ARB, 1.0f, 0.0f 0f ); glmultitexcoordfarb( GL_TEXTURE1_ARB, 1.0f, 0.0f ); glvertex3f(1.0f, -1.0f, 0.0f); glmultitexcoordfarb( GL_TEXTURE0_ARB, 1.0f, 1.0f ); glmultitexcoordfarb( GL_TEXTURE1_ARB, 1.0f, 1.0f ); glvertex3f(1.0f, 1.0f, 0.0f); 0f); glmultitexcoordfarb( GL_TEXTURE0_ARB, 0.0f, 1.0f ); glmultitexcoordfarb( GL_TEXTURE1_ARB, 0.0f, 1.0f ); glvertex3f(-1.0f, 1.0f, 0.0f); glend(); x (0,0) u (-1,1,0) (1,1,0) glclientactivetexturearb(texture); Client state analog to glactivetexturearb(); 멀티텍스쳐 vertex array 상태를지정하는데사용 y (0,0,0) x z (-1,-1,0) (1,-1,0) texture coordinate arrays 지정하는예 : glclientactivetexturearb(gl TEXTURE0 ARB); glclientactivetexturearb(gl_texture0_arb); gltexcoordpointer(, GL_FLOAT, 0, tex_array_ptr0); glenableclientstate(gl_texture_coord_array); g ( _ ); glclientactivetexturearb(gl_texture1_arb); gltexcoordpointer(, GL_FLOAT, 0, tex_array_ptr1); glenableclientstate(gl_texture_coord_array);
Billboarding 빌보드기법 사각형의정면이항상카메라의정면을향하여바라보도록만드는것으로, 결과적으로카메라가어느방향에서바라보아도사각형은항상같은면을보여주게됨 사용예로써, 넓은지면위에나무를나타내고자할때나무를메쉬모델링으로표현하지않고나무이미지를빌보드로구현함 알파텍스처기법과애니메이션이결합된빌보드기법은고체표면을갖지않는여러현상을표현하는데사용 : 연기, 불, 안개, 폭발등 Billboarding 빌보드원리 구현의핵심은, 항상시점을바라보도록 Modelview 행렬을이용하여빌보드사각형을이루는 vertex를조정해야함 Modelview 행렬에는관찰자의시점에대한수직벡터 (up vector) 와우측벡터 (right vector) 정보가있음 Glfloat M[16]; glgetfloatv(gl_modelview_matrix, M); Right-vector Up-vector Look-vector m 0 m 1 m m 3 Up-vector m 4 m 5 m 6 m 7 Billboarding 적용후 m 8 m 9 m 10 m 11 Right-vector m 1 m 13 m 14 m 15 Billboarding Axial Symmetry 빌보드사각형이 vertical axis를중심으로회전 (rotate) 해야함 Modelview matrix M에서부터카메라의 yaw angle을계산함 theta = 180.0f * atanf(m[8], M[10]) /M_PI; Look.x Look.z 빌보드사각형의 Rotation matrix R은 arbirary axis ( 일반적으로 up vector=(0, 1, 0)) 과 angle ( 카메라 yaw angle의반대 ) 로계산함 RIcos Symmetric (1 cos Skew sin a x cos (1 ax ) axa y(1 cos az sin axa z(1 cos ay sin a xay (1 cos az sin ay cos (1 ay ) aya z(1 cos ax sin a xaz (1 cos ay sin aya z(1 cos ax sin az cos (1 az ) Point Sprites Point Sprites이란하드웨어기반의빌보드기법으로, 사용예로써파티클시스템 (Particle System) 에서다수의입자 (Particle) 을텍스쳐사각형메쉬 (Quad) 대신점 (Point) 를사용하여지정함 OpenGL extension (GL_ARB_point_parameters & GL_ARB_point_sprite)
Point Sprites 확장지원헤더포함 #include <GL/glext.h> PFNGLPOINTPARAMETERFARBPROC glpointparameterfarb = NULL; PFNGLPOINTPARAMETERFVARBPROC glpointparameterfvarb = NULL; Point Sprites 확장지원여부확인및함수포인터설정 char *ext = (char*) glgetstring(gl_extensions); if(strstr(ext, "GL_ARB_point_parameters") == NULL) { printf("gl GL_ARB_point_parameters parameters extension was not found\n"); return; } else { glpointparameterfarb = (PFNGLPOINTPARAMETERFARBPROC) wglgetprocaddress("glpointparameterfarb"); g glpointparameterfvarb = (PFNGLMULTITEXCOORDFARBPROC) wglgetprocaddress(" glpointparameterfvarb "); if(! glpointparameterfarb! glpointparameterfvarb ) { printf("one or more GL_ARB_point_parameters were not found\n"); return; } } Point Sprites glpointparameterf[v]arb (GLenum pname, GLfloat param); GL_POINT_SIZE_MIN_ARB (default: 0.0) GL_POINT_SIZE_MAX_ARB ARB GL_POINT_FADE_THRESHOLD_SIZE_ARB (default: 1.0) GL_POINT_DISTANCE_ATTENUATION_ARB ATTENUATION ARB (default: 0, 0, 0) Point sprite 으로 texture coordinate 을지정하고 enable 함 gltexenvf(gl_point_sprite_arb, GL_COORD_REPLACE_ARB, GL_TRUE); glenable(gl_point_sprite_arb); Point Sprites Point 를렌더링 // enable point sprites... glenable(gl_point_sprite_arb); glbegin(gl_points); for (int i = 0; i < MAX_PARTICLES; ++i) { glcolor4f(g_particles[i].col[0], g_particles[i].col[1], g_particles[i].col[], 1.0f); glvertex3fv(g_particles[i].pos); } glend(); // disable point sprites gldisable( GL_POINT_SPRITE_ARB );
Reference OpenGL Billboarding Tutorial http://www.lighthouse3d.com/opengl/billboarding SIGGRAPH 97 Advanced OpenGL Programs http://www.opengl.org/resources/code/samples/advanced/advanc org/resources/code/samples/advanced/advanc ed97/programs/programs.html OpenGL Point Sprites http://www.informit.com/articles/article.aspx?p=770639&seqnum= 7 Particle Systems http://www.gamedev.net/