11.OpenGL ES

11-1.Ãà¼ÒµÈ ¼­ºê¼Â

3D ±×·¡ÇÈ ¶óÀ̺귯¸®ÀÎ OpenGLÀº Å»ýÀûÀ¸·Î ¹«°Å¿ï ¼ö¹Û¿¡ ¾ø´Ù. ¿¬»ê·®ÀÌ ¸¹À¸¹Ç·Î CPU´Â °¡±ÞÀû »¡¶ó¾ß ÇÏ¸ç ´ë¿ë·®ÀÇ µ¥ÀÌÅ͸¦ ´Ù·ç°í ´Ù·®ÀÇ ¹öÆÛ¸¦ »ç¿ëÇϹǷΠ¸Þ¸ð¸®µµ ¸¹ÀÌ ¼Ò¸ðÇÑ´Ù. °í¼º´É PC ȯ°æÀº ÀÌ·± ¿ä±¸ »çÇ×À» ¸ðµÎ ÃæÁ·½ÃÅ°¹Ç·Î Å« ¹«¸®¾øÀÌ Àß ½ÇÇàµÈ´Ù. ±×·¯³ª ÀÚ¿øÀÇ Á¦¾àÀÌ ÈξÀ ´õ ½ÉÇÑ ¸ð¹ÙÀÏ ÀåºñµéÀº ÀÔü ±×·¡ÇÈÀ» Ãâ·ÂÇϱ⿡´Â ¾çÀûÀ¸·Î³ª ÁúÀûÀ¸·Î³ª ºÎÁ·ÇÑ ºÎºÐÀÌ ¸¹´Ù.

CPU´Â ´À¸®°í ¸Þ¸ð¸®´Â Á¦ÇѵǾî ÀÖ´Ù. °Ô´Ù°¡ Ç×»ó ¹èÅ͸®¿¡ ÀÇÁ¸Çؼ­ µ¿ÀÛÇϹǷΠºÎÁ·ÇÑ ÀÚ¿øÁ¶Â÷µµ ¸¶À½²¯ È°¿ëÇϱ⠾î·Æ´Ù. ´õ Ä¡¸íÀûÀÎ °ÍÀº ±×·¡ÇÈ Çϵå¿þ¾îÀÇ Áö¿øÀÌ ¾Æ¿¹ ¾ø°Å³ª ¹Ì¾àÇؼ­ ¸ðµç °ÍÀ» ¼ÒÇÁÆ®¿þ¾î·Î ó¸®ÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. ÃÖ¾ÇÀÇ °æ¿ì´Â ºÎµ¿ ¼Ò¼öÁ¡ ¿¬»êÁ¶Â÷µµ ¼ÒÇÁÆ®¿þ¾î·Î ¼öÇàÇØ¾ß ÇÑ´Ù.

ÀÌ·± Á¦¾àÀÌ ½ÉÇÑ ÀÓº£µðµå ȯ°æÀ» À§ÇØ ´õ ÀÛ°í °¡º­¿î º°µµÀÇ Ç¥ÁØÀ» ÀçÁ¤Çߴµ¥ ÀÌ°ÍÀÌ ¹Ù·Î OpenGL ESÀÌ´Ù. ES´Â Embeded SystemÀÇ ¾àÀÚÀÌ´Ù. ES Ç¥ÁØÀº Å©·Î³ë½º ±×·ì¿¡¼­ °ü¸®ÇÑ´Ù. ES´Â »óÀ§ÀÇ Ç¥ÁØÀÎ OpenGL¿¡¼­ Àß »ç¿ëµÇÁö ¾Ê°Å³ª ´ëüÀûÀÎ ¹æ¹ýÀÌ ÀÖ´Â °ÍÀ» Á¦¿ÜÇÏ°í Ãà¼ÒÇÏ¿© ¸¸µç °ÍÀÌ´Ù. Áï, OpenGLÀÇ ¼­ºê¼ÂÀÌ´Ù. OpenGL°ú ESÀÇ °ü°è´Â ´ÙÀ½°ú °°´Ù.

 

OpenGL1.3 -> ES 1.0

OpenGL1.5 -> ES 1.1

OpenGL2.0 -> ES 2.0(2007³â)

 

ÃֽŠ¹öÀüÀÎ ES 2.0Àº ÇÏÀ§ ¹öÀüÀÎ 1.x¿Í ȣȯµÇÁö ¾Ê´Â´Ù. 1.x ¹öÀüÀº °íÁ¤µÈ ÆÄÀÌÇÁ¶óÀÎÀ» »ç¿ëÇÏ´Â µ¥ ºñÇØ ES 2.0Àº ÇÁ·Î±×·¡¹Ö °¡´ÉÇÑ ½¦ÀÌ´õ¸¦ »ç¿ëÇÑ´Ù. 3D ±×·¡ÇÈÀ» À§ÇÑ ¶óÀ̺귯¸®¶ó´Â ¸é¿¡¼­¸¸ °°Àº ¸ñÀûÀ» °¡Áö°í ÀÖÀ» »ÓÀÌ¸ç ¾Æ¿¹ ´Ù¸¥ Ç¥ÁØÀ̶ó°í ºÁµµ µÉ Á¤µµ´Ù. ¶°¿À¸£´Â ½Å±â¼úÀÎ HTML5ÀÇ WebGLÀº ES 2.0À» ±âÁØÀ¸·Î ÆÄ»ýµÈ Ç¥ÁØÀÌ´Ù.

ES´Â ÀÓº£µðÆ® ȯ°æÀ» À§ÇØ °æ·®È­µÈ °ÍÀ̾ ÁÖ·Î OpenGLÀÇ ±â´É¿¡¼­ ÀϺθ¦ Á¦¿ÜÇÏ¿© ÀÛ¼ºµÈ Ç¥ÁØÀÌ´Ù. ES ½ºÆå ¹®¼­´Â °¢ ±â´É¿¡ ´ëÇÑ ¸í¼¼¸¦ ¹àÈ÷´Â °Íº¸´Ù OpenGL¿¡¼­ ¾î¶² ±â´ÉÀÌ Á¦¿ÜµÇ¾ú´ÂÁö¸¦ ¼³¸íÇÑ´Ù. ÀÌ ¸»Àº ESÀÇ ÁÖ¿ä À̷еéÀÌ OpenGL¿¡¼­ ¿Â °ÍÀ̸ç ES¸¦ ¹è¿ì±â À§Çؼ­´Â OpenGLÀ» ¸ÕÀú ¹è¿ö¾ß ÇÑ´Ù´Â ¶æÀÌ´Ù. OpenGL¿¡ ºñÇØ ES´Â ´ÙÀ½ ±â´ÉµéÀÌ Á¦°Å ¶Ç´Â Ãà¼ÒµÇ¾ú´Ù.

 

¡á Áö¿ø ŸÀÔÀÇ ¼ö¸¦ ÁÙ¿´´Ù. ´ëÇ¥ÀûÀ¸·Î GLdouble ŸÀÔÀ» Áö¿øÇÏÁö ¾Ê´Âµ¥ »ç½Ç OpenGL¿¡¼­µµ ÀÌ Å¸ÀÔÀº Àß »ç¿ëµÇÁö ¾Ê¾Ò´Ù. ¶óÀÌÆ® ¹öÀü¿¡´Â GLfloatµµ ¾ø°í °íÁ¤ ¼Ò¼öÁ¡ ŸÀÔÀÎ GLfixed ŸÀÔÀ» ´ë½Å »ç¿ëÇÑ´Ù. ÀÓº£µðµå ½Ã½ºÅÛ¿¡´Â ºÎµ¿¼Ò¼öÁ¡ ¿¬»êÀ» Çϵå¿þ¾î°¡ ¼öÇàÇÏÁö ¸øÇϹǷΠ¼ÒÇÁÆ®¿þ¾î·Î ´À¸®°Ô ¼öÇàÇØ¾ß Çϱ⠶§¹®ÀÌ´Ù. GLbyte, GLubyte, GLshort ŸÀÔµµ Á¦°ÅµÇ¾ú´Ù.

¡á Áï½Ã ¸ðµå¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù. glBegin~glEnd ºí·Ï¾È¿¡¼­ ±×¸®±â ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ¾ø°í Á¤Á¡ ¹è¿­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÇÔ¼ö È£Ãâ ¿À¹öÇìµå¸¦ ÁÙÀ̱â À§Çؼ­ÀÌ´Ù. ¿©·¯ Á¤º¸¸¦ ÇÑ ¹è¿­¿¡ ÀúÀåÇÏ´Â ÀÎÅ͸®ºê ¹è¿­µµ Áö¿øÇÏÁö ¾Ê´Â´Ù.

