指针和 opengl 绘图的问题

发布于 2024-12-11 04:18:47 字数 5264 浏览 2 评论 0原文

我正在尝试实现一个简单的渲染管理器。另一个类提供了表示四边形的结构,并将其复制到渲染管理器中的顶点数组缓冲区中。

然而,复制似乎不起作用,当我手动创建一个结构并将其复制到顶点数组中时,一切都很好并且可以渲染。但在副本的某个地方一切都出了问题。我可以使用 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, &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++, &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), &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:&tiles[0]];

} 

编辑 针对问题,添加

NSLog(@"Tiles:%x\tDisgusting 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

I am trying to implement a simple rendermanager. Another class provides a structure that represents a quad, and this is copied into a vertex array buffer in the rendermanager.

However the copying doesn't seem to work, when I manually create a struct and copy into the the vertexarray everything is fine and it renders. But somewhere in the copy everything goes awry. I can see this using gdb(the values are different), but I cannot figure out what is going on.

RenderManager methods

-(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
        };

If I comment this out nothing draws. Using it and I get the nice quad I am expecting

        memcpy(iva, &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++, &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;
}   

Tile Manager methods

@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), &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:&tiles[0]];

} 

EDIT
In response to question, Adding

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

Give the result

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2024-12-18 04:18:47

memcpy 中的偏移量应为 (i*MAX_HEIGHT + j)。您想使用“i”(外循环)跳转行并使用“j”(内循环)顺序深入研究它们。

希望这有帮助

Your offset in memcpy should be (i*MAX_HEIGHT + j). You want to jump rows with the "i"(outer loop) and delve sequentially into them with "j" (inner loop).

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文