Проблемы с указателями и рисованием в opengl

#objective-c #c #pointers #opengl-es

#objective-c #c #указатели #opengl-es

Вопрос:

Я пытаюсь реализовать простой rendermanager. Другой класс предоставляет структуру, представляющую квадрат, и она копируется в буфер массива вершин в rendermanager.

Однако копирование, похоже, не работает, когда я вручную создаю структуру и копирую в vertexarray, все в порядке, и он отображается. Но где-то в копии все идет наперекосяк. Я вижу это с помощью gdb (значения разные), но я не могу понять, что происходит.

Методы RenderManager

 -(id)init
{
    if([super init]){
        iva = calloc(MAX_QUADS, sizeof(quad));

        quad draw = {
            0.0f,0.0f,0.0f,          0.0f,0.0f,1.0f,    //Bottom left
            1.0f,0.0f,0.0f,          0.0f,0.0f,1.0f,    //Top Left
            1.0f,1.0f,0.0f,          0.0f,0.0f,1.0f,    //Top Right
            0.0f,1.0f,0.0f,          0.0f,0.0f,1.0f,    //Bottom Right

            0.5f,0.5f,0.0f,          0.0f,0.0f,1.0f,    //Center
        };
  

Если я прокомментирую это, ничего не получится. Используя его, я получаю ожидаемый результат

         memcpy(iva, amp;draw, sizeof(draw)); 
        . . . OpenGl methods

//Add the quad details to the render queue
-(void)addDetailsToRenderQueue:(quad *)details
{
    if(iva == NULL)
        NSLog(@"Error claiming memory, something is very wrong");

    if(renderCount   1 > MAX_QUADS){
        NSLog(@"Render buffer full, dumping...");
        [self render];
    }

    memcpy((quad *)iva   renderCount  , amp;details, sizeof(quad));
}

//Render the details in the render queue, for each quad we need to make two triangles.
-(void)render
{
    int counter = 0;

    renderCount *= 5;

    for(int i;i < renderCount;){
        ivaIndices[counter  ] = i   0;     // Bottom left
        ivaIndices[counter  ] = i   1;     //Top Left
        ivaIndices[counter  ] = i   4;      //Center

        ivaIndices[counter  ] = i   1;      //Top Left
        ivaIndices[counter  ] = i   2;      //Top right
        ivaIndices[counter  ] = i   4;      //Center

        ivaIndices[counter  ] = i   2;      //Top right
        ivaIndices[counter  ] = i   3;      //Bottom right
        ivaIndices[counter  ] = i   4;      //Center

        ivaIndices[counter  ] = i   3;      //Bottom right
        ivaIndices[counter  ] = i   0;      //Bottom Left
        ivaIndices[counter  ] = i   4;      //Center

        i  = 5;
    }
    glBindVertexArrayOES(_vertexArray);

    glDrawElements(GL_LINE_STRIP,12, GL_UNSIGNED_SHORT, ivaIndices);

    // Reset the number of quads which need to be rendered
    renderCount = 0;
}   
  

Методы диспетчера листов

 @interface TileSet : NSObject
{
    quad *tiles;
    NSUInteger tileCount;

    RenderManager *sharedRenderManager;
}

-(id)init
{
    if([super init]){
        tiles = calloc(MAX_HEIGHT * MAX_WIDTH, sizeof(quad));
        tileCount = 0;

        sharedRenderManager = [RenderManager sharedManager];
    }
    [self fillArray];
    return self;
}

-(void)fillArray
{   
    int rows = 4;
    int columns = 12;

    for(int i = 0; i < rows;i  = 2) { 
        for(int j = 0;j < columns;j  = 2) {
            quad tmp;

            tmp.v1.x = i;
            tmp.v1.y = j;
            tmp.v1.z = 0.0f;
            tmp.v1.nx = 0.0f;
            tmp.v1.ny = 0.0f;
            tmp.v1.nz = 1.0f;

            tmp.v2.x = i   1;
            tmp.v2.y = j;
            tmp.v2.z = 0.0f;
            tmp.v2.nx = 0.0f;
            tmp.v2.ny = 0.0f;
            tmp.v2.nz = 1.0f;

            tmp.v3.x = i;
            tmp.v3.y = j 1;
            tmp.v3.z = 0.0f;
            tmp.v3.nx = 0.0f;
            tmp.v3.ny = 0.0f;
            tmp.v3.nz = 1.0f;

            tmp.v4.x = i   1;
            tmp.v4.y = j 1;
            tmp.v4.z = 0.0f;
            tmp.v4.nx = 0.0f;
            tmp.v4.ny = 0.0f;
            tmp.v4.nz = 1.0f;

            tmp.v5.x = i   0.5;
            tmp.v5.y = j   0.5;
            tmp.v5.z = 0.0f;
            tmp.v5.nx = 0.0f;
            tmp.v5.ny = 0.0f;
            tmp.v5.nz = 1.0f;

            memcpy((quad *)tiles   (i*j   j), amp;tmp, sizeof(quad));
            tileCount  ;
        }
    }
}

//Draw the tiles in the tileset, loop through and add to renderManagers queue
-(void)render
{
for(int i = 0; i  < tileCount;i  )
    [sharedRenderManager addDetailsToRenderQueue:amp;tiles[0]];

} 
  

Редактировать
В ответ на вопрос, добавив

 NSLog(@"Tiles:%xtDisgusting pointer math:%x",tiles,(quad *)tiles   (i*j   j));
  

Выдайте результат

 2011-10-21 21:29:21.456 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:7316200
2011-10-21 21:29:21.458 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73162f0
2011-10-21 21:29:21.463 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73163e0
2011-10-21 21:29:21.464 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73164d0
2011-10-21 21:29:21.465 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73165c0
2011-10-21 21:29:21.465 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:7316200
2011-10-21 21:29:21.466 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73164d0
2011-10-21 21:29:21.467 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:73167a0
2011-10-21 21:29:21.470 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:7316a70
2011-10-21 21:29:21.470 TerrainRendering[11293:fb03] Tiles:7316200  Disgusting pointer math:7316d40
  

Комментарии:

1. NSLog(@»%x %x», …) адреса tiles и (quad *)tiles (i*j j) , я думаю, вычисляемый адрес не тот, который вы ожидали.

2. Теперь это значение указателя то, которое вы ожидаете? Или что это должно быть?

3. Честно говоря, я не совсем уверен, чего я ожидал. Хотя это не кажется правильным.

Ответ №1:

Ваше смещение в memcpy должно быть (i*MAX_HEIGHT j) . Вы хотите переходить по строкам с помощью «i» (внешний цикл) и последовательно углубляться в них с помощью «j» (внутренний цикл).

Надеюсь, это поможет