¡á »ç°¢ÇüÀ» ±×¸®´Â glRect ÇÔ¼ö°¡ Á¦¿ÜµÇ¾ú´Ù. ±×·¡¼­ ¸ðµç ¹°Ã¼¸¦ »ï°¢ÇüÀ¸·Î¸¸ ±¸¼ºÇØ¾ß ÇÑ´Ù. GL_QUADS, GL_POLYGON ¸ðµ¨µµ Á¦¿ÜµÇ¾ú´Ù. »ç½Ç ÀÌ ±â´ÉµéÀº OpenGL¿¡¼­µµ Àß »ç¿ëµÇÁö ¾Ê´Â °ÍÀÌ´Ù.

¡á »ö»ó À妽º ¸ðµå´Â Áö¿øÇÏÁö ¾Ê´Â´Ù. Á¶¸íÀ̳ª ÅؽºÃ³ ¸ÊÇÎ µî¿¡ Á¦¾àÀÌ ¸¹´Ù. OpenGL¿¡¼­µµ ÆÈ·¹Æ® ¸ðµå´Â ¿ø·¡ Á¦¾àÀÌ ¸¹¾Ò´Ù.

¡á ±×¿Ü Æú¸®°ï ¸ðµå, Çǵå¹é, ¼±Åà ±â´É, ´©Àû ¹öÆÛ, Ãâ·Â ¸ñ·Ï, ¼Ó¼º ÀúÀå ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù.

¡á ÅؽºÃ³ ¸ÊÇÎÀº 2D¸¸ Áö¿øµÈ´Ù.

¡á Á¶¸íÀº ¾ÕµÞ¸éÀÌ ¹Ýµå½Ã µ¿ÀÏÇØ¾ß ÇÑ´Ù. ÀçÁú ¸ðµå´Â GL_AMBIENT_AND_DIFFUSE¸¸ Áö¿øµÈ´Ù.

 

PC ȯ°æ¿¡¼­ ES¸¦ ½Ç½ÀÇ϶ó¸é º°µµÀÇ ¿¡¹Ä·¹ÀÌÅÍ°¡ ÇÊ¿äÇÏ´Ù. ±×º¸´Ù ´õ È®½ÇÇÑ ¹æ¹ýÀº ES¸¦ Á÷Á¢ Áö¿øÇϴ ȯ°æ¿¡¼­ ½Ç½ÀÇÏ´Â °ÍÀÌ´Ù. ¿©±â¼­´Â ¾Èµå·ÎÀ̵å ȯ°æ¿¡¼­ ½Ç½ÀÇϱâ·Î ÇÑ´Ù. ¾ÆÀÌÆùµµ ES¸¦ Àß Áö¿øÇϱâ´Â ÇÏÁö¸¸ ½Ç½À Àåºñ°¡ ´ëÁßÀûÀÌÁö ¾Ê¾Æ ±¸¼ºÇϴµ¥ ºñ¿ëÀÌ ¸¹ÀÌ µå´Â ¹®Á¦°¡ ÀÖ´Ù. ¹«¾ùº¸´Ù º»ÀÎ ½º½º·Î ¾ÆÀÌÆùÀ» Àß ¸ô¶ó¼­ ´Ù·ç±â ¾î·Æ´Ù.

À©ÆùÀº OpenGLÀ» Áö¿øÇÏÁöµµ ¾ÊÀ¸¸ç ÀÚ½ÅÀÇ ±â¼úÀÎ XNA¸¸ Áö¿øÇÑ´Ù. ¸ðµÎ°¡ Ç¥ÁØÀ» ÁؼöÇÏ°í Àß µû¸£´Âµ¥ È¥ÀÚ¸¸ µ¶ºÒ À屺ÀÌ´Ù. ÀÌ·± Àú·± ÀÌÀ¯·Î ES ȯ°æÀ» À§ÇÑ ÃÖÀûÀÇ ½Ç½À ȯ°æÀº ¾Èµå·ÎÀ̵åÀÌ´Ù. ±»ÀÌ Àåºñ°¡ ¾ø¾îµµ ¿¡¹Ä·¹ÀÌÅÍ·Î ½Ç½ÀÀ» ÇÒ ¼ö ÀÖÀ¸¸ç ´ëºÎºÐÀÇ ¿î¿µÃ¼Á¦¿¡ °³¹ßÅøÀ» ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ÀÌ °­Á¿¡¼­´Â ¾Èµå·ÎÀÌµå °³¹ß ȯ°æ¿¡ ´ëÇؼ­´Â ±âº»Àº ¾È´Ù°í °¡Á¤ÇÑ´Ù.

11-2.¾Èµå·ÎÀ̵åÀÇ ±×·¡ÇÈ Áö¿ø

¾Èµå·ÎÀÌµå ±×¸®±â ½Ã½ºÅÛÀÇ ÇÙ½ÉÀº ºäÀÌ´Ù. ¾×ƼºñƼ´Â ºä¸¦ ´ã´Â ²®µ¥±â°Ô ºÒ°úÇÏ°í ÀԷ°ú Ãâ·ÂÀ» ´ã´çÇÏ´Â °ÍÀº ºäÀÌ´Ù. ±âº» ÀÔÃâ·Â ½Ã½ºÅÛÀÎ ºä¿Í ES¸¦ ¿¬°áÇÏ´Â °í¸®´Â GLSurfaceView Ŭ·¡½ºÀÌ´Ù. GLSurfaceView´Â 3D ±×·¡ÇÈ Ç¥¸éÀ» Á¦°øÇÏ¸ç ¾Èµå·ÎÀ̵åÀÇ ºä ½Ã½ºÅÛ°ú OpenGLÀ» Áß°èÇÑ´Ù.

OpenGL ±×¸®±â¸¦ ¼öÇàÇÏ·Á¸é GLSurfaceView °´Ã¼¸¦ ÁغñÇØ¾ß ÇÑ´Ù. ´ëºÎºÐÀÇ ±â´ÉÀ» ¸Þ¼­µå·Î Á¶Á¤ÇÒ ¼ö ÀÖÀ¸¹Ç·Î ±»ÀÌ »ó¼ÓÀ» ¹ÞÀ» ÇÊ¿ä´Â ¾ø´Ù. ±×³É GLSurfaceView ŸÀÔÀÇ °´Ã¼¸¦ ¾×ƼºñƼÀÇ ¸â¹ö·Î ¼±¾ðÇÑ ÈÄ »ç¿ëÇÏ¸é µÈ´Ù. ´Ü, ÀÔ·Â ¸Þ¼­µå¸¦ ÀçÁ¤ÀÇÇÒ ¶§¿¡¸¸ »ó¼ÓÀ» ¹ÞÀ¸¸é µÈ´Ù.

GLSurfaceView´Â Á߰踸 ´ã´çÇÒ »ÓÀÌ¸ç ½ÇÁ¦·Î ±×¸®±â¸¦ ¼öÇàÇÏ´Â °ÍÀº ·»´õ·¯ÀÌ´Ù. ·£´õ·¯´Â ºÐ¸®µÈ ½º·¹µå¿¡¼­ ±×¸®±â¸¸ ¼öÇàÇÑ´Ù. ¾×ƼºñƼ´Â onPause, onResume½Ã¿¡ GLSurfaceViewºäÀÇ µ¿ÀÏÇÑ ¸Þ¼­µé¸£ ¹Ýµå½Ã È£ÃâÇÏ¿© ½º·¹µå¸¦ ÁßÁö ¹× Àç°³ÇÒ ¼ö ÀÖµµ·Ï ÇØ¾ß ÇÑ´Ù. ·£´õ·¯´Â 3Â÷¿ø Àå¸éÀ» ±×·Á³½´Ù. ¿¬»ê·®ÀÌ ¸¹À¸¹Ç·Î UI ½º·¹µå¿Í´Â ´Ù¸¥ ºÐ¸®µÈ ½º·¹µå¿¡¼­ ½ÇÇàµÈ´Ù. ·£´õ·¯´Â Ŭ·¡½º°¡ ¾Æ´Ñ ÀÎÅÍÆäÀ̽ºÀÌ¸ç ´ÙÀ½ 3°³ÀÇ ÁÖ¿ä ¸Þ¼­µå Á¦°øÇÑ´Ù. ·£´õ·¯ ±¸Çö Ŭ·¡½º´Â ÀÌ ¸Þ¼­µåµéÀ» ¸ðµÎ ±¸ÇöÇØ¾ß ÇÑ´Ù.

 

void onSurfaceCreated (GL10 gl, EGLConfig config)

±×¸®±â Ç¥¸éÀÌ »ý¼ºµÉ ¶§³ª EGL ÄÁÅؽºÆ®°¡ ÆÄµÇµÉ ¶§ ÀÌ ¸Þ¼­µå°¡ È£ÃâµÈ´Ù. Àåºñ°¡ ½½¸³ »óÅ·Πµé¾î°¥ ¶§ ESL ÄÁÅؽºÆ®°¡ ÀÚµ¿À¸·Î Æı«µÇ¸ç °ü·Ã ¸®¼Ò½ºµµ ¸ðµÎ Á¦°ÅµÈ´Ù. ±×·¡¼­ ÀÌ ¸Þ¼­µå°¡ È£ÃâµÉ ¶§¸¶´Ù °ü·Ã ¸®¼Ò½º¸¦ ´Ù½Ã ÁغñÇØ¾ß ÇÑ´Ù. ¸ðµç ¸®¼Ò½º´Â ÀÚµ¿À¸·Î Æı«µÇ¹Ç·Î ÀϺη¯ Æı«ÇÒ ÇÊ¿ä´Â ¾ø´Ù.

 

