[Day 21] 2D批次渲染 (三) - Bug!一堆Bug

今日目标

  • 继续完成批次渲染

结果...

今天抓到一堆bug,但是还是没debug完,被我弄丢的小方块(矩形)回不来了。目前还在努力Debug中....

这是目前的结果,看起来跟之前预设贴图没有差别,但这边主要算是优化的部分(过早优化?)

Bug001 - buffer的初始化大小

一开始碰到的问题是闪退,我就猜可能跟我配置的阵列大小有问题。

之前有提到(如果读者还记得的话),会初始化一个很大的阵列储存顶点资料,我是这样new出来的

CONTEXT.RenderState.vertex_buffer.vertices = (V2f*)calloc(DEFAULT_MAX_RECT * VERICES_PER_RECT, DEFAULT_MAX_RECT * VERICES_PER_RECT * sizeof(V2f));

这是一个非常单纯的错误,calloc的用法用错了arg0是「数量大小」;arg1是「物件」大小,但arg1我代成「记忆体区块」大小了。

所以,要改成这样

CONTEXT.RenderState.vertex_buffer.vertices = (V2f*)calloc(DEFAULT_MAX_RECT * VERICES_PER_RECT, sizeof(V2f));

参考 calloc - cppreference

Bug002 - draw call计数被清掉了

後来正常进入Game Loop了,但是只有看到背景颜色,没有看到图,於是我直接在RenderCurrentBatch放上计数器与绘出的定点数目,我还没正式介绍整个详细流程作法,之後会详细介绍,先说这个function功能是绘出目前所有Draw call里记录的顶点。

结果,发现虽然Game Loop一直在更新,但是RenderCurrentBatch只有呼叫一次 O_O

後来发现是这里

...

    // draw!!
    size_t vertex_offset = 0;
    for (size_t i = 0; i < CONTEXT.RenderState.draw_calls_count; i++) { // 这里会看draw call阵列的长度
        glDrawElements(GL_TRIANGLES, (CONTEXT.RenderState.draw_calls[i].vertices_count / VERICES_PER_RECT * INDICES_PER_RECT), GL_UNSIGNED_INT, (const GLvoid*)(sizeof(unsigned int) * vertex_offset / VERICES_PER_RECT * INDICES_PER_RECT));
        vertex_offset += CONTEXT.RenderState.draw_calls[i].vertices_count;
        // LogInfo("Current draw %d, vertices count %d", (i + 1), CONTEXT.RenderState.draw_calls[i].vertices_count);
    }

    glBindVertexArray(0);

    // reset vertex buffer and draw calls
    CONTEXT.RenderState.vertex_buffer.vertices_count = 0;
    CONTEXT.RenderState.vertex_buffer.texcoords_count = 0;
    CONTEXT.RenderState.vertex_buffer.colors_count = 0;
    CONTEXT.RenderState.vertex_buffer.indices_count = 0;

    for (int i = 0; i < MAX_DRAW_CALL_PER_FRAME; i++) {
        CONTEXT.RenderState.draw_calls[i].vertices_count = 0;
    }
    CONTEXT.RenderState.draw_calls_count = 1; // 这一行,原本是指派为0,之会导致下一帧,没有初始数量的draw call计数,直接跳开堆送顶点与渲染的功能

...

Bug003 - 颜色(Color)的attribute没有抓到...

问题出在预设的shader上,_Color从原本的uniform变为从vertex shader就开始设置的属性(VertexAttribute),原本是这样:

// default vertex sahder
static const char* DEFAULT_2D_VERTEX_SHADER_CODE = "#version 330 core\n"
"in vec2 _Pos;\n"
"in vec2 _Texcoords;\n"
"out vec2 Texcoords;\n"
"out vec4 Color;\n"
"uniform mat4 _MVP;\n"
"void main() {\n"
"   gl_Position = _MVP * vec4(_Pos, 0.0, 1.0);\n"
"   Texcoords = _Texcoords;\n"
"}\n\0";

