OpenGL ES 2.0 捏合和缩放 [英] OpenGL ES 2.0 Pinch and Zoom
问题描述
在 iOS 上的 OpenGL ES 1.1 中,我曾经通过使用以下内容设置视野来实现捏合和缩放:
In OpenGL ES 1.1 on iOS I used to implement pinch and zoom by setting the Field Of View using the following:
// Handles Touches Events
- (IBAction)handlePinchGesture:(UIGestureRecognizer *)sender
{
static float startFOV=0.0;
CGFloat factor = [(UIPinchGestureRecognizer *)sender scale];
UIGestureRecognizerState state;
state=sender.state;
if(state==UIGestureRecognizerStateBegan)
{
startFOV=[self getFieldOfView];
}
else if(state==UIGestureRecognizerStateChanged)
{
float minFOV=5.0;
float maxFOV=12.0;
float currentFOV;
currentFOV=startFOV*factor;
if((currentFOV>=minFOV) && (currentFOV<=maxFOV))
[self setFieldOfView:currentFOV];
}
}
使用捏合手势我会做这样的事情:
Using the pinch gesture I would do something like this:
// Set the fulstrum and our field of view for the window
-(void)setClipping
{
// Near and far are the front and back walls
// FOV is in degrees
float aspectRatio;
const float zNear = .1;
const float zFar = 2000;
GLfloat size;
float scale;
// Get the main screen and define the aspect ratio
CGRect frame = [[UIScreen mainScreen] bounds];
aspectRatio=(float)frame.size.width/(float)frame.size.height;
scale=[[UIScreen mainScreen]scale];
// Use the 2D projection matrix to project our 3D into 2D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (m_FieldOfView > 75.0) {
m_FieldOfView = 75.0;
}
size = zNear * tanf(GLKMathDegreesToRadians (m_FieldOfView) / 2.0);
// Define the pyramid of Giza (4 sided pyramid with top lopped off on its side)
// ... this is how were viewing things
glFrustumf(-size, size, -size/aspectRatio, size/aspectRatio, zNear, zFar);
glViewport(0, 0, frame.size.width*scale, frame.size.height*scale);
// To be safe go back to tranformational matrix
glMatrixMode(GL_MODELVIEW);
}
我制作了一个简单的 OpenGL ES 2.0 应用程序,我的更新方法(部分)如下所示:
I made a simple OpenGL ES 2.0 application and my update method looks ( partially ) like this:
#pragma mark - GLKView and GLKViewController delegate methods
- (void)update
{
// Set up the frustrum and projection matrix
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
我一直在网上搜索如何使用 OpenGL ES 2.0 做到这一点……但无济于事.我如何在 2.0 中执行此操作?
I've been scouring the web for how to do this with OpenGL ES 2.0... but to no avail. How do I do this in 2.0?
推荐答案
将 GLKMatrix4MakePerspective 的第一项乘以一个因子(属性或类变量)并在手势识别器中更改该因子 - 不是与您在 1.1 方法中所做的完全不同.
Multiply the first term of GLKMatrix4MakePerspective by a factor (a property or class variable) and change that factor in the gesture recogniser - not too different to what you do in your 1.1 method.
这是我从 GestureRecogniser 调用的方法.以 _ 开头的变量是类变量.ZOOMTOUCHSENSITIVITY 是一个预处理器定义.
Here is the method I call from my GestureRecogniser. Variables starting with _ are class variables. ZOOMTOUCHSENSITIVITY is a preprocessor define.
-(void)Scale:(UITapGestureRecognizer*)sender
{
CGFloat scale = _lastScale + (1.0 - [(UIPinchGestureRecognizer*)sender scale])*ZOOMTOUCHSENSITIVITY;
float newScale = MAX(0.1, MIN(scale, 3));
_projectionMatrix = GLKMatrix4MakePerspective(newScale*GLKMathDegreesToRadians(45.0f), (float)_screenWidth/(float)_screenHeight, 100.0f, 1000.0f);
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastScale = newScale;
return;
}
}
请注意,一旦手势停止,我将如何保存 scale
的最后一个值,以便每次都不会重置"缩放.
Note how I'm saving the last value of scale
once the gesture stops, so that the zoom isn't 'reset' everytime.
这篇关于OpenGL ES 2.0 捏合和缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!