void onSurfaceChanged (GL10 gl, int width, int height)

Ç¥¸éÀÇ Å©±â°¡ º¯°æµÉ ¶§ È£ÃâµÇ¸ç »ý¼º Á÷ÈÄ¿¡µµ È£ÃâµÈ´Ù. ¿©±â¼­´Â Åë»ó ºäÆ÷Æ®¸¦ ¼³Á¤ÇÏ°í Åõ¿µ ¸ðµå¸¦ ÁöÁ¤ÇÑ´Ù.

 

void onDrawFrame (GL10 gl)

ÇÁ·¹ÀÓÀ» ±×¸± ¶§¸¶´Ù È£ÃâµÈ´Ù. ¿©±â¼­ Àμö·Î Àü´ÞµÇ´Â glÀÇ ¿©·¯ ¸Þ¼­µå¸¦ »ç¿ëÇÏ¿© 3Â÷¿ø Àå¸éÀ» ±×¸°´Ù.

 

°¢ ¸Þ¼­µå·Î Àü´ÞµÇ´Â gl Àμö´Â Ç×»ó GL10 ŸÀÔÀÌ´Ù. ¸¸¾à glÀÌ GL10º¸´Ù ´õ ³ôÀº ¹öÀüÀÎ °æ¿ì instanceof ¿¬»êÀÚ·Î Å×½ºÆ®ÇØ º¸°í ij½ºÆÃÇÏ¿© »ç¿ëÇÑ´Ù. GLSurfaceView.Renderer¸¦ ±¸ÇöÇϴ Ŭ·¡½º¸¦ Á¤ÀÇÇÏ°í GLSurfaceViewÀÇ ´ÙÀ½ ¸Þ¼­µå·Î ·£´õ·¯¸¦ ÁöÁ¤ÇÑ´Ù.

 

void setRenderer (GLSurfaceView.Renderer renderer)

 

GLSurfaceView´Â ÁÖ±âÀûÀ¸·Î onDrawFrame ¸Þ¼­µå¸¦ È£ÃâÇÏ¿© Àå¸éÀ» °è¼Ó °»½ÅÇÑ´Ù. ÀÌ·± ¸ðµå¸¦ ¿¬¼Ó ¸ðµå(RENDERMODE_CONTINUOUSLY)¶ó°í Çϴµ¥ 3D È­¸éÀº º¸Åë °è¼Ó º¯Çϱ⠶§¹®¿¡ µðÆúÆ®°¡ ¿¬¼Ó ¸ðµå·Î µÇ¾î ÀÖ´Ù. ´ëÇ¥ÀûÀÎ 3D ÇÁ·Î±×·¥ÀÎ °ÔÀÓÀº ´Ü ÇѼø°£µµ ½¬Áö ¾Ê°í °è¼Ó ¹Ù²ï´Ù. ±×·¡¼­ ·£´õ·¯°¡ º°µµÀÇ ½º·¹µå¿¡¼­ µ¿ÀÛÇÏ´Â °ÍÀÌ´Ù. ¸¸¾à ¿¬¼ÓÀûÀ¸·Î ´Ù½Ã ±×¸®±â¸¦ ÇÒ ÇÊ¿ä°¡ ¾ø´Ù¸é ´ÙÀ½ ¸Þ¼­µå·Î ·£´õ ¸ðµå¸¦ º¯°æÇÑ´Ù.

 

void setRenderMode (int renderMode)

 

RENDERMODE_WHEN_DIRTY·Î º¯°æÇϸé ÃÖÃÊ Çѹø ±×¸®±â¸¦ ¼öÇàÇÏ°í ´ÙÀ½ ±×¸®±â ¿äûÀÌ ÀÖÀ» ¶§±îÁö´Â È­¸éÀ» °»½ÅÇÏÁö ¾Ê´Â´Ù. Áöµµ ÇÁ·Î±×·¥À̳ª ¼³°è µµ¸éó·³ »ç¿ëÀÚÀÇ ÀÔ·ÂÀÌ ¾øÀ¸¸é ±»ÀÌ ´Ù½Ã ±×¸± ÇÊ¿ä°¡ ¾ø´Â ÇÁ·Î±×·¥Àº ÀÌ ¸ðµå¸¦ »ç¿ëÇÏ´Â °ÍÀÌ À¯¸®ÇÏ´Ù. ´Ù½Ã ±×¸®±â¸¦ ¿äûÇÒ ¶§´Â ´ÙÀ½ ¸Þ¼­µå¸¦ È£ÃâÇÑ´Ù.

 

void requestRender ()

 

ÀÌ ¸Þ¼­µå´Â ÀÓÀÇÀÇ ½º·¹µå¿¡ È£Ãâ °¡´ÉÇϹǷΠ±×¸®±â Á¤º¸°¡ ¹Ù²ï Áï½Ã ¾ðÁ¦µçÁö È£ÃâÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½ ¿¹Á¦´Â 2Â÷¿øÀÇ »ï°¢ÇüÀ» ±×¸°´Ù. ¾Èµå·ÎÀ̵å OpenGL ÇÁ·Î±×·¥ÀÇ °¡Àå °£´ÜÇÑ ¿¹À̸ç ÀÌ °­Á¿¡¼­ À©µµ¿ì¿ëÀ¸·Î óÀ½ ¸¸µé¾ú´ø ¿¹Á¦¸¦ ¾Èµå·ÎÀ̵å·Î Æ÷ÆÃÇÑ °ÍÀÌ´Ù.

 

Triangle

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import android.app.*;

import android.opengl.*;

import android.os.*;

 

public class Triangle extends Activity {

     GLSurfaceView mGLSurfaceView;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new GLSurfaceView(this);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

    

     class Renderer implements GLSurfaceView.Renderer {