// * texture(_Texture2D, Texcoords)

// default fragment shader
static const char* DEFAULT_2D_FRAGMENT_SHADER_CODE = "#version 330 core\n"
"in vec2 Texcoords;\n"
"uniform vec4 Color;\n" // 这里
"uniform sampler2D _Texture2D;"
"out vec4 _FragColor;\n"
"void main() {\n"
"   _FragColor = _Color * texture(_Texture2D, Texcoords);\n" // TODO: can't draw the default texture over here
"}\n\0";

改成这样

// default vertex sahder
static const char* DEFAULT_2D_VERTEX_SHADER_CODE = "#version 330 core\n"
"in vec2 _Pos;\n"
"in vec2 _Texcoords;\n"
"in vec4 _Color;\n" // 这里
"out vec2 Texcoords;\n"
"out vec4 Color;\n" // 这里
"uniform mat4 _MVP;\n"
"void main() {\n"
"   gl_Position = _MVP * vec4(_Pos, 0.0, 1.0);\n"
"   Texcoords = _Texcoords;\n"
"   Color = _Color;\n" // 这里
"}\n\0";

// * texture(_Texture2D, Texcoords)

// default fragment shader
static const char* DEFAULT_2D_FRAGMENT_SHADER_CODE = "#version 330 core\n"
"in vec2 Texcoords;\n"
"in vec4 Color;\n" // 这里
"uniform sampler2D _Texture2D;"
"out vec4 _FragColor;\n"
"void main() {\n"
"   _FragColor = Color * texture(_Texture2D, Texcoords);\n" // TODO: can't draw the default texture over here
"}\n\0";

但我在iron_asset内载入shader的属性,没有改写,依旧是

int color_location = glGetUniformLocation(shader->id, "_Color");
shader->attribs_locations[SHADER_ATTRIB_VEC4_COLOR] = color_location;

要改成

int color_location = glGetAttribLocation(shader->id, "_Color");
shader->attribs_locations[SHADER_ATTRIB_VEC4_COLOR] = color_location;

请注意: 虽说我都是说属性(Attribute),但是在OpenGL状态机中纪录的uniformattribute是分开的,毕竟两个的功能面确实都不一样。

说说最近...

原本参加铁人赛应该是发技术文章的,但不知不觉已经变成开发日志了,老实说,之前参加(2020年)会去囤积文章,这样有问题就可以先发出去了。

今年(2021年)想说这次参加来点限制与挑战,「不」囤积一天写或学多少,就做多少,结果到现在20天过了,也没有个雏型出来,如果真的要完成就要突破30天限制了...

老实说,渐渐的不太像是单纯的完成一款2D Platformer了,比较像是从「引擎」开始做起。

有把这几个bug修正上传了,但是就如同最开始说的....还是有很bug,这里是连结


<<:  Day 30:「很刺眼,这样太亮了啦!」- 深色模式切换开关

>>:  [Day16] 第十六章-Skill的API 服务建构 (migration,route,controller,model)

[烧烤吃到饱-2] 好好吃肉韩式烤肉吃到饱-台中公益店 #中秋节烤肉精选店家

这样的食材,才299吃到饱,别挑剔了啦~ 这家好好吃肉,就位在前几天分享过的「咕咕家」正对面。 好好...

Python 学习笔记

内容主要是codewar练习的成果 自己写得以及自己看得懂的觉得写得好的解答 目的是为了自己哪天懈怠...

[线上工具] 分享 / [铁人赛] 完赛心得

最後一篇除了参赛心得之外,也来分享一下切版时常用的线上应用小工具好了~这样才有写了「三十篇」技术文的...

【Day9】[资料结构]-杂凑表Hash Table

杂凑表(Hash Table)又称哈希表,是透过杂凑函式(Hash Function)来计算出一个键...

Day6-React Hook 篇-useReducer

这个 hook 可以让我们用类似 redux 用 reducer、action、dispatch 操...