【问题标题】:Converting iPad Coordinates to OpenGL ES 2.0 Scene Coordinates ? iOS将 iPad 坐标转换为 OpenGL ES 2.0 场景坐标? iOS
【发布时间】:2013-10-18 13:37:18
【问题描述】:

我有一个仅包含 2D 对象的 OpenGL ES 2.0 场景。我正在应用以下两个矩阵:

width = 600;

CC3GLMatrix * projection = [CC3GLMatrix matrix];
height = width * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-width/2 andRight:width/2 andBottom:-height/2 andTop:height/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);

CC3GLMatrix * modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(xTranslation ,yTranslation, -7)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);

在 touches started 方法中,我尝试将触摸点坐标映射到 OpenGL ES 2.0 场景坐标:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches Began");
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self];

float differentialWidth = (768-width)/2; //Accounts for if OpenGL view is less than iPad width or height.
float differentialHeight = (1024-height)/2;
float openGlXPoint = ((touchPoint.x - differentialWidth) - (width/2));
float openGlYPoint = ((touchPoint.y - differentialHeight) - (width/2));
NSLog(@"X in Scene Touched is %f", openGlXPoint);

CGPoint finalPoint = CGPointMake(openGlXPoint, openGlYPoint);

for (SquareObject * square in squareArray) {
    if (CGRectContainsPoint(stand.bounds, finalPoint)) {
        NSString * messageSquare = (@"Object name is %@", square.Name);
        UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Touched"
                                                          message:messageSquare
                                                         delegate:nil
                                                cancelButtonTitle:@"OK"
                                                otherButtonTitles:nil];
        [message show];
    }
}
}

此代码的工作原理是它返回 OpenGL 坐标 - 例如,单击屏幕中间成功返回 0,0。然而问题是(我认为)是我需要以某种方式考虑场景的缩放比例,因为以 150,0 为原点绘制的对象与我在 iPad 上单击的位置不匹配(返回 112,0使用上面的代码)。谁能建议我如何纠正这个问题?

谢谢!

【问题讨论】:

    标签: ios objective-c opengl-es matrix coordinate-systems


    【解决方案1】:

    这对于 2D 应用程序来说可能是多余的,但您通常会为 3D 应用程序执行此操作的方式是创建两个向量,一个“远点”和一个“近点”,使用 GLKUnproject 或其他方式取消投影它们您想要的其他数学库,然后从远点减去近点以获得对象坐标中的射线,您可以使用该射线仅使用几何来测试相交,而不必担心投影或模型视图矩阵。这是一个例子

    bool testResult;
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    
    GLKVector3 nearPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, tapLoc.y, 0.0), modelViewMatrix, projectionMatrix, &viewport[0] , &testResult);
    
    GLKVector3 farPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, tapLoc.y, 1.0), modelViewMatrix, projectionMatrix, &viewport[0] , &testResult);
    
    farPt = GLKVector3Subtract(farPt, nearPt);
    //now you can test if the farPt ray intersects the geometry of interest, perhaps
    //using a method like the one described here http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
    

    在您的情况下,projectionMatrix 可能是身份,因为您在二维中工作,而 modelViewMatrix 是您应用于对象的比例、平移、旋转、剪切等。

    另外,如果您不知道,您所询问的内容通常被称为“挑选”,如果您在 Google 中输入“OpenGL 挑选”,您可能会发现比以前获得的信息更好的主题信息只需“转换坐标”。

    【讨论】:

    • 谢谢 - 非常有帮助,并说服我将项目重构为 GLKViewController。
    • 两个问题 - 第一个 GLKVector 应该称为 farPt 对吗?其次,&testResult 是什么?
    • 是的,这两个都是错别字。第二个实际上是我代码中的远点。 testresult 只是一个布尔值,如果你想知道 unproject 是否成功,你可以通过地址传递它(如果你不关心,你可以传递 NULL)。现在两个都修好了。希望这会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    相关资源
    最近更新 更多