          public Renderer() {

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

              gl.glColor4f(1,1,0,1);

 

              float vert[] = {0, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(vert.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer vertbuf = bytebuf.asFloatBuffer();

              vertbuf.put(vert);

              vertbuf.position(0);

             

              gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertbuf);

              gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

          }

     }

}

 

È­¸é Áß¾Ó¿¡ ³ë¶õ»ö »ï°¢Çü Çϳª¸¸ ±×·Á º¸¾Ò´Ù. ÀåºñÀÇ È­¸éÀÌ ¼¼·Î·Î ±æÂßÇϱ⠶§¹®¿¡ »ï°¢Çüµµ ±æÂßÇÑ ¸ð¾çÀ¸·Î ±×·ÁÁø´Ù.

onCreate¿¡¼­ GLSurfaceView °´Ã¼¸¦ »ý¼ºÇÏ°í GLSurfaceView.Renderer ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â Renderer °´Ã¼¸¦ »ý¼ºÇÏ¿© ÁöÁ¤Çß´Ù. 2Â÷¿øÀÇ ´Ü¼øÇÑ »ï°¢ÇüÀÏ »ÓÀÌ°í È­¸éÀÌ ¹Ù²î´Â °Íµµ ¾Æ´Ï¹Ç·Î ·£´õ ¸ðµå´Â ºñ¿¬¼Ó ¸ðµå·Î ÁöÁ¤Çß´Ù. ·£´õ ¸ðµå¸¦ º¯°æÇÏÁö ¾ÊÀ¸¸é ¶È°°Àº È­¸éÀ» °è¼Ó ±×¸®¹Ç·Î CPU¸¦ Ȥ»çÇÏ°í ¹èÅ͸®µµ ±Ý¹æ ¼ÒÁøµÉ °ÍÀÌ´Ù.

·£´õ·¯°¡ ÁöÁ¤µÈ GLSurfaceView °´Ã¼¸¦ ¾×ƼºñƼÀÇ ³»¿ë¹°·Î ä¿ì¸é ÀÌ Ç¥¸é¿¡ ·£´õ·¯°¡ Àå¸éÀ» ±×¸°´Ù. ¾×ƼºñƼ´Â onResume, onPuase¿¡¼­ GLSurfaceViewÀÇ µ¿ÀÏ ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ¸®¼Ò½º¿Í ±×¸®±â ½º·¹µå¸¦ °ü¸®ÇÒ ¼ö ÀÖµµ·Ï ÇØ¾ß ÇÑ´Ù.

·£´õ·¯´Â ¼¼ °³ÀÇ ¸Þ¼­µå¸¦ ±¸ÇöÇÑ´Ù. Ç¥¸éÀÌ »ý¼ºµÉ ¶§ ¿©·¯ °¡Áö ÃʱâÈ­¸¦ ÇÒ ¼ö Àִµ¥ ¹è°æ»öÀ» £Àº ȸ»öÀ¸·Î º¯°æÇÏ¿´´Ù. OpenGL ES´Â Á÷Á¢ ±×¸®±â¸¦ Áö¿øÇÏÁö ¾ÊÀ¸¹Ç·Î Á¤Á¡ ¹è¿­À» ¹Ýµå½Ã »ç¿ëÇØ¾ß ÇÑ´Ù. Ç¥¸éÀÌ »ý¼ºµÉ ¶§ GL_VERTEX_ARRAY ±â´ÉÀ» Ä×´Ù. Ç¥¸éÀÇ Å©±â°¡ °áÁ¤µÉ ¶§´Â ºäÆ÷Æ®¸¦ ºäÀÇ Å©±â¿¡ ¸ÂÃß¾ú´Ù. ÇÊ¿äÇÏ´Ù¸é ºäÀÇ ÀϺο¡¸¸ Ãâ·ÂÇÒ ¼öµµ ÀÖ°í Á¾È¾ºñ¸¦ ¸ÂÃâ ¼öµµ ÀÖ´Ù.

onDrawFrame¿¡¼­ ¹è°æÀ» ¸ÕÀú Áö¿ì°í Á¤Á¡ÀÇ »ö»óÀ» ³ë¶õ»öÀ¸·Î ÁöÁ¤Çß´Ù. glClear, glColor ÇÔ¼ö´Â OpenGL°ú µ¿ÀÏÇÏ´Ù. ´ÙÀ½Àº »ï°¢ÇüÀ» ±¸¼ºÇÏ´Â 3°³ÀÇ Á¤Á¡ ÁÂÇ¥¸¦ ¹è¿­¿¡ Á¤ÀÇÇÑ´Ù. µðÆúÆ® ÁÂÇ¥°è°¡ -1 ~ 1 »çÀÌÀ̹ǷΠÀÌ ¹üÀ§¾È¿¡ Á¤Á¡À» ¹èÄ¡Çß´Ù.

glVertexPointer µî ¹è¿­À» Àü´Þ¹Þ´Â ¸Þ¼­µå´Â ¹è¿­ ÀÚü¸¦ ¹ÞÁö ¾Ê°í ¹ÙÀÌÆ® ¼ø¼­¿¡ ´ëÇÑ Á¤º¸°¡ ¼³Á¤µÈ Buffer °´Ã¼¸¦ ¿ä±¸ÇϹǷΠ¹è¿­·ÎºÎÅÍ ¹öÆÛ °´Ã¼¸¦ »ý¼ºÇØ¾ß ÇÑ´Ù. ¹öÆÛ¸¦ °æÀ¯ÇÏ¿© Á¤Á¡ ¹è¿­¿¡ 2°³¾¿ ÇѽÖÀ¸·Î Á¤Á¡ÀÌ ÀúÀåµÇ¾î ÀÖÀ½À» ¾Ë·Á ÁÖ°í glDrawArrays ¸Þ¼­µå·Î »ï°¢ÇüÀ» ±×·È´Ù.

Triangle ¿¹Á¦´Â ±×¸®±â °ü·Ã Äڵ尡 ·£´õ·¯¿¡ ¸ðµÎ ÀÛ¼ºµÇ¾î ÀÖÀ¸¹Ç·Î ÇÑ´«¿¡ ¾Ë¾Æ º¸±â´Â ½±´Ù. ±×·¯³ª ÀýÂ÷ÀûÀ¸·Î ³ª¿­µÈ ÄÚµå¶ó °ü¸®Çϱ⿡´Â ÁÁÁö ¾Ê°í ¸Å Àå¸éÀ» ±×¸± ¶§¸¶´Ù ¹è¿­À» ´Ù½Ã ÃʱâÈ­Çϱ⠶§¹®¿¡ ½ÇÇà ¼Óµµ¿¡µµ ºÒ¸®ÇÏ´Ù. OpenGLÀº C ¼öÁØÀÇ ¶óÀ̺귯¸®ÀÌÁö¸¸ ¾Èµå·ÎÀ̵åÀÇ °³¹ß ¾ð¾îÀÎ ÀÚ¹Ù´Â ¿ÏÀüÇÑ °´Ã¼ ÁöÇâ ¾ð¾îÀ̹ǷΠ°´Ã¼ ÁöÇâÀûÀ¸·Î ÀÛ¼ºÇÏ´Â °ÍÀÌ À¯¸®ÇÏ´Ù. µ¿ÀÏÇÑ ¿¹Á¦¸¦ ´Ù¸¥ Çü½ÄÀ¸·Î ÀÛ¼ºÇØ º¸ÀÚ.

 

Triangle2

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import android.app.*;

import android.opengl.*;

import android.os.*;

 

public class Triangle2 extends Activity {

     GLSurfaceView mGLSurfaceView;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new GLSurfaceView(this);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

    

     class Renderer implements GLSurfaceView.Renderer {

          TriangleObject triangle;

          public Renderer() {

              triangle = new TriangleObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

              triangle.draw(gl);

          }

     }

    

     class TriangleObject {

          float vert[] = {0, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };

          FloatBuffer vertbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

         

          public TriangleObject() {

              vertbuf = ArrayToBuffer(vert);

          }

         

          public void draw(GL10 gl) {

              gl.glColor4f(1,1,0,1);

             

              gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertbuf);

              gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

          }

     }

}

 

 

½ÇÇà °á°ú´Â ¿ÏÀüÈ÷ µ¿ÀÏÇÏ´Ù. »ï°¢Çü°ú °ü·ÃµÈ Äڵ尡 TriangleObject °´Ã¼ ¾ÈÀ¸·Î ĸ½¶È­µÇ¾ú´Ù. Á¤Á¡ÀÇ ¹è¿­°ú ¹öÆÛ´Â ¸â¹ö·Î ¼±¾ðµÇ¾ú°í »ý¼ºÀÚ¿¡¼­ ¹è¿­À» ¹Ì¸® ¹öÆÛ·Î ¹Ù²Ù¾î µÐ´Ù. draw ¸Þ¼­µå¿¡¼­´Â »ö»óÀ» ÁöÁ¤ÇÏ°í Á¤Á¡ ¹è¿­·Î »ï°¢ÇüÀ» ±×¸®±â¸¸ ÇÑ´Ù.

·£´õ·¯´Â TriangleObject¸¦ ¸â¹ö·Î ¼±¾ðÇØ ³õ°í onDrawFrame¿¡¼­ »ï°¢Çü°ú °ü·ÃµÈ ±×¸®±â´Â °´Ã¼ÀÇ draw ¸Þ¼­µå·Î ±×¸°´Ù. µµÇüµéÀÌ ±²ÀåÈ÷ ¸¹¾Æµµ Äڵ尡 ü°èÀûÀ¸·Î ³ª´©¾îÁö¹Ç·Î °ü¸®Çϱâ ÁÁ°í ±×¸®±â¿¡ °ü·ÃµÈ ¿¹ºñ µ¿ÀÛÀ» °´Ã¼ ¼öÁØ¿¡¼­ ÁغñÇϹǷΠ¼Óµµ¿¡µµ À¯¸®ÇÏ´Ù.

11-3.ÀÔü µµÇü

ÀÔü µµÇüÀ» ±×¸®´Â ¹æ¹ýµµ À©µµ¿ìÁî¿Í º°¹Ý ´Ù¸£Áö ¾Ê´Ù. ¾çÀÌ Á» ´Ã¾î³¯ »Ó ÁúÀûÀ¸·Î ¾Õ ¿¹Á¦¿Í Å©°Ô ´Ù¸¥ Á¡Àº ¾ø´Ù.

 

Pyramid

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import android.app.*;

import android.content.*;

import android.opengl.*;

import android.os.*;

import android.view.*;

 

public class Pyramid extends Activity {

     GLSurfaceView mGLSurfaceView;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new GLSurfaceView(this);

          mGLSurfaceView.setRenderer(new Renderer());

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

 

     class Renderer implements GLSurfaceView.Renderer {

          PyramidObject pyramid;

          public Renderer() {

              pyramid = new PyramidObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

 

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

              gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

              gl.glShadeModel(GL10.GL_FLAT);

              gl.glEnable(GL10.GL_DEPTH_TEST);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

             

              gl.glRotatef(0.3f, 1, 0, 0);

              gl.glRotatef(1.0f, 0, 1, 0);

             

              pyramid.draw(gl);

          }

     }

    

     class PyramidObject {

          float vert[] = {

                   0, 0, -0.8f,              // Áß¾Ó

                   0.5f, 0.5f, 0,            // ¿ì»ó

                   -0.5f, 0.5f, 0,           // Á»ó

                   -0.5f, -0.5f, 0,         // ÁÂÇÏ

                   0.5f, -0.5f, 0,           // ¿ìÇÏ

                   0.5f, 0.5f, 0,            // ¹Ø¸é ¿ì»ó

          };

 

