- Äɲ䵤줿¹Ô¤Ï¤³¤Î¿§¤Ç¤¹¡£
- ºï½ü¤µ¤ì¤¿¹Ô¤Ï¤³¤Î¿§¤Ç¤¹¡£
º£²ó¤ÏOpenGLES2¤ÇÈĥݥꥴ¥ó¤òÉÁ²è¤·¤Þ¤¹
&ref(screenshot2.PNG);
º£²ó¤Î¥×¥í¥°¥é¥à°ì¼°¤Ï¤³¤Á¤é
¡¦&ref(OpenGLES2DrawQuad.zip);
º£²ó°Ê¹ß¤«¤é
Á°²ó¤ÎOpenGLES.framework¡¢QuartzCore.framework¤Ë²Ã¤¨¤Æ
¿ô³Ø·×»»½èÍý¤Ê¤ÉÊØÍø¤ÊAPI¤âÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç
¡¦GLKit.framework
¤ò¥×¥í¥¸¥§¥¯¥È¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤
&ref(framework.png);
º£²ó¤Ï¤ä¤ë¤³¤ÈÀ¹¤ê¤À¤¯¤µ¤ó¤Ç¤¹¡£
²èÁüÉÕ¤Èĥݥꥴ¥ó¤òÉÁ²è¤¹¤ë¤¿¤á¤Ë¤Ï
°Ê²¼¤Î¼ê½ç¤¬É¬ÍפǤ¹¡£
¡¦¡ÄºÅÀ¹½Â¤¤ÎÄêµÁ
¡¦¢¥Æ¥¯¥¹¥Á¥ã¡Ê²èÁü¡Ë¤ÎÆɤ߹þ¤ß
¡¦£ÄºÅÀ¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È(VBO)¤ÎºîÀ®
¡¦¤ÄºÅÀ¥·¥§¡¼¥À¡¢¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤ÎºîÀ®¤ª¤è¤Ó¥³¥ó¥Ñ¥¤¥ë¡õ¥ê¥ó¥¯
¡¦¥¥·¥§¡¼¥ÀÊÑ¿ô¤ÎÀßÄê
¡¦¦ÄºÅÀ¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È¤ÎÉÁ²è
ÉÁ²è¤Îή¤ì¤ÏDrawQuadView.m¤Ë¤Þ¤È¤á¤Æ¤¢¤ë¤Î¤Ç
¤½¤Á¤é¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤
¡ÄºÅÀ¹½Â¤¤ÎÄêµÁ
ÉÁ²èÍѤÎĺÅÀ¥Ç¡¼¥¿¤òÄêµÁ¤·¤Þ¤¹
// ĺÅÀ¹½Â¤
typedef struct {
float Position[3]; // ĺÅÀºÂɸ
float TexCoord[2]; // ¥Æ¥¯¥¹¥Á¥ãºÂɸ
} Vertex;
#define TEX_COORD_MAX 1
// ĺÅÀ¥Ç¡¼¥¿
const Vertex Vertices[] = {
{{1, -1, 1}, {TEX_COORD_MAX, 0}},
{{1, 1, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},
{{-1, 1, 1}, {0, TEX_COORD_MAX}},
{{-1, -1, 1},{0, 0}},
};
// ĺÅÀ¥¤¥ó¥Ç¥Ã¥¯¥¹
const GLubyte Indices[] = {
2, 1, 0,
0, 3, 2,
};
º£²ó¤ÏĺÅÀ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç»ØÄꤷ¤¿ÄºÅÀ¤«¤éÀ®¤ë
»°³Ñ·Á¤ò£²¤Ä¹çÂΤ·¤Æ»Í³Ñ·Á¤òºîÀ®¤·¤Þ¤¹¡£
£³DÉÁ²è¤Î´ðËÜñ°Ì¤Ï»°³Ñ·Á¤Ç¤¹
¸Þ³Ñ·Á¤Ï»°³Ñ·Á»°¸Ä¡¢
Ï»³Ñ·Á¤Ï»°³Ñ·Á»Í¸Ä¤Ëʬ³ä²Äǽ¤È¤¤¤Ã¤¿¤è¤¦¤Ë
²¿³Ñ·Á¤Ç¤â»°³Ñ·Á¤Çɽ¸½¤Ç¤¤Þ¤¹¡£
»°³Ñ·Á¤Î¤è¤¦¤ËÉÁ²è¤Î´ðËܤȤʤëñ°Ì¤ò¥×¥ê¥ß¥Æ¥£¥Ö¤È¸Æ¤Ó¤Þ¤¹¡£
¾¤Ë¤â¡¢Àþ¤äÅÀ¤Ê¤É¤Î¥×¥ê¥ß¥Æ¥£¥Ö¤¬¤¢¤ê¤Þ¤¹¡£
¢¥Æ¥¯¥¹¥Á¥ã¡Ê²èÁü¡Ë¤ÎÆɤ߹þ¤ß
_texture = [[Texture alloc] initWithFile:[NSString stringWithUTF8String:"tile_floor.png"]];
£ÄºÅÀ¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È¡ÊVBO¡Ë¤ÎºîÀ®
ĺÅÀ¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È¤Ï
ÂçÎ̤ÎĺÅÀ¥Ç¡¼¥¿¤ò¸úΨ¤è¤¯ÉÁ²è¤¹¤ë¤¿¤á¤Ë
¥ª¥ó¥á¥â¥ê¤Ë¥Ç¡¼¥¿¤ò¥¥ã¥Ã¥·¥å¤¹¤ë»ÅÁȤߤǤ¹¡£
ĺÅÀ¥Ç¡¼¥¿¤ò³ÊǼ¤¹¤ëĺÅÀ¥Ð¥Ã¥Õ¥¡¤È
¤É¤ÎĺÅÀ¤ò»È¤Ã¤Æ»°³Ñ·Á¤òÉÁ²è¤¹¤ë¤Î¤«¤ò·è¤á¤ëĺÅÀ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò³ÊǼ¤¹¤ë¥¤¥ó¥Ç¥Ã¥¯¥¹¥Ð¥Ã¥Õ¥¡¤ÎºîÀ®¤ò¤·¤Þ¤¹
// ĺÅÀ¥Ð¥Ã¥Õ¥¡ºîÀ®
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
// ¥¤¥ó¥Ç¥Ã¥¯¥¹¥Ð¥Ã¥Õ¥¡ºîÀ®
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
¤ÄºÅÀ¥·¥§¡¼¥À¡¢¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤ÎºîÀ®¤ª¤è¤Ó¥³¥ó¥Ñ¥¤¥ë¡õ¥ê¥ó¥¯
¥·¥§¡¼¥À¤È¤ÏGPU¡Ê¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¡Ë¤Ç¤ÎÌ¿Îá½èÍý¤Ç¤¹¡£
½èÍý¤¬½Å¤¤¡¢ÉÁ²è½èÍý¤Ë´Ø¤·¤Æ¤ÏGPU¤ËľÀÜÌ¿Î᤹¤ë¤³¤È¤Ç¹â®²½¤¬·×¤ì¤Þ¤¹¡£
¤Þ¤¿¡¢OpenGLES2°Ê¹ß¤«¤é¥·¥§¡¼¥À¤Ç¤ÎÌ¿Î᤬ɬ¿Ü¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
¥·¥§¡¼¥À¤ÇľÀÜÉÁ²è½èÍý¤ò»ØÄꤹ¤ë¤³¤È¤Ç¤è¤êĺÅÀ¡¦¥Ô¥¯¥»¥ëñ°Ì¤Ç¤Î
½ÀÆð¤Ç¹â®¤ÊÉÁ²è½èÍý¤ò¹Ô¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
¥·¥§¡¼¥À¤Ï£²¼ïÎढ¤ê¡¢
ĺÅÀ¥·¥§¡¼¥À¤ÏĺÅÀñ°Ì¤Î½èÍý¡¢¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤Ï¥Ô¥¯¥»¥ëñ°Ì¤Î½èÍý¤ò¹Ô¤¤¤Þ¤¹¡£
ÉÁ²è»þ¤Ë¤ÏĺÅÀñ°Ì¤Ë½èÍý¤ò¤µ¤ì¤¿¸å¡¢
ĺÅÀƱ»Î¤Î¥Ô¥¯¥»¥ë´Ö¤òÊä´Ö¤¹¤ë¥é¥¹¥¿¥é¥¤¥º²½¤È¸Æ¤Ð¤ì¤ë½èÍý¤¬¤µ¤ì¡¢
¥Ô¥¯¥»¥ëñ°Ì¤Î½èÍý¤Ë°Ü¹Ô¤·¤Þ¤¹¡£
¤½¤Î¤¿¤áξÊý¤È¤â¼ÂÁõ¤Ïɬ¿Ü¤Ç¤¹¡£
Vertex.glsl¤¬ÄºÅÀ¥·¥§¡¼¥À¤Ç¤¹¡£
// input Vertex data
attribute vec3 aPosition;
attribute vec2 aTexCoord;
// Uniform data
uniform mat4 uProjectionMatrix;
uniform mat4 uModelViewMatrix;
// Output Vertex data
varying vec2 vTexCoord;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition,1.0);
vTexCoord = aTexCoord;
}
attribute°À¤ò»ý¤ÄÊÑ¿ô¤ÏĺÅÀñ°Ì¤ÇÁ÷¤é¤ì¤Æ¤¯¤ë¥Ç¡¼¥¿¤Ç¤¹¡£
uniform°À¤ò»ý¤ÄÊÑ¿ô¤Ï³°Éô¡ÊCPU¦¤Î¥×¥í¥°¥é¥à¡Ë¤«¤éÀßÄꤵ¤ì¤ë¤É¤ÎĺÅÀ¤Ç¤â¶¦Ä̤Υǡ¼¥¿¤Ç¤¹¡£
varying°À¤ò»ý¤ÄÊÑ¿ô¤Ï¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤ËÅϤ¹¥Ç¡¼¥¿¤Ç¤¹¡£
ĺÅÀ°ÌÃ֤ϥե饰¥á¥ó¥È¥·¥§¡¼¥À¤ËÅϤ¹É¬Íפ¬¤Ê¤¤¤¿¤á
gl_Position¤È¤¤¤¦Í½Ìó¸ì¤Ç½ÐÎϤ·¤Þ¤¹¡£
Fragment.glsl¤¬¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤Ç¤¹¡£
varying highp vec2 vTexCoord;
uniform sampler2D ColorTextureSampler;
void main(void) {
gl_FragColor = texture2D(ColorTextureSampler, vTexCoord);
}
varying°À¤ò»ý¤ÄÊÑ¿ô¤Ï¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤ËÁ÷¤é¤ì¤Æ¤¯¤ë¥Ç¡¼¥¿¤Ç¤¹¡£
¤Ê¤ª¡¢¥Õ¥é¥°¥á¥ó¥È¥·¥§¡¼¥À¤Ç¤Ïvec2,vec3¤Ê¤É¤Î¥Ù¥¯¥È¥ë¤ämat4¤Ê¤É¤Î¹ÔÎó¤Ê¤É
¿ôÃͤ¬Íí¤àÊÑ¿ô¤Ë¤ÏÀºÅÙ¼¨¤¹Â°À¤ò¤Ä¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
highp°À¤Ï¹âÀºÅ٤Ǥ¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£
ÄãÀºÅÙ¤Êlowp°À¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡£
uniform°À¤ò»ý¤ÄÊÑ¿ô¤Ï³°Éô¡ÊCPU¦¤Î¥×¥í¥°¥é¥à¡Ë¤«¤éÀßÄꤵ¤ì¤ë¤É¤Î¥Ô¥¯¥»¥ë¤Ç¤â¶¦Ä̤Υǡ¼¥¿¤Ç¤¹¡£
¥µ¥ó¥×¥é¡Êsampler2D¡Ë¤Ë¤Ï¥é¥¹¥¿¥é¥¤¥º²½¤µ¤ì¤¿¥Æ¥¯¥¹¥Á¥ã¤Î¥Æ¥¯¥»¥ë¥Ç¡¼¥¿¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
texture2D´Ø¿ô¤Ë¤è¤Ã¤Æ¥Æ¥¯¥¹¥Á¥ãºÂɸ¤ËÂбþ¤¹¤ë¥Æ¥¯¥»¥ë¤Î¿§¾ðÊó¤ò¼èÆÀ¤Ç¤¤Þ¤¹¡£
ºîÀ®¤·¤¿¥·¥§¡¼¥À¤Î¥³¥ó¥Ñ¥¤¥ë¡õ¥ê¥ó¥¯¤Ï
²¼µ¤Ç¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£
// ¥×¥í¥°¥é¥à¥Ö¥ë¥·¥§¡¼¥À¡¼¤Î¥³¥ó¥Ñ¥¤¥ë
- (void)compileShaders {
shader = [[Shader alloc] init];
[shader compileShaders:@"Vertex.glsl" fragmentShader:@"Fragment.glsl"];
¥³¥ó¥Ñ¥¤¥ë¡õ¥ê¥ó¥¯¤Î¼ÂÁõ¤Ï
Shader.h,Shader.m¤Ë¤¢¤ê¤Þ¤¹¤¬
·è¤Þ¤ê¤¤Ã¤¿½èÍý¤Ê¤Î¤ÇÀâÌÀ¤Ï³ä°¦¤·¤Þ¤¹¡£
¥·¥§¡¼¥À¡¼¤Î¥³¥ó¥Ñ¥¤¥ë¡õ¥ê¥ó¥¯¤¬À®¸ù¤·¤¿¤é
¥·¥§¡¼¥À¡¼ÊÑ¿ô¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Î¥Ï¥ó¥É¥ë¤ò¼èÆÀ¤·¤Æ¤ª¤¤Þ¤¹
¤³¤ì¤é¤Î¥Ï¥ó¥É¥ë¤ÏÉÁ²è»þ¤Ë¥·¥§¡¼¥À¤Ë¥Ç¡¼¥¿¤òÅϤ¹¤¿¤á¤Ë»È¤¤¤Þ¤¹
// ¥·¥§¡¼¥ÀÊÑ¿ô¤Î¥Ï¥ó¥É¥ë¼èÆÀ
_positionSlot = glGetAttribLocation(shader.programHandle, "Position");
_texCoordSlot = glGetAttribLocation(shader.programHandle, "TexCoordIn");
_modelViewUniform = glGetUniformLocation(shader.programHandle, "Modelview");
_projectionUniform = glGetUniformLocation(shader.programHandle, "Projection");
_textureUniform = glGetUniformLocation(shader.programHandle, "ColorTexture");
¥¥·¥§¡¼¥ÀÊÑ¿ô¤ÎÀßÄê
GLKMatrix4 modelMatrix = GLKMatrix4Make(1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1);
// ¥Ó¥å¡¼ÊÑ´¹
GLKMatrix4 viewMatrix = [_transformations getViewMatrix];
GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(viewMatrix,modelMatrix);
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelViewMatrix.m);
// ¼Í±ÆÊÑ´¹¹ÔÎó
const GLfloat aspectRatio = (GLfloat)(self.bounds.size.width) / (GLfloat)(self.bounds.size.height);
const GLfloat fieldView = GLKMathDegreesToRadians(60.0f);
const GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(fieldView, aspectRatio, 0.1f, 100.0f);
glUniformMatrix4fv(_projectionUniform, 1, 0, projectionMatrix.m);
// ¥Ó¥å¡¼¥Ý¡¼¥ÈÊÑ´¹¤ÎÀßÄê
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// ÉÁ²è»þ¤Ë»ÈÍѤ¹¤ë¥·¥§¡¼¥À¤ÎÀßÄê
glUseProgram(shader.programHandle);
// VBO¤ÎÀßÄê
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
// ĺÅÀ¥Ç¡¼¥¿¹½Â¤¤ÎÀßÄê
glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_texCoordSlot);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
// ¥Æ¥¯¥¹¥Á¥ã¤ÎÀßÄê
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _texture.handle);
glUniform1i(_textureUniform, 0);
¦ÄºÅÀ¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È¤ÎÉÁ²è
// ÉÁ²è
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
Ê䡧
ÉÁ²è¤ÈľÀܤϴط¸¤¢¤ê¤Þ¤»¤ó¤¬
¥¸¥§¥¹¥Á¥ã¡¼¤Ç²èÌ̤Υ¤¥ó¥¿¥é¥¯¥Æ¥£¥ÖÁàºî¤¬¤Ç¤¤ë¤è¤¦¤Ë¤·¤Æ¤¢¤ê¤Þ¤¹
¥Ñ¥ó¡Ê£±Ëܻإɥé¥Ã¥°¡Ë¡§²èÌÌÊ¿¹Ô°ÜÆ°
¥Ñ¥ó¡Ê£²Ëܻإɥé¥Ã¥°¡Ë¡§²èÌ̤ÎXY¼´¤ò´ð¼´¤È¤·¤¿²óž
¥Ô¥ó¥Á¡¦¥¤¥ó¥¢¥¦¥È¡§³ÈÂç½Ì¾®
¥í¡¼¥Æ¡¼¥·¥ç¥ó¡Ê£²Ëܻزóž¡Ë¡§¸«¤Æ¤¤¤ë±ü¹Ô¤Êý¸þ(Z¼´)¤ËÂФ·¤Æ¤Î²óž
¥¸¥§¥¹¥Á¥ã¡¼ÁàºîÉôʬ¤Ï¤½¤Î¤Þ¤Þ¥Ñ¥¯¤Ã¤Æ¤¤¿¤â¤Î¤Ê¤Î¤Ç¾ÜºÙ¤Ï¥ê¥ó¥¯Àè¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤
http://www.raywenderlich.com/50398/opengl-es-transformations-gestures
DrawQuadView.m¤Î
¥¸¥§¥¹¥Á¥ã¡¼¼ÂÁõÉôʬ¤òÈ´¿è¤·¤Þ¤¹
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Begin transformations
[_transformations start];
}
// ¥Ñ¥ó
- (IBAction)pan:(UIPanGestureRecognizer *)sender
{
// Pan (1 Finger)
if((sender.numberOfTouches == 1) &&
((_transformations.state == S_NEW) || (_transformations.state == S_TRANSLATION)))
{
// Ê¿¹Ô°ÜÆ°
CGPoint translation = [sender translationInView:sender.view];
float x = translation.x/sender.view.frame.size.width;
float y = translation.y/sender.view.frame.size.height;
[_transformations translate:GLKVector2Make(x, y) withMultiplier:5.0f];
}
// Pan (2 Fingers)
else if((sender.numberOfTouches == 2) &&
((_transformations.state == S_NEW) || (_transformations.state == S_ROTATION)))
{
// ²óž
const float m = GLKMathDegreesToRadians(0.5f);
CGPoint rotation = [sender translationInView:sender.view];
[_transformations rotate:GLKVector3Make(rotation.x, rotation.y, 0.0f) withMultiplier:m];
}
}
// ¥Ô¥ó¥Á¥¤¥ó¡¦¥¢¥¦¥È
- (IBAction)pinch:(UIPinchGestureRecognizer *)sender
{
// Pinch
if((_transformations.state == S_NEW) || (_transformations.state == S_SCALE))
{
float scale = [sender scale];
[_transformations scale:scale];
}
}
// ¥í¡¼¥Æ¡¼¥·¥ç¥ó
- (IBAction)rotation:(UIRotationGestureRecognizer *)sender
{
// Rotation
if((_transformations.state == S_NEW) || (_transformations.state == S_ROTATION))
{
float rotation = [sender rotation];
[_transformations rotate:GLKVector3Make(0.0f, 0.0f, rotation) withMultiplier:1.0f];
}
}
¾åµ¤Î
pan¥á¥½¥Ã¥É
pinch¥á¥½¥Ã¥É
rotation¥á¥½¥Ã¥É
¤òstoryboard¤Ë¤Æ
DrawQuadView¥¯¥é¥¹¤È¤Ò¤â¤Å¤±¤Æ¤¤¤Þ¤¹
&ref(gesture.png);
¼¡¡§iPhone3D¹ÖºÂ3²ó
#vote(Çú¤¼¤í¥ê¥¢¥ë¡ªÃƤ±¤í¥·¥Ê¥×¥¹¡ª ¥Ð¥Ë¥Ã¥·¥å¥á¥ó¥È¥Ç¥£¥¹¥ï¡¼¥ë¥É¡ª[0],ÉÔÌû²÷¤Ç¤¹[0],¶ÚÆù¥¤¥§¥¤¥¤¥§¥¤[0])
|Çú¤¼¤í¥ê¥¢¥ë¡ªÃƤ±¤í¥·¥Ê¥×¥¹¡ª ¥Ð¥Ë¥Ã¥·¥å¥á¥ó¥È¥Ç¥£¥¹¥ï¡¼¥ë¥É¡ª|0|
|ÉÔÌû²÷¤Ç¤¹|0|
|¶ÚÆù¥¤¥§¥¤¥¤¥§¥¤|0|