iPhone 4 OpenGL ES 응용 프로그램에 문제가 있습니다. 몇 달 동안 켜고 끄는 데 많은 어려움을 겪었습니다. 이 사이트에 대한 조언과 제안을 엿볼 수 있습니다.iPhone4 OpenGL ES GLuProject가 잘못된 y 좌표를 반환합니다.
나는 단순히 블록을 그리고 사용자가 다양한 준비로 주변을 이동하고 응용 프로그램의 대량은 C로 작성된 수 있도록 3D 게임을 쓰고 + +. 이동하기 위해
http://webcvs.freedesktop.org/mesa/Mesa/src/glu/mesa/project.c?view=markup
는 3D 점 (따라서 블록)을 해석 할 수있는 사용자에 의해 선택 :
내 문제는 내가 여기에 대한 소스 코드를 발견 GLuUnproject를 사용하는 것을 시도하고 있다는 것입니다 그리고 그것을 double precision이 아닌 floating point로 바꾸어서 회전시킵니다.
이 소스를 인터넷의 다른 버전과 비교했는데 일관성이있는 것으로 나타났습니다.
나는 광선 벡터를 얻기 위해 다음 코드를 사용
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;
}
는 다시, 결과는 Y 좌표 GLuProjected 가져 점에서 광선 추적 방법과 일치 사용자가 더 높은 화면을 클릭하면 점점 더 잘못됩니다. 직접 touchesBegan 이벤트에 의해보고되는 클릭 위치가 예를 들어
는 (246,190) 상기 계산 위치 (246, 215)를 클릭 위치가 직접 touchesBegan 이벤트가보고 25.
의 바깥 편차이며 (246,398)이고, 계산 된 위치는 (246, 405)이고, 불일치는 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);
픽셀 및 가능한 스케일링에 대한 필요성 때문에 이러한 정보가 아이폰 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
@ 토미. 귀하의 질문에 감사드립니다. 위에서 추가 한 메서드가있는 GLView라는 사용자 지정 클래스가 있습니다 (함수 호출에서 호출 된 코드 중 일부는 쉽게 따라갈 수 있도록 인라인으로 표시됩니다). – Braunius