          float color[] = {

              1,1,1,1,                  // Áß¾Ó

              0,0,1,1,                  // ¿ì»ó

              1,0,0,1,                  // Á»ó

              1,1,0,1,                  // ÁÂÇÏ

               0,1,0,1,                  // ¿ìÇÏ

              1,1,1,1,                  // ¹Ø¸é ¿ì»ó

          };

 

          byte index[] = {

              3, 2, 5,              // ¹Ø¸é1

              4, 3, 5,              // ¹Ø¸é2

              0, 1, 2,              //12½Ã

              0, 2, 3,              // 9½Ã

              0, 3, 4,              // 6½Ã

              0, 4, 1,              // 3½Ã

          };

          FloatBuffer vertbuf;

          FloatBuffer colorbuf;

          ByteBuffer indexbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

         

          public PyramidObject() {

              vertbuf = ArrayToBuffer(vert);

              colorbuf = ArrayToBuffer(color);

             

              indexbuf = ByteBuffer.allocateDirect(index.length);

              indexbuf.put(index);

              indexbuf.position(0);

          }

 

          public void draw(GL10 gl) {

              gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertbuf);

              gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorbuf);

              gl.glDrawElements(GL10.GL_TRIANGLES, index.length,

                        GL10.GL_UNSIGNED_BYTE, indexbuf);

          }

     }

}

 

 

ÀÔüÀ̹ǷΠÁ¤Á¡ ¹è¿­¿¡ z ÁÂÇ¥¸¦ Çϳª ´õ ³Ö¾î ÁÖ¸é µÈ´Ù. »ö»óÀ» ÀÔÈ÷·Á¸é »ö»ó ¹è¿­µµ ÁöÁ¤ÇØ¾ß ÇÏ°í GL_COLOR_ARRAY ±â´Éµµ ¹Ýµå½Ã ÄÑ ÁÖ¾î¾ß ÇÑ´Ù. ±×¸®°í ÀÔüÀ̹ǷΠ±íÀÌ Å×½ºÆ®µµ ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. ¼ÎÀÌµå ¸ðµ¨Àº ´Ü»öÀ¸·Î ÁöÁ¤Çß´Ù.

vert ¹è¿­¿¡´Â z ÁÂÇ¥°¡ Çϳª ´õ ´Ã¾î³µ´Ù. ES´Â »ç°¢ÇüÀ» Áö¿øÇÏÁö ¾ÊÀ¸¹Ç·Î ¹Ø¸éÀÇ »ç°¢ÇüÀº µÎ °³ÀÇ »ï°¢ÇüÀ¸·Î ºÐÇÒÇؼ­ ±×·Á¾ß ÇÑ´Ù. ÇǶó¹Ìµå¸¦ ±¸¼ºÇÏ´Â Á¤Á¡À» ÁöÁ¤Ç쵂 ¹Ø¸é »ç°¢ÇüÀÇ »ö»óÀÌ ´Ù¸£¹Ç·Î ¿À¸¥ÂÊ À§ ÁÂÇ¥¸¦ Çѹø ´õ ½á ÁÖ¾ú´Ù. ÁÂÇ¥´Â »ï°¢ÇüÀÇ Á¤Á¡°ú µ¿ÀÏÇÏÁö¸¸ ´ëÀÀµÇ´Â »ö»óÀÌ ´Ù¸£¹Ç·Î Áߺ¹µÈ Á¤Á¡ÀÌ Çϳª ´õ ÇÊ¿äÇÏ´Ù.

»ö»ó ¹è¿­¿¡´Â °¢ Á¤Á¡ÀÇ »ö»óÀ» Àû´Â´Ù. ¾ËÆÄ°ª±îÁö ¹Ýµå½Ã 4°³ÀÇ ¿ä¼Ò¸¦ ´Ù ÁöÁ¤ÇØ¾ß ÇÑ´Ù. °¢¸é¿¡ ¿ø»öÀ» ÁöÁ¤Çß°í ¹Ø¸éÀº Èò»öÀ¸·Î ÁöÁ¤Çß´Ù. À妽º ¹è¿­¿¡´Â ¹°Ã¼¸¦ ±¸¼ºÇÏ´Â °¢ »ï°¢ÇüÀÇ Á¤Á¡ÀÌ ±â·ÏµÇ¾î ÀÖ´Ù. ½ÇÇà °á°ú´Â ´ÙÀ½°ú °°´Ù.

ÇǶó¹ÌµåÀÇ ²ÀÁöÁ¡ÀÌ Á¤¸éÀ» º¸°í ÀÖ´Â »óŶó ±×´ë·Î µÖ¼­´Â ÀÔüÀÎÁö È®ÀεÇÁö ¾Ê´Â´Ù. ±×·¡¼­ ·£´õ ¸ðµå¸¦ ¿¬¼ÓÀ¸·Î ÁöÁ¤ÇÏ°í ¸Å¹ø ±×¸®±â¸¦ ÇÒ ¶§¸¶´Ù xÃà ±âÁØÀ¸·Î 0.3µµ, yÃà ±âÁØÀ¸·Î 1µµ¸¸Å­ ȸÀü½ÃÄ×´Ù. ¾ó¸¶³ª »¡¸® ȸÀüÇÒ °ÍÀΰ¡´Â ÀåºñÀÇ ¼Óµµ¿¡ µû¶ó ´Ù¸£´Ù.

ÀÚµ¿ ȸÀüÀº ÀÔüÀÓÀ» È®ÀÎÇØ º¼ ¼ö ÀÖÁö¸¸ »ç¿ëÀÚ°¡ Á÷Á¢ ȸÀü½ÃÅ°´Â °ÍÀÌ ¾Æ´Ï¹Ç·Î ¹°Ã¼ÀÇ ¿ä¸ð Á¶¸ð¸¦ Äf¾î º¸±â¿¡´Â ºÒÆíÇÏ´Ù. ´ÙÀ½ ¿¹Á¦´Â »ç¿ëÀÚÀÇ Å°º¸µå, ÅÍÄ¡ ÀÔ·ÂÀ» ¹Þ¾Æ¼­ ¹°Ã¼¸¦ ȸÀü½ÃŲ´Ù.

 

Rotate

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import exam.andexam_opengl.Pyramid.*;

 

import android.app.*;

import android.content.*;

import android.opengl.*;

import android.os.*;

import android.view.*;

 

public class Rotate extends Activity {

     MySurface mGLSurfaceView;

     float xAngle, yAngle, zAngle;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new MySurface(this);

          mGLSurfaceView.setFocusable(true);

          mGLSurfaceView.setFocusableInTouchMode(true);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

 

     class MySurface extends GLSurfaceView {

 

          public MySurface(Context context) {

              super(context);

          }

         

          public boolean onKeyDown(int keyCode, KeyEvent event) {

              switch (keyCode) {

              case KeyEvent.KEYCODE_A:

                   yAngle += 2;

                   break;

              case KeyEvent.KEYCODE_D:

                   yAngle -= 2;

                   break;

              case KeyEvent.KEYCODE_W:

                   xAngle += 2;

                   break;

              case KeyEvent.KEYCODE_S:

                   xAngle -= 2;

                   break;

              case KeyEvent.KEYCODE_Q:

                    zAngle += 2;

                   break;

              case KeyEvent.KEYCODE_E:

                   yAngle -= 2;

                   break;

              case KeyEvent.KEYCODE_Z:

                   xAngle = yAngle = zAngle = 0;

                   break;

              }

              if (keyCode == KeyEvent.KEYCODE_A) {

                   yAngle += 2;

              }

 

              requestRender();

              return super.onKeyDown(keyCode, event);    

          }

         

          public boolean onTouchEvent(MotionEvent event) {

              WindowManager wm = (WindowManager)getSystemService(

                        Context.WINDOW_SERVICE);

              Display dis = wm.getDefaultDisplay();

              int mx = (int) (event.getX()/(dis.getWidth()/3));

              int my = (int) (event.getY()/(dis.getHeight()/3));

              int pos = my * 3 + mx;

             

              switch(pos) {

              case 0:

                   zAngle += 2;

                   break;

              case 1:

                   xAngle += 2;

                   break;

              case 2:

                   zAngle -= 2;

                   break;

              case 3:

              case 6:

                   yAngle += 2;

                   break;

              case 4:

                   xAngle = yAngle = zAngle = 0;

                   break;

              case 5:

              case 8:

                   yAngle -= 2;

                   break;

              case 7:

                   xAngle -= 2;

                   break;

              }

             

              requestRender();

              return super.onTouchEvent(event);

          }

     }

    

     class Renderer implements GLSurfaceView.Renderer {

          PyramidObject pyramid;

          public Renderer() {

              pyramid = new PyramidObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

 

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

              gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

              gl.glShadeModel(GL10.GL_SMOOTH);

              gl.glEnable(GL10.GL_DEPTH_TEST);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

             

              gl.glMatrixMode(GL10.GL_MODELVIEW);

              gl.glLoadIdentity();

              gl.glRotatef(xAngle, 1, 0, 0);

              gl.glRotatef(yAngle, 0, 1, 0);

              gl.glRotatef(zAngle, 0, 0, 1);

             

              pyramid.draw(gl);

          }

     }

 

