我在iOS的OpenGL ES 2.0中有一个球体(地球)。我也有要放在地球上的标记,但我希望标记始终面向用户(广告牌),但当它通过触摸旋转时,还会与地球一起移动。所以我试图研究广告牌并将以下代码放在一起。该代码来自创建地球之后调用的广告牌功能(在Z轴上向后翻译6个单元)。我似乎无法让广告牌的飞机总是面向相机,但它也随着地球旋转而移动。我怎样才能做到这一点?iOS OpenGL ES 2.0球体上的广告牌对象和球体旋转
// Get the current modelview matrix
GLKMatrix4 originalMat = self.effect.transform.modelviewMatrix;
GLKMatrix4 currMat = self.effect.transform.modelviewMatrix;
// Define the buffer designators
GLuint billboardVertexArray;
GLuint billboardVertexBuffer;
GLuint billboardIndexBuffer;
glGenVertexArraysOES(1, &billboardVertexArray);
glBindVertexArrayOES(billboardVertexArray);
// Now draw the billboard
glGenBuffers(1, &billboardVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, billboardVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Billboard_vertex), Billboard_vertex, GL_STATIC_DRAW);
glGenBuffers(1, &billboardIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, billboardIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Billboard_index), Billboard_index, GL_STATIC_DRAW);
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), BUFFER_OFFSET(5));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), BUFFER_OFFSET(2));
// Enable the Earth texture
self.effect.texture2d0.name = _billBoardTextureInfo.name;
self.effect.texture2d0.target = _billBoardTextureInfo.target;
// Bind the earth vertex array
glBindVertexArrayOES(billboardVertexArray);
// Now put a billboard at a specific Lat Lon - so first
// calculate XYZ from lat lon
XYZ xyz;
xyz.x = 0; xyz.y = 0; xyz.z = 0;
[self LLAtoXYZwithLat:0 andLon:0 andXYZ:&xyz];
//NSLog(@"XYZ after: %f %f %f",xyz.x,xyz.y,xyz.z);
// Move the billboard back so we can see it
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f);
// In update, we convert the quaternion into a rotation matrix, and apply it to the model view matrix as usual.
GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotation);
// First create the variation translations to anchor the billboard
GLKMatrix4 translationXYZ = GLKMatrix4MakeTranslation(xyz.x, xyz.y, xyz.z);
GLKMatrix4 translationForLatLonWithTranslation = GLKMatrix4Multiply(modelViewMatrix,translationXYZ);
// Scale this object as well
GLKMatrix4 scaledWithTranslationAndRotation = GLKMatrix4Scale(translationForLatLonWithTranslation, scale, scale, scale);
// Remove the Translation portion of the matrix
// | xx xy xz xw |
// | yx yy yz yw |
// | zx zy zz zw |
// | wx wy wz ww |
//
// | R T |
// | (0,0,0) 1 |
//
// d = sqrt(xx² + yx² + zx²)
//
// | d 0 0 T.x |
// | 0 d 0 T.y |
// | 0 0 d T.z |
// | 0 0 0 1 |
//
// union _GLKMatrix4
// {
// struct
// {
// float m00, m01, m02, m03;
// float m10, m11, m12, m13;
// float m20, m21, m22, m23;
// float m30, m31, m32, m33;
// };
// float m[16];
// }
// typedef union _GLKMatrix4 GLKMatrix4;
// Construct the rows in the new matrix
float d = sqrt(pow(currMat.m00,2) + pow(currMat.m10,2) + pow(currMat.m20,2));
GLKVector4 columnToInsert0 = GLKVector4Make(d, 0, 0, currMat.m03+xyz.x);
GLKVector4 columnToInsert1 = GLKVector4Make(0, d, 0, currMat.m13+xyz.y);
//GLKVector4 columnToInsert2 = GLKVector4Make(0, 0, d, currMat.m23-6+xyz.z);
GLKVector4 columnToInsert3 = GLKVector4Make(0, 0, 0, 1);
// Build the new Matrix
GLKMatrix4 noTranslationInfo = GLKMatrix4SetRow(currMat, 0, columnToInsert0);
noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 1, columnToInsert1);
//noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 2, columnToInsert2);
noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 3, columnToInsert3);
[self printMatrix:noTranslationInfo];
// Assign the new matrix to draw with - no translation
self.effect.transform.modelviewMatrix = noTranslationInfo;
// Render the object with GLKit
[self.effect prepareToDraw];
// Draw elements from the index array and uv/vertex/normal info
glDrawElements(GL_TRIANGLES,Billboard_polygoncount*3,GL_UNSIGNED_SHORT,0);
// Restore the original matrix
self.effect.transform.modelviewMatrix = originalMat;
您的代码非常友好,对我非常有帮助。但我只有一个问题: 如何计算四元数(在代码中是'_quat' ivar)? – 2013-07-25 11:55:39
嗨,我做到了,就像在本教程中一样:http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl – PhilBot 2013-07-25 18:57:11