我目前正在try 创建一个可以渲染体素和平面的最小3D引擎,但我遇到了一点小问题.现在,我正在try 开发一种算法,根据物体在相机上的位置对其进行分类.后面更远的东西总是先绘制的,如果它们的Z轴(相机正前方的距离)相同,它会绘制离屏幕中心更远的那个.

我有一个版本,我知道它可以在我的PC上运行,既可以使用gcc,也可以使用clang,但当我使用我正在开发的设备的工具链编译它时,它开始出现故障,并不完全符合我的要求.输出每隔一次更改一次.我可以做些什么来修复它,或者实现一个独立于我正在使用的Toochain的qsort函数,我能有什么建议吗?

// includes

int8_t player_x = 0;
int8_t player_y = 0;
int8_t player_z = 0;


int compareCoordinates(const void *a, const void *b) {

    int8_t *coord1 = (int8_t *)a;
    int8_t *coord2 = (int8_t *)b;
    
    
    if ((coord2[2] - coord1[2]) != 0) {
        return (coord2[2] - coord1[2]);
    }
    
    int value = (abs(coord2[0] - player_x) + abs(coord2[1] - player_y)) - (abs(coord1[0] - player_y) + abs(coord1[1] - player_y));

    if (value == 0){
        return 1;
    }
    
    return value;
}




void sortCoordinateList(int8_t coordinates[][3], int numCoordinates) {

    qsort(coordinates, numCoordinates, sizeof(coordinates[0]), compareCoordinates);
}

int8_t coordinates[][3] = {
        {1, 2, 5},
        {-1, 2, 5},
        {-3, 2, 5},
};

int main(void)
{

    sortCoordinateList(coordinates, LEN(coordinates));
    for (int i = 0; i < LEN(coordinates); i++) {
        dbg_printf("(%d, %d, %d)\n", coordinates[i][0], coordinates[i][1], coordinates[i][2]);
    }
    dbg_printf("\n\n");
}

这是删除移动函数的代码片段,但这是主要内容.我对C编程相当陌生,但我知道qsort会随机处理具有相同值的项或类似的东西,称为stable sorting,但我非常确信情况并非如此.

我try 了多种不同的调试和测试方法,但我完全被难住了.通常,当我遇到错误时,我会自己找出来,但我不得不屈服并提出我的第一个StackOverflow问题.顺便说一句,从今天到昨天,我已经为此工作了至少13-15个小时,所以是的,我已经尽我所能了.

推荐答案

这行看起来很可疑:

int value = (abs(coord2[0] - player_x) + abs(coord2[1] - player_y)) - (abs(coord1[0] - player_y) + abs(coord1[1] - player_y));

在该"值"计算中有4个表达式:

  • coord2.x - player.x
  • Coord2.y-player.y
  • Coord1.x-player.y ????
  • Coord1.y-player.y

这个副词:(abs(coord1[0] - player_y)似乎不太对劲.它用一个"y"值来子跟踪一个"x"值.

如果非要我猜的话,你应该先根据z深度进行排序.然后,作为相同z索引上的项目的打破平局的手段,根据与玩家的{x,y,z}坐标的距离进行排序.

我觉得你真的想要这个:

int compareCoordinates(const void* a, const void* b) {

    int8_t* coord1 = (int8_t*)a;
    int8_t* coord2 = (int8_t*)b;

    int8_t x1 = coord1[0];
    int8_t y1 = coord1[1];
    int8_t z1 = coord1[2];

    int8_t x2 = coord2[0];
    int8_t y2 = coord2[1];
    int8_t z2 = coord2[2];

    if (z2 != z1) {
        return z2 - z1;
    }

    int distance1 = (x1 - player_x) * (x1 - player_x) + (y1 - player_y) * (y1 - player_y);
    int distance2 = (x2 - player_x) * (x2 - player_x) + (y2 - player_y) * (y2 - player_y);

    return distance2 - distance1;

    return 0;
}

其中,距离1和距离2是"平方距离".不需要为了计算距离而取平方根.

所有这些都不能解释为什么你会得到不同的结果.这就是为什么我认为SPD的答案很可能是您所看到的错误的来源.

Update

为了解决对"数组的数组"进行排序的问题,使用qort时,使用tyecif是很有帮助的:

typedef int8_t COORD[3];

那么你的排序功能就是快速调整;

int compareCoordinates(const void* a, const void* b) {

    COORD* coord1 = (COORD*)a;
    COORD* coord2 = (COORD*)b;

    int8_t x1 = *(coord1)[0];
    int8_t y1 = *(coord1)[1];
    int8_t z1 = *(coord1)[2];

    int8_t x2 = *(coord2)[0];
    int8_t y2 = *(coord2)[1];
    int8_t z2 = *(coord2)[2];

    if (z2 != z1) {
        return z2 - z1;
    }

    int distance1 = (x1 - player_x) * (x1 - player_x) + (y1 - player_y) * (y1 - player_y);
    int distance2 = (x2 - player_x) * (x2 - player_x) + (y2 - player_y) * (y2 - player_y);

    return distance2 - distance1;

    return 0;
}

然后,其他一切都是使用COORD struct 的快速修复

void sortCoordinateList(COORD* coordinates, size_t numCoordinates) {
    qsort(coordinates, numCoordinates, sizeof(coordinates[0]), compareCoordinates);
}

COORD coordinates[3] = {
        {1, 2, 5},
        {-1, 2, 5},
        {-3, 2, 5},
};


int main(void)
{
    sortCoordinateList(coordinates, sizeof(coordinates) / sizeof(COORD));

C++相关问答推荐

如何在C中通过转换为char * 来访问float的字节表示?

错误:在.h程序中重新定义 struct

va_copy的使用是未定义的行为吗?

C中是否有语法可以直接初始化一个常量文本常量数组的 struct 成员?

GCC引发不明确的诊断消息

将 struct 传递给函数

使用错误的命令执行程序

有什么方法可以将字符串与我们 Select 的子字符串分开吗?喜欢:SIN(LOG(10))

这个计算C中阶乘的函数正确吗?

用C++从外部ELF符号读取值

tick.q中的Kdb+键控表语法

如何在GDB中查看MUSL的源代码

按长度对argv中的单词进行排序

将多项式从文件.txt加载到终端时出现问题

从BIOS(8086)中读取刻度需要多少?

在吉陀罗中,_2_1_和CONCAT11是什么意思?

如何在C中定义指向函数的指针并将该指针赋给函数?

意外的C并集结果

尽管将其标记为易失性,但 gcc 是否优化了我的等待代码?

如何在 C 中编辑 struct 体中的多个变量