     class PyramidObject {

          float vert[] = {

                   0, 0, -0.8f,              // Áß¾Ó

                   0.5f, 0.5f, 0,            // ¿ì»ó

                   -0.5f, 0.5f, 0,           // Á»ó

                   -0.5f, -0.5f, 0,         // ÁÂÇÏ

                   0.5f, -0.5f, 0,           // ¿ìÇÏ

                   0.5f, 0.5f, 0,            // ¹Ø¸é ¿ì»ó

              };

 

          // »ö»ó°ª¿¡ ¾ËÆĵµ ¹Ýµå½Ã ÇÊ¿äÇÔ.

          float color[] = {

              1,1,1,1,                  // Áß¾Ó

              0,0,1,1,                  // ¿ì»ó

              1,0,0,1,                  // Á»ó

              1,1,0,1,                  // ÁÂÇÏ

              0,1,0,1,                  // ¿ìÇÏ

              1,1,1,1,                  // ¹Ø¸é ¿ì»ó

          };

 

          byte index[] = {

              3, 2, 5,              // ¹Ø¸é1

              4, 3, 5,              // ¹Ø¸é2

              0, 1, 2,              //12½Ã

              0, 2, 3,              // 9½Ã

              0, 3, 4,              // 6½Ã

              0, 4, 1,              // 3½Ã

          };

          FloatBuffer vertbuf;

          FloatBuffer colorbuf;

          ByteBuffer indexbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

 

          public PyramidObject() {

              vertbuf = ArrayToBuffer(vert);

              colorbuf = ArrayToBuffer(color);

             

               indexbuf = ByteBuffer.allocateDirect(index.length);

              indexbuf.put(index);

              indexbuf.position(0);

          }

 

          public void draw(GL10 gl) {

              gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertbuf);

              gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorbuf);

              gl.glDrawElements(GL10.GL_TRIANGLES, index.length,

                        GL10.GL_UNSIGNED_BYTE, indexbuf);

          }

     }

}

 

 

ÀÔ·ÂÀÌ ÀÖÀ» ¶§¸¸ ´Ù½Ã ±×¸®¸é µÇ¹Ç·Î ·£´õ ¸ðµå´Â ¿¬¼ÓÀ¸·Î ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ¼ÎÀÌµå ¸ðµå´Â µðÆúÆ®ÀÎ GL_SMOOTH¸¦ ¹Þ¾ÆµéÀ̵µ·Ï Çß´Ù. °¢ ¸éÀÇ »ö»óÀÌ È­·ÁÇÏ°Ô ±×¶óµ¥ÀÌ¼Ç Ã³¸®µÈ´Ù.

ÀÔ·ÂÀ» ¹ÞÀ¸·Á¸é GLSurfaceView¸¦ »ó¼Ó¹Þ¾Æ ÀÔ·Â ¸Þ¼­µå¸¦ ÀçÁ¤ÀÇÇØ¾ß Çϸç Å°º¸µå ÀÔ·ÂÀ» ¹ÞÀ¸·Á¸é Æ÷Ä¿½º¸¦ ¹Ýµå½Ã ÁÖ¾î¾ß ÇÑ´Ù. x, y, z ¼¼ Ãà¿¡ ´ëÇÑ È¸Àü °¢µµ¸¦ º¯¼ö·Î Á¤ÀÇÇÏ°í onDrawFrame¿¡¼­ °¢ Ãà¿¡ µû¶ó ȸÀü½ÃÄ×´Ù. Çѹø ȸÀüÇØ ³õÀº °ÍÀº ´ÙÀ½¹ø ±×¸®±â¿¡µµ ´©ÀûÀûÀ¸·Î Àû¿ëµÇ¹Ç·Î ȸÀüÇϱâ Àü¿¡ ¸ðµ¨ºä Çà·ÄÀ» ¹Ýµå½Ã ¸®¼ÂÇØ¾ß ÇÔÀ» ÁÖÀÇÇÏÀÚ.

Å°º¸µå ó¸® ·çƾÀº ¾ÆÁÖ ½±´Ù. ad ÀÔ·ÂÀ¸·Î yÃà, ws ÀÔ·ÂÀ¸·Î xÃà, qe ÀÔ·ÂÀ¸·Î zÃà °¢µµ¸¦ Áõ°¨½ÃÅ°°í requestRender ¸Þ¼­µå¸¦ È£ÃâÇÏ¿© ´Ù½Ã ±×¸®±â¸¸ ÇÏ¸é µÈ´Ù. ÅÍÄ¡ ó¸® ·çƾÀº ¾à°£ º¹ÀâÇØ º¸À̴µ¥ È­¸éÀ» 9ºÐÇÒÇÏ°í °¢ ºÐÇÒ¸éÀÇ ÅÍÄ¡¸¦ ÀÔ·Â¹Þ¾Æ È¸Àü½ÃÅ°´Â °ÍÀÌ´Ù. Á¤ Áß¾ÓÀ» ´©¸£¸é ¸®¼ÂµÈ´Ù. ´ÙÀ½ ¿¹Á¦´Â »ö»ó Å¥ºê À°¸éü¸¦ ±×¸®°í ÅÍÄ¡ µå·¡±×·Î ȸÀü½ÃŲ´Ù.

 

ColorCube

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import android.app.*;

import android.content.*;

import android.opengl.*;

import android.os.*;

import android.view.*;

 

public class ColorCube extends Activity {

     MySurface mGLSurfaceView;

     float xAngle= 45, yAngle = 45;

     float oldx, oldy;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new MySurface(this);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

    

     class MySurface extends GLSurfaceView {

          final static float DRAGSPEED = 5;

          public MySurface(Context context) {

              super(context);

          }

         

          public boolean onTouchEvent(MotionEvent event) {

              float x = event.getX();

             float y = event.getY();

 

             if (event.getAction() == MotionEvent.ACTION_MOVE) {

               float dx = (oldx - x)/DRAGSPEED;

               float dy = (oldy - y)/DRAGSPEED;

            

               yAngle += dx;

               xAngle += dy;

              

                   requestRender();

             }

 

          oldx = x;

          oldy = y;

 

          return true;

          }

     }

 

     class Renderer implements GLSurfaceView.Renderer {

          CubeObject cube;

          public Renderer() {

              cube = new CubeObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

              gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

              gl.glEnable(GL10.GL_DEPTH_TEST);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

             

              gl.glMatrixMode(GL10.GL_MODELVIEW);

              gl.glLoadIdentity();

              gl.glRotatef(xAngle, 1, 0, 0);

              gl.glRotatef(yAngle, 0, 1, 0);

 

              cube.draw(gl);

          }

     }

    

     class CubeObject {

          float vert[] = {

                   -0.5f, 0.5f, -0.5f,

                   0.5f, 0.5f, -0.5f,

                   0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, -0.5f,

                   -0.5f, 0.5f, 0.5f,

                   0.5f, 0.5f, 0.5f,

                   0.5f, -0.5f, 0.5f,

                   -0.5f, -0.5f, 0.5f,

              };

         

          float color[] = {

                   0,1,1,1,

                   1,1,1,1,

                   1,1,0,1,

                   0,1,0,1,

                   0,0,1,1,

                   1,0,1,1,

                   1,0,0,1,

                   0,0,0,1,

              };

         

          byte index[] = {

                   0,3,1,  1,3,2,

                   1,2,6,  1,6,5,

                   0,1,4,  1,5,4,

                   4,5,7,  7,5,6,

                   0,4,7,  0,7,3,

                   3,7,2,  2,7,6,

              };

         

          FloatBuffer vertbuf;

          FloatBuffer colorbuf;

          ByteBuffer indexbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

 

          public CubeObject() {

              vertbuf = ArrayToBuffer(vert);

              colorbuf = ArrayToBuffer(color);

             

              indexbuf = ByteBuffer.allocateDirect(index.length);

              indexbuf.put(index);

              indexbuf.position(0);

          }

         

          public void draw(GL10 gl) {

               gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertbuf);

              gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorbuf);

              gl.glDrawElements(GL10.GL_TRIANGLES, index.length,

                        GL10.GL_UNSIGNED_BYTE, indexbuf);

          }

     }

}

 

À°¸éü´Â »ç°¢Çü 6°³·Î ±¸¼ºµÇ¾î ÀÖÁö¸¸ »ï°¢ÇüÀ¸·Î ÂÉ°³¼­ ±×·Á¾ß ÇϹǷΠ12°³ÀÇ »ï°¢ÇüÀÌ ÇÊ¿äÇÏ´Ù. Á¤Á¡ ¹è¿­ÀÌ »ó´çÈ÷ º¹ÀâÇØ º¸À̴µ¥ ´ÙÀ½°ú °°ÀÌ °¢ Á¤Á¡¿¡ ¹øÈ£¸¦ ºÙ¿© µÎ°í ÁÂÇ¥¸¦ »ý°¢ÇØ º¸¸é ½±°Ô ±¸ÇÒ ¼ö ÀÖ´Ù.

