OpenGL ES 2.0 (خصيصًا لعرض iPhone) يتم إيقاف تشغيله قليلاً. أفضل تخمين هي مشكلة مصفوفة الإسقاط

StackOverflow https://stackoverflow.com/questions/3886329

سؤال

لذلك اشتريت برمجة iPhone 3D من O'Reilly ووجدت ما أعتقد أنه خطأ في رمز هناك. ومع ذلك ، لا يمكنني معرفة ماهية المشكلة ، وما لم يكن لا يمكنني المضي قدمًا مع الكود الخاص بي.

سألصق ما أعتبره رمزًا مناسبًا في هذا المنشور ، لكن لحسن الحظ ، تتوفر كل الرمز عبر الإنترنت على:http://examples.oreilly.com/9780596804831/hellocone/

المشكلة التي أواجهها هي مع عارض OpenGL ES 2.0 ، لا تظهر في عارض ES 1.1.

إذن ما لاحظته هو أن المخروط لا يقدمه بالضبط في الموضع الصحيح. لاختبار هذا ، قمت بتغيير modelViewMatrix لتقديمه بالضبط على الطائرة frustumnear. لذلك يجب أن يظهر المخروط قطعًا تمامًا في قسمين. عندما أقوم بذلك باستخدام ES 1.1 ، فإن هذا هو الحال ، عندما أفعل الشيء نفسه في OpenGL ES 2.0 ومع ذلك ، فهو ليس كذلك. المخروط هو في معظمه هناك ، ولكن حلق قليلا. وهذا يعني أنه لا يهبط بالضبط على وجه Fustrum القريب.

فيما يلي رمز التهيئة حيث يتم إنشاء مصفوفة الإسقاط وإعدادها:

void RenderingEngine2::Initialize(int width, int height)
{
const float coneRadius = 0.5f;
const float coneHeight = 1.0f;
const int coneSlices = 40;

{
    // Allocate space for the cone vertices.
    m_cone.resize((coneSlices + 1) * 2);

    // Initialize the vertices of the triangle strip.
    vector<Vertex>::iterator vertex = m_cone.begin();
    const float dtheta = TwoPi / coneSlices;
    for (float theta = 0; vertex != m_cone.end(); theta += dtheta) {

        // Grayscale gradient
        float brightness = abs(sin(theta));
        vec4 color(brightness, brightness, brightness, 1);

        // Apex vertex
        vertex->Position = vec3(0, 1, 0);
        vertex->Color = color;
        vertex++;

        // Rim vertex
        vertex->Position.x = coneRadius * cos(theta);
        vertex->Position.y = 1 - coneHeight;
        vertex->Position.z = coneRadius * sin(theta);
        vertex->Color = color;
        vertex++;
    }
}

{
    // Allocate space for the disk vertices.
    m_disk.resize(coneSlices + 2);

    // Initialize the center vertex of the triangle fan.
    vector<Vertex>::iterator vertex = m_disk.begin();
    vertex->Color = vec4(0.75, 0.75, 0.75, 1);
    vertex->Position.x = 0;
    vertex->Position.y = 1 - coneHeight;
    vertex->Position.z = 0;
    vertex++;

    // Initialize the rim vertices of the triangle fan.
    const float dtheta = TwoPi / coneSlices;
    for (float theta = 0; vertex != m_disk.end(); theta += dtheta) {
        vertex->Color = vec4(0.75, 0.75, 0.75, 1);
        vertex->Position.x = coneRadius * cos(theta);
        vertex->Position.y = 1 - coneHeight;
        vertex->Position.z = coneRadius * sin(theta);
        vertex++;
    }
}

// Create the depth buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,
                      GL_DEPTH_COMPONENT16,
                      width,
                      height);

// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                          GL_COLOR_ATTACHMENT0,
                          GL_RENDERBUFFER,
                          m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                          GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER,
                          m_depthRenderbuffer);

// Bind the color buffer for rendering.
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);

// Set up some GL state.
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);

// Build the GLSL program.
m_simpleProgram = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
glUseProgram(m_simpleProgram);

// Set the projection matrix.
GLint projectionUniform = glGetUniformLocation(m_simpleProgram, "Projection");
mat4 projectionMatrix = mat4::Frustum(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glUniformMatrix4fv(projectionUniform, 1, 0, projectionMatrix.Pointer());
}

وهنا هو رمز التجسيد. كما ترون ، قمت بتغيير modelviematrix لوضع المخروط في الركن الأيسر السفلي من وجه القريب القريب.

void RenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");

glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnableVertexAttribArray(positionSlot);
glEnableVertexAttribArray(colorSlot);

دوران MAT4 (m_animation.current.tomatrix ()) ؛ ترجمة MAT4 = mat4 :: ترجمة (-1.6 ، -2.4 ، -5) ؛

// Set the model-view matrix.
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = rotation * translation;
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());

// Draw the cone.
{
  GLsizei stride = sizeof(Vertex);
  const GLvoid* pCoords = &m_cone[0].Position.x;
  const GLvoid* pColors = &m_cone[0].Color.x;
  glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords);
  glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, m_cone.size());
}

// Draw the disk that caps off the base of the cone.
{
  GLsizei stride = sizeof(Vertex);
  const GLvoid* pCoords = &m_disk[0].Position.x;
  const GLvoid* pColors = &m_disk[0].Color.x;
  glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords);
  glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);
  glDrawArrays(GL_TRIANGLE_FAN, 0, m_disk.size());
}

glDisableVertexAttribArray(positionSlot);
glDisableVertexAttribArray(colorSlot);
}
هل كانت مفيدة؟

المحلول

يبدو أنني وجدت الإجابة على سؤالي.

يتم حساب مصفوفة الإسقاط في رمز O'Reilly بشكل غير صحيح.

في الكود لديهم:

T a = 2 * near / (right - left);
T b = 2 * near / (top - bottom);
T c = (right + left) / (right - left);
T d = (top + bottom) / (top - bottom);
T e = - (far + near) / (far - near);
T f = -2 * far * near / (far - near);
Matrix4 m;
m.x.x = a; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = b; m.y.z = 0; m.y.w = 0;
m.z.x = c; m.z.y = d; m.z.z = e; m.z.w = -1;
m.w.x = 0; m.w.y = 0; m.w.z = f; m.w.w = 1;
return m;

لكن هذه ليست مصفوفة الإسقاط. يجب أن يكون MWW 0 وليس 1.

Matrix4 m;
m.x.x = a; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = b; m.y.z = 0; m.y.w = 0;
m.z.x = c; m.z.y = d; m.z.z = e; m.z.w = -1;
m.w.x = 0; m.w.y = 0; m.w.z = f; m.w.w = 0;
return m;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top