Импорт текстурированной 3D-модели из файла .obj в iOS OpenGl E.S 2.0

В настоящее время я пытаюсь преобразовать 3D-модели в формате .obj с текстурой в код, совместимый с Objective c, и визуализировать их с помощью OpenGL E.S. 2.0.

Я использую [obj2opengl][1] от Хайко Беренса для преобразования 3D-модели в заголовочный файл.

3D-модель имеет UV-картографирование с этим изображением текстуры.

Все почти работает, но почему-то текстуры отрисовываются некорректно и мой куб отображается как это.

Я пробовал все виды вещей, но не могу понять, что я делаю неправильно, или я просто не понимаю.

Вот мой код того, как я визуализирую куб:

unsigned int boxNumVerts = 36;

float boxVerts [] = {
  // f 1/1/1 2/2/1 3/3/1 4/4/1 
  -0.5, -0.5, 0.5,
  -0.5, -0.5, -0.5,
  0.5, -0.5, -0.5,
  // f 1/1/1 2/2/1 3/3/1 4/4/1 
  -0.5, -0.5, 0.5,
  0.5, -0.5, 0.5,
  0.5, -0.5, -0.5,
  // f 5/5/2 6/6/2 7/7/2 8/8/2 
  -0.5, 0.5, 0.5,
  0.5, 0.5, 0.5,
  0.5, 0.5, -0.5,
  // f 5/5/2 6/6/2 7/7/2 8/8/2 
  -0.5, 0.5, 0.5,
  -0.5, 0.5, -0.5,
  0.5, 0.5, -0.5,
  // f 1/9/3 4/10/3 6/6/3 5/5/3 
  -0.5, -0.5, 0.5,
  0.5, -0.5, 0.5,
  0.5, 0.5, 0.5,
  // f 1/9/3 4/10/3 6/6/3 5/5/3 
  -0.5, -0.5, 0.5,
  -0.5, 0.5, 0.5,
  0.5, 0.5, 0.5,
  // f 4/11/4 3/12/4 7/7/4 6/6/4 
  0.5, -0.5, 0.5,
  0.5, -0.5, -0.5,
  0.5, 0.5, -0.5,
  // f 4/11/4 3/12/4 7/7/4 6/6/4 
  0.5, -0.5, 0.5,
  0.5, 0.5, 0.5,
  0.5, 0.5, -0.5,
  // f 3/13/5 2/14/5 8/8/5 7/7/5 
  0.5, -0.5, -0.5,
  -0.5, -0.5, -0.5,
  -0.5, 0.5, -0.5,
  // f 3/13/5 2/14/5 8/8/5 7/7/5 
  0.5, -0.5, -0.5,
  0.5, 0.5, -0.5,
  -0.5, 0.5, -0.5,
  // f 2/2/6 1/1/6 5/5/6 8/8/6 
  -0.5, -0.5, -0.5,
  -0.5, -0.5, 0.5,
  -0.5, 0.5, 0.5,
  // f 2/2/6 1/1/6 5/5/6 8/8/6 
  -0.5, -0.5, -0.5,
  -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5,
};


float boxTexCoords [] = {
  // f 1/1/1 2/2/1 3/3/1 4/4/1 
  0.5016, 0.7508,
  0.2504, 0.7508,
  0.2504, 1.002,
  // f 1/1/1 2/2/1 3/3/1 4/4/1 
  0.5016, 0.7508,
  0.5016, 1.002,
  0.2504, 1.002,
  // f 5/5/2 6/6/2 7/7/2 8/8/2 
  0.5016, 0.4996,
  0.5016, 0.2484,
  0.2504, 0.2484,
  // f 5/5/2 6/6/2 7/7/2 8/8/2 
  0.5016, 0.4996,
  0.2504, 0.4996,
  0.2504, 0.2484,
  // f 1/9/3 4/10/3 6/6/3 5/5/3 
  0.7528, 0.4996,
  0.7528, 0.2484,
  0.5016, 0.2484,
  // f 1/9/3 4/10/3 6/6/3 5/5/3 
  0.7528, 0.4996,
  0.5016, 0.4996,
  0.5016, 0.2484,
  // f 4/11/4 3/12/4 7/7/4 6/6/4 
  0.5016, -0.00279999999999991,
  0.2504, -0.00279999999999991,
  0.2504, 0.2484,
  // f 4/11/4 3/12/4 7/7/4 6/6/4 
  0.5016, -0.00279999999999991,
  0.5016, 0.2484,
  0.2504, 0.2484,
  // f 3/13/5 2/14/5 8/8/5 7/7/5 
  -0.0008, 0.2484,
  -0.0008, 0.4996,
  0.2504, 0.4996,
  // f 3/13/5 2/14/5 8/8/5 7/7/5 
  -0.0008, 0.2484,
  0.2504, 0.2484,
  0.2504, 0.4996,
  // f 2/2/6 1/1/6 5/5/6 8/8/6 
  0.2504, 0.7508,
  0.5016, 0.7508,
  0.5016, 0.4996,
  // f 2/2/6 1/1/6 5/5/6 8/8/6 
  0.2504, 0.7508,
  0.2504, 0.4996,
  0.5016, 0.4996,
};