°¢ Á¤Á¡ÀÇ »ö»óÀº »ö»ó Å¥ºê¿¡ ¸Â°Ô ÇÒ´çÇß´Ù. Á¦ÀÏ ¾ÈÂÊ ¸ð¼­¸®°¡ °ËÁ¤»öÀÌ°í xÃàÀ¸·Î »¡°­, yÃàÀ¸·Î ÆĶû, zÃàÀ¸·Î ÃÊ·Ï»öÀÌ´Ù.

onTouchEvent¿¡¼­ µå·¡±×ÇÏ¿© °¢µµ¸¦ °è»êÇÏ´Â ÄÚµå´Â Áö±ØÈ÷ ±âº»ÀûÀÎ ÄÚµåÀÌ´Ù. ¸Å À̵¿°Å¸®¸¸Å­ °¢µµ¸¦ Áõ°¨½ÃÅ°µÇ ÅÍÄ¡ À̵¿ °Å¸®°¡ °¢µµº¸´Ù´Â Á» °úÀåµÇ¾î ÀÖÀ¸¹Ç·Î Àû´çÈ÷ ³ª´©¾î õõÈ÷ ȸÀüÇϵµ·Ï Çß´Ù.

11-4.ÅؽºÃ³

´ÙÀ½ ¿¹Á¦´Â À°¸éü¿¡ ¿Á¼ö¼ö »çÁø ÅؽºÃ³¸¦ ÀÔÈù´Ù. ÅؽºÃ³ À̹ÌÁö´Â 128Å©±âÀÇ cornpng.png ÆÄÀÏ·Î ÁغñÇß´Ù. ¾ÐÃà Æ÷¸ËÀÇ À̹ÌÁöµµ »ç¿ë °¡´ÉÇÏ´Ù.

 

TextureCube

package exam.andexam_opengl;

 

import java.io.*;

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import android.app.*;

import android.content.*;

import android.graphics.*;

import android.opengl.*;

import android.os.*;

import android.view.*;

 

public class TextureCube extends Activity {

     MySurface mGLSurfaceView;

     float xAngle= 45, yAngle = 45;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new MySurface(this);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

    

     class MySurface extends GLSurfaceView {

          final static float DRAGSPEED = 5;

          float oldx, oldy;

          public MySurface(Context context) {

              super(context);

          }

         

          public boolean onTouchEvent(MotionEvent event) {

              float x = event.getX();

             float y = event.getY();

 

             if (event.getAction() == MotionEvent.ACTION_MOVE) {

               float dx = (oldx - x)/DRAGSPEED;

               float dy = (oldy - y)/DRAGSPEED;

            

               yAngle += dx;

               xAngle += dy;

              

                   requestRender();

             }

 

          oldx = x;

          oldy = y;

 

          return true;

          }

     }

 

     class Renderer implements GLSurfaceView.Renderer {

          CubeObject cube;

          public Renderer() {

              cube = new CubeObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

              gl.glEnable(GL10.GL_DEPTH_TEST);

              gl.glEnable(GL10.GL_TEXTURE_2D);

              gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

 

              InputStream stream = getResources().openRawResource(R.drawable.cornpng);

              Bitmap bitmap = BitmapFactory.decodeStream(stream);

              try {

                   stream.close();

              } catch (IOException e) { ; }

 

              int[] textures = new int[1];

              gl.glGenTextures(1, textures, 0);

              gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

              gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);

              gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

              GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

              bitmap.recycle();

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

             

              gl.glMatrixMode(GL10.GL_MODELVIEW);

              gl.glLoadIdentity();

              gl.glRotatef(xAngle, 1, 0, 0);

              gl.glRotatef(yAngle, 0, 1, 0);

 

              cube.draw(gl);

          }

     }

    

     class CubeObject {

          float vert[] = {

                   -0.5f, 0.5f, -0.5f,           // 0

                   0.5f, 0.5f, -0.5f,

                   0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, -0.5f,

                  

                   -0.5f, 0.5f, 0.5f,            // 4

                   0.5f, 0.5f, 0.5f,

                   0.5f, 0.5f, -0.5f,

                   -0.5f, 0.5f, -0.5f,

 

                   -0.5f, 0.5f, 0.5f,            // 8

                   0.5f, 0.5f, 0.5f,

                   0.5f, -0.5f, 0.5f,

                   -0.5f, -0.5f, 0.5f,

         

                   -0.5f, -0.5f, 0.5f,           // 12

                   0.5f, -0.5f, 0.5f,

                   0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, -0.5f,

 

                   0.5f, 0.5f, -0.5f,            // 16

                   0.5f, 0.5f, 0.5f,

                   0.5f, -0.5f, 0.5f,

                   0.5f, -0.5f, -0.5f,

 

                   -0.5f, 0.5f, -0.5f,           // 20

                   -0.5f, 0.5f, 0.5f,

                   -0.5f, -0.5f, -0.5f,

                    -0.5f, -0.5f, 0.5f,

          };

         

         

          float text[] = {

                   0,1,1,1,1,0,0,0,

                   0,1,1,1,1,0,0,0,

                   0,1,1,1,1,0,0,0,

                   0,1,1,1,1,0,0,0,

                   0,1,1,1,1,0,0,0,

                   0,1,1,1,1,0,0,0,

          };

         

          byte index[] = {

                   0,3,1,  1,3,2,

                   4,7,6,  4,6,5,

                   8,11,10,    8,10,9,

                   12,14,15,  12,13,14,

                   16,18,19,  16,18,17,

                   20,23,22,  20,21,23, 

          };

         

          FloatBuffer vertbuf;

          FloatBuffer textbuf;

          ByteBuffer indexbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

 

          public CubeObject() {

              vertbuf = ArrayToBuffer(vert);

              textbuf = ArrayToBuffer(text);

 

               indexbuf = ByteBuffer.allocateDirect(index.length);

              indexbuf.put(index);

              indexbuf.position(0);

          }

         

          public void draw(GL10 gl) {

              gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertbuf);

              gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textbuf);

              gl.glDrawElements(GL10.GL_TRIANGLES, index.length,

                        GL10.GL_UNSIGNED_BYTE, indexbuf);

          }

     }

}

 

ÅؽºÃ³·Î Ç¥¸éÀ» µ¤À» °ÍÀ̹ǷΠ»ö»ó ¹è¿­Àº Á¦¿ÜÇß´Ù. ¹°·Ð »ö»ó ¹è¿­°ú ÇÔ²² ÅؽºÃ³¸¦ ¾µ ¼öµµ ÀÖ´Ù. »ö»ó Å¥ºê´Â °¢ ¹øÈ£¿¡ µû¶ó Á¤Á¡À» Á¤ÀÇÇØ ³õ°í °øÀ¯ÇÏ¸é µÇÁö¸¸ ÅؽºÃ³¸¦ ÀÔÈú ¶§´Â °°Àº Á¤Á¡ÀÌ¶óµµ ¼Ò¼ÓµÇ´Â ¸é¿¡ µû¶ó ÅؽºÃ³ ÁÂÇ¥°¡ ´Þ¶óÁö¹Ç·Î °¢ ¸é¿¡ µû¶ó Á¤Á¡À» ÀÏÀÏÀÌ Á¤ÀÇÇØ¾ß ÇÑ´Ù. ±×¸®°í ´ëÀÀµÇ´Â Á¤Á¡¿¡ ´ëÇØ À̹ÌÁöÀÇ ¾î¶² ºÎºÐÀÌ ¸ÊÇ뵃 °ÍÀÎÁö ÁÂÇ¥µµ ÀÏÀÏÀÌ ÁöÁ¤ÇØ¾ß ÇÑ´Ù. Á¤Á¡ÀÇ ¹øÈ£¸¦ ´ÙÀ½°ú °°ÀÌ »õ·Î ºÎ¿©Çß´Ù.

ÀüºÎ ¿ÞÂÊ À§¿¡¼­ºÎÅÍ ½Ã°è ¹æÇâÀ¸·Î ¹øÈ£¸¦ ¸Å±èÀ¸·Î½á ÅؽºÃ³¿Í ´ëÀÀµÇ´Â ÁöÁ¡À» ÀÏÄ¡½ÃÄ×´Ù. ½ÇÇà °á°ú´Â ´ÙÀ½°ú °°´Ù.

¿Á¼ö¼ö À̹ÌÁö°¡ ³ª¸§ ¸ÔÀ½Á÷½º·´´Ù. Á¤Á¡À» ÀÏÀÏÀÌ ¹è¿­·Î ¸¸µå´À¶ó ÀÌ ¿¹Á¦ ÀÛ¼º¿¡ °ÅÀÇ 2½Ã°£ÀÌ °É·È´Ù.

11-5.Á¶¸í

´ÙÀ½ ¿¹Á¦´Â À°¸éü¿¡ ÁÖº¯±¤°ú ºÐ»ê±¤À» ºñÃá´Ù.

 

Lighting

package exam.andexam_opengl;

 

import java.nio.*;

 

import javax.microedition.khronos.egl.*;

import javax.microedition.khronos.opengles.*;

 

import exam.andexam_opengl.TextureCube.*;

 

import android.app.*;

import android.content.*;

import android.opengl.*;

import android.os.*;

import android.view.*;

 

public class Lighting extends Activity {

     MySurface mGLSurfaceView;

     float xAngle, yAngle;

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

 

          mGLSurfaceView = new MySurface(this);

          mGLSurfaceView.setRenderer(new Renderer());

          mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

          setContentView(mGLSurfaceView);

     }

 

     protected void onResume() {

          super.onResume();

          mGLSurfaceView.onResume();

     }

 

     protected void onPause() {

          super.onPause();

          mGLSurfaceView.onPause();

     }

 

     class MySurface extends GLSurfaceView {

          final static float DRAGSPEED = 5;

          float oldx, oldy;

          public MySurface(Context context) {

              super(context);

          }

         

          public boolean onTouchEvent(MotionEvent event) {

              float x = event.getX();

             float y = event.getY();

 

             if (event.getAction() == MotionEvent.ACTION_MOVE) {

               float dx = (oldx - x)/DRAGSPEED;

               float dy = (oldy - y)/DRAGSPEED;

            

               yAngle += dx;

               xAngle += dy;

              

                   requestRender();

             }

 

          oldx = x;

          oldy = y;

 

          return true;

          }

     }

    

     class Renderer implements GLSurfaceView.Renderer {

          CubeObject cube;

          FloatBuffer AmbientBuffer;

          FloatBuffer DiffuseBuffer;

          FloatBuffer lightPosBuffer;

 

          public Renderer() {

              cube = new CubeObject();

          }

 

          public void onSurfaceCreated(GL10 gl, EGLConfig config) {

              gl.glClearColor(0.2f,0.2f,0.2f,1);

 

              gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

              gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

              gl.glShadeModel(GL10.GL_FLAT);

              gl.glEnable(GL10.GL_DEPTH_TEST);

 

              gl.glEnable(GL10.GL_LIGHTING);

              float[] Ambient = {0.5f, 0.5f, 0.5f, 1.0f};

              float[] Diffuse = {0.5f, 0.5f, 0.5f, 1.0f};

              float[] lightPos = {0.0f, 0.0f, -1.0f, 1.0f};

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(Ambient.length * 4);

              bytebuf.order(ByteOrder.nativeOrder());

              AmbientBuffer = bytebuf.asFloatBuffer();

              AmbientBuffer.put(Ambient);

              AmbientBuffer.position(0);

             

              bytebuf = ByteBuffer.allocateDirect(Diffuse.length * 4);

              bytebuf.order(ByteOrder.nativeOrder());

              DiffuseBuffer = bytebuf.asFloatBuffer();

              DiffuseBuffer.put(Diffuse);

              DiffuseBuffer.position(0);

             

              bytebuf = ByteBuffer.allocateDirect(lightPos.length * 4);

              bytebuf.order(ByteOrder.nativeOrder());

              lightPosBuffer = bytebuf.asFloatBuffer();

              lightPosBuffer.put(lightPos);

              lightPosBuffer.position(0);

 

              gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, AmbientBuffer);

              gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, DiffuseBuffer);

              gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosBuffer);

              gl.glEnable(GL10.GL_LIGHT0);

          }

 

          public void onSurfaceChanged(GL10 gl, int width, int height) {

              gl.glViewport(0, 0, width, height);

          }

 

          public void onDrawFrame(GL10 gl) {

              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

             

              gl.glMatrixMode(GL10.GL_MODELVIEW);

              gl.glLoadIdentity();

              gl.glRotatef(xAngle, 1, 0, 0);

              gl.glRotatef(yAngle, 0, 1, 0);

             

              cube.draw(gl);

          }

     }

    

     class CubeObject {

          float vert[] = {

                   -0.5f, 0.5f, -0.5f,           // 0

                   0.5f, 0.5f, -0.5f,

                   0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, -0.5f,

                  

                   -0.5f, 0.5f, 0.5f,            // 4

                   0.5f, 0.5f, 0.5f,

                   0.5f, 0.5f, -0.5f,

                   -0.5f, 0.5f, -0.5f,

 

                   -0.5f, 0.5f, 0.5f,            // 8

                   0.5f, 0.5f, 0.5f,

                   0.5f, -0.5f, 0.5f,

                   -0.5f, -0.5f, 0.5f,

         

                   -0.5f, -0.5f, 0.5f,           // 12

                   0.5f, -0.5f, 0.5f,

                   0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, -0.5f,

 

                   0.5f, 0.5f, -0.5f,            // 16

                   0.5f, 0.5f, 0.5f,

                   0.5f, -0.5f, 0.5f,

                   0.5f, -0.5f, -0.5f,

 

                   -0.5f, 0.5f, -0.5f,           // 20

                   -0.5f, 0.5f, 0.5f,

                   -0.5f, -0.5f, -0.5f,

                   -0.5f, -0.5f, 0.5f,

          };

         

          float normal[] = {

                   0.0f, 0.0f, -1.0f,

                   0.0f, 0.0f, -1.0f,

                   0.0f, 0.0f, -1.0f,

                   0.0f, 0.0f, -1.0f,

 

                   0.0f, 1.0f, 0.0f,

                   0.0f, 1.0f, 0.0f,

                   0.0f, 1.0f, 0.0f,

                   0.0f, 1.0f, 0.0f,

 

                   0.0f, 0.0f, 1.0f,

                   0.0f, 0.0f, 1.0f,

                   0.0f, 0.0f, 1.0f,

                   0.0f, 0.0f, 1.0f,

 

                   0.0f, -1.0f, 0.0f,

                   0.0f, -1.0f, 0.0f,

                   0.0f, -1.0f, 0.0f,

                   0.0f, -1.0f, 0.0f,

 

                   1.0f, 0.0f, 0.0f,

                   1.0f, 0.0f, 0.0f,

                   1.0f, 0.0f, 0.0f,

                   1.0f, 0.0f, 0.0f,

 

                   -1.0f, 0.0f, 0.0f,

                   -1.0f, 0.0f, 0.0f,

                   -1.0f, 0.0f, 0.0f,

                   -1.0f, 0.0f, 0.0f,

          };

         

          byte index[] = {

                   0,3,1,  1,3,2,

                   4,7,6,  4,6,5,

                   8,11,10,    8,10,9,

                   12,14,15,  12,13,14,

                   16,18,19,  16,18,17,

                   20,23,22,  20,21,23, 

          };

         

          FloatBuffer vertbuf;

          FloatBuffer normalbuf;

          ByteBuffer indexbuf;

         

          public FloatBuffer ArrayToBuffer(float[] ar) {

              ByteBuffer bytebuf = ByteBuffer.allocateDirect(ar.length*4);

              bytebuf.order(ByteOrder.nativeOrder());

              FloatBuffer buf = bytebuf.asFloatBuffer();

              buf.put(ar);

              buf.position(0);

              return buf;

          }

 

          public CubeObject() {

              vertbuf = ArrayToBuffer(vert);

              normalbuf = ArrayToBuffer(normal);

             

              indexbuf = ByteBuffer.allocateDirect(index.length);

              indexbuf.put(index);

              indexbuf.position(0);

          }

         

          public void draw(GL10 gl) {

              gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertbuf);

              gl.glNormalPointer(GL10.GL_FLOAT, 0, normalbuf);

              gl.glDrawElements(GL10.GL_TRIANGLES, index.length,

                        GL10.GL_UNSIGNED_BYTE, indexbuf);

          }

     }

}

 

 

Á¶¸íÀÌ Á¦´ë·Î ºñÃß±â À§Çؼ­´Â °¢ Á¤Á¡¿¡ ´ëÇØ ¹ý¼±À» ÁöÁ¤ÇØ¾ß ÇÑ´Ù. °¢ ¸é¿¡ ´ëÇØ ¹Ù±ùÂÊÀ¸·Î ´ÜÀ§ ±æÀÌÀÇ ¹ý¼±À» ÁöÁ¤Çߴµ¥ ÀǵµÇÑ´ë·Î ³ª¿ÀÁö ¾Ê¾Ò´Ù.

¿ÍÀεùÀÇ ¹®Á¦´Â ¾Æ´Ñ °Í °°°í ¹ý¼±À» Àß ¸ø ÁØ °Í °°Àºµ¥ ¾ÆÁ÷ ¹®Á¦¸¦ Á¤È®ÇÏ°Ô ÆľÇÇÏÁö ¸øÇß´Ù. Á» ´õ ¿¬±¸°¡ ÇÊ¿äÇÑ ºÎºÐÀÌ´Ù.