我有一個iPhone 4的OpenGL ES應用程序,我一直在努力,現在解決和關閉了幾個月,並且已經進入了死衚衕儘管有一些真正有用的一個莫名其妙的問題和誘人的提示和建議在這個網站上。的iPhone4的OpenGL ES GLuProject返回錯誤的y座標
我寫一個3D遊戲,其簡單地畫塊,並允許用戶移動它們成各種安排和應用程序的大部分是用C++編寫。
我的問題是,我想使用GLuUnproject,我發現這裏的源代碼:由用戶選擇
http://webcvs.freedesktop.org/mesa/Mesa/src/glu/mesa/project.c?view=markup
解釋三維點(因此塊),以推動並旋轉它,我贊成浮點而不是雙精度。
請注意,我已將此源與網絡上的其他版本進行了比較,它看起來是一致的。
我用下面的代碼來獲取光線矢量:
Ray RenderingEngine::GetRayVector(vec2 winPos) const
{
// Get the last matrices used
glGetFloatv(GL_MODELVIEW_MATRIX, __modelview);
glGetFloatv(GL_PROJECTION_MATRIX, __projection);
glGetIntegerv(GL_VIEWPORT, __viewport);
// Flip the y coordinate
winPos.y = (float)__viewport[3] - winPos.y;
// Create vectors to be set
vec3 nearPoint;
vec3 farPoint;
Ray rayVector;
//Retrieving position projected on near plan
gluUnProject(winPos.x, winPos.y , 0,
__modelview, __projection, __viewport,
&nearPoint.x, &nearPoint.y, &nearPoint.z);
//Retrieving position projected on far plan
gluUnProject(winPos.x, winPos.y, 1,
__modelview, __projection, __viewport,
&farPoint.x, &farPoint.y, &farPoint.z);
rayVector.nearPoint = nearPoint;
rayVector.farPoint = farPoint;
//Return the ray vector
return rayVector;
}
從近平面描繪出返回的射線到遠平面向量代碼很簡單,我發現附近的墊塊屏幕被正確識別,但是隨着屏幕向上移動,所報告的y值和所選點的預期y值似乎有越來越大的差異。
我一直在使用GLuProject手動檢查其屏幕座標生成我的世界座標如下也試過:
vec3 RenderingEngine::GetScreenCoordinates(vec3 objectPos) const
{
// Get the last matrices used
glGetFloatv(GL_MODELVIEW_MATRIX, __modelview);
glGetFloatv(GL_PROJECTION_MATRIX, __projection);
glGetIntegerv(GL_VIEWPORT, __viewport);
vec3 winPos;
gluProject(objectPos.x, objectPos.y, objectPos.z ,
__modelview, __projection, __viewport,
&winPos.x, &winPos.y, &winPos.z);
// Swap the y value
winPos.y = (float)__viewport[3] - winPos.y;
return winPos;
}
再次,結果與在光線追蹤方法的GLuProjected y座標得到一致越來越錯誤,因爲用戶點擊更高的屏幕。
例如,當由所述的touchesBegan事件直接報告點擊位置是(246190)所計算出的位置爲(246,215)的25
,AY差異當由事件的touchesBegan直接報告點擊位置是(246,398)計算出的位置是(246,405),ay的差異是7.
x座標似乎是現貨。
我注意到,當視口高度設置爲480(全屏幕高度)時,layer.bounds.size.height報告爲436。報告的圖層邊界寬度爲320,這也是視口的寬度。
無論我使用的視口大小,還是顯示窗口頂部的狀態屏幕,436的值似乎都是固定的。
嘗試設置bounds.size。身高480以下的呼叫前:
[my_context
renderbufferStorage:GL_RENDERBUFFER
fromDrawable: eaglLayer];
但這似乎被忽略和高度後報告爲呼叫436:
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
GL_RENDERBUFFER_HEIGHT_OES, &height);
我已經看到了分差的一些討論和像素以及可能的縮放需求,但一直在努力使用這些信息,因爲這些暗示了差異是由於iPhone 4的視網膜顯示分辨率以及模擬器和實際設備需要不同的縮放比例。但是,據我所知,模擬器和設備的表現一致。
2011年8月30日由於沒有收到任何反饋意見,是否有更多的信息可以讓問題變得更加易於理解?
31 - 8 - 2011 OpenGL的設置和顯示代碼如下:
- (id) initWithCoder:(NSCoder*)coder
{
if ((self = [super initWithCoder:coder]))
{
// Create OpenGL friendly layer to draw in
CAEAGLLayer* eaglLayer = (CAEAGLLayer*) self.layer;
eaglLayer.opaque = YES;
// eaglLayer.bounds.size.width and eaglLayer.bounds.size.height are
// always 320 and 436 at this point
EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
m_context = [[EAGLContext alloc] initWithAPI:api];
// check have a context
if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
[self release];
return nil;
}
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
[m_context
renderbufferStorage:GL_RENDERBUFFER
fromDrawable: eaglLayer];
UIScreen *scr = [UIScreen mainScreen];
CGRect rect = scr.applicationFrame;
int width = CGRectGetWidth(rect); // Always 320
int height = CGRectGetHeight(rect); // Always 480 (status bar not displayed)
// Initialise the main code
m_applicationEngine->Initialise(width, height);
// This is the key c++ code invoked in Initialise call shown here indented
// Setup viewport
LowerLeft = ivec2(0,0);
ViewportSize = ivec2(width,height);
// Code to create vertex and index buffers not shown here
// …
// Extract width and height from the color buffer.
int width, height;
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
GL_RENDERBUFFER_WIDTH_OES, &width);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
GL_RENDERBUFFER_HEIGHT_OES, &height);
// Create a depth buffer that has the same size as the color buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES,
width, height);
// Create the framebuffer object.
GLuint framebuffer;
glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
// Set up various GL states.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
// ...Back in initiWithCoder
// Do those things which need to happen when the main code is reset
m_applicationEngine->Reset();
// This is the key c++ code invoked in Reset call shown here indented
// Set initial camera position where
// eye=(0.7,8,-8), m_target=(0,4,0), CAMERA_UP=(0,-1,0)
m_main_camera = mat4::LookAt(eye, m_target, CAMERA_UP);
// ...Back in initiWithCoder
[self drawView: nil];
m_timestamp = CACurrentMediaTime();
// Create timer object that allows application to synchronise its
// drawing to the refresh rate of the display.
CADisplayLink* displayLink;
displayLink = [CADisplayLink displayLinkWithTarget:self
selector:@selector(drawView:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
}
return self;
}
- (void) drawView: (CADisplayLink*) displayLink
{
if (displayLink != nil) {
// Invoke main rendering code
m_applicationEngine->Render();
// This is the key c++ code invoked in Render call shown here indented
// Do the background
glClearColor(1.0f, 1.0f, 1.0f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// A set of objects are provided to this method
// for each one (called visual below) do the following:
// Set the viewport transform.
glViewport(LowerLeft.x, LowerLeft.y, ViewportSize.x, ViewportSize.y);
// Set the model view and projection transforms
// Frustum(T left, T right, T bottom, T top, T near, T far)
float h = 4.0f * size.y/size.x;
mat4 modelview = visual->Rotation * visual->Translation * m_main_camera;
mat4 projection = mat4::Frustum(-1.5, 1.5, h/2, -h/2, 4, 14);
// Load the model view matrix and initialise
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(modelview.Pointer());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glLoadMatrixf(projection.Pointer());
// Draw the surface - code not shown
// …
// ...Back in drawView
[m_context presentRenderbuffer:GL_RENDERBUFFER];
}
}
如何在屏幕上顯示CAEAGLLayer?如果你圍繞它構建了一個UIView,那麼它有什麼框架? 436與426相似 - 您確定您的視圖或代碼沒有假設或嘗試強制使用4:3的寬高比嗎? – Tommy
@Tommy。謝謝你的問題。我有一個名爲GLView的自定義類,它具有上面添加的方法(從函數調用調用的一些代碼顯示爲內聯以便於跟蹤)。 – Braunius