И мой код рендеринга:

-(void)setup
{
    self.drawingMode = GL_TRIANGLES;
    vertexData = [NSMutableData dataWithBytes:boxVerts length:sizeof(float)*boxNumVerts*3];
    textureCoordinateData = [NSMutableData dataWithBytes:boxTexCoords length:sizeof(float)*boxNumVerts*2];
    //    vertexNormalData = [NSMutableData dataWithBytes:PrisonCellNormals length:sizeof(float)*PrisonCellNumVerts*3];
}

-(void)renderInScene:(FRPGScene *)_scene 
{
     if (texture != nil)
        {
            effect.texture2d0.envMode = GLKTextureEnvModeReplace;
            effect.texture2d0.target = GLKTextureTarget2D;
            effect.texture2d0.name = texture.name;
            [effect.texture2d0 setEnabled:YES];
        }

        effect.transform.modelviewMatrix = self.modelviewMatrix;
        effect.transform.projectionMatrix = _scene.projectionMatrix;

        [effect prepareToDraw];

        // setup
        glEnable(GL_BLEND);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glEnableVertexAttribArray(GLKVertexAttribPosition);

        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, self.vertices);

        if (!useConstantColor)
        {
            glEnableVertexAttribArray(GLKVertexAttribColor);
            glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, self.vertexColors);
        }

        if (texture != nil)
        {
            glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
            glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, self.textureCoordinates);
        }

        glDrawArrays(drawingMode, 0, self.numVertices);

        glDisable(GL_BLEND);

        // teardown
        glDisableVertexAttribArray(GLKVertexAttribPosition);

        if (!useConstantColor)
        {
            glDisableVertexAttribArray(GLKVertexAttribColor);
        }

        if (texture != nil)
        {
            glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
        }
}

ОБНОВЛЕНИЕ: функция appDelegate, в которой я устанавливаю свой контекст.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:context];

    GLKView *view = [[GLKView alloc] initWithFrame:[[UIScreen mainScreen] bounds] context:context];
    view.delegate = self; //Makes sure the views drawInRect is called

    FRPGViewController *controller = [[FRPGViewController alloc] init];
    controller.delegate = self;
    controller.view = view;

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = controller;
    [self.window makeKeyAndVisible];

    scene = [[FRPGTestLevel alloc] init];

    //Set screen aspect ratio boundaries ipad 4:3 iphone 3:2
    CGRect rect = view.bounds;

    scene.left = -100.0f;
    scene.right = 100.0f;
    scene.bottom = -100.0f / (rect.size.width / rect.size.height); // -75.0..
    scene.top = 100.0f / (rect.size.width / rect.size.height); // 75.0..
    [scene setup];

    [controller setScene:scene];


    return YES;
}

Функция рендеринга My Scenes очищает буфер и вызывает указанный выше метод renderInScene для каждого объекта.

-(void)render
{
     glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
     glClear(GL_COLOR_BUFFER_BIT);
     [object renderInScene:scene]; 
}  

person user2237669    schedule 04.04.2013    source источник
comment
Вы должны опубликовать свой код для настройки контекста OpenGL. У вас вообще есть буфер глубины? Я заметил, что вы не очищаете свой буфер глубины. Этот вызов glClear должен выглядеть как glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   -  person Aaron Golden    schedule 05.04.2013
comment
Для меня это похоже на проблему спереди/сзади. Я не прошел через все ваши вершины, но вы должны убедиться, что вы определяете все полигоны в порядке против часовой стрелки, чтобы сообщить OpenGL, что это передняя сторона многоугольника. Попробуйте использовать отсечение обратной стороны, чтобы не рисовать обратные стороны многоугольников с помощью glCullFace(GL_BACK); и glEnable(GL_CULL_FACE);.   -  person guitarflow    schedule 05.04.2013
comment
Спасибо за ваше время. Я обновил свой пост и добавил создание контекста. Я попробовал настройки cull face, как вы предложили, но это дало мне еще более странный эффект. imageshack.us/photo/my-images/27/test2ic.png   -  person user2237669    schedule 05.04.2013
comment
Спасибо, Дэн и Аарон, теперь каждый раз, когда я визуализирую объект с текстурой, я делаю glEnable(GL_CULL_FACE) перед рендерингом и glDisable(GL_CULL_FACE) после рендеринга объекта. Это работает хорошо!   -  person user2237669    schedule 05.04.2013


Ответы (1)


Вам нужно настроить буфер глубины

GLuint _depthRenderBuffer;

- (void)setupDepthBuffer
{
    glGenRenderbuffers(1, &_depthRenderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height);
}

а затем добавьте в буфер кадров

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
person goldenway    schedule 27.05.2013