You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从float[16]数组创建CGLM的Mat4矩阵?

从float[16]数组创建CGLM的mat4

问题描述

我知道在C++中可通过#include <glm/gtc/type_ptr.hpp>调用glm::make_mat4(),但CGLM中似乎没有可用的make_mat4()函数。有人能告诉我如何从float[16]数组创建CGLM的mat4吗?我尝试了以下方法,但输出的float值不符合预期:

#include "cglm/cglm.h" 
#include "cglm/call.h"

void main() {

   // Atempt #1
   float  aaa[16] = {
      1, 2, 3, 4,
      5, 6, 7, 8,
      9, 10, 11, 12,
      13, 14, 15, 16
   };
   mat4 bbb = {
   { aaa[0],aaa[1],aaa[2],aaa[3] },
   { aaa[4],aaa[5],aaa[6],aaa[7] },
   { aaa[8],aaa[9],aaa[10],aaa[11] },
   { aaa[12],aaa[13],aaa[14],aaa[15] }
   };
   for (int i = 0; i < 4; i++) {
       for (int k = 0; k < 4; k++) {
           printf("%d", bbb[i][k]);
           printf("\n");
       }
   }
   printf("\n");

   // Atempt #2
   //void *memcpy(void *dest, const void * src, size_t n)
   memcpy(bbb, aaa, sizeof(aaa));

   for (int i = 0; i < 4; i++) {
       for (int k = 0; k < 4; k++) {
           printf("%d", bbb[i][k]);
           printf("\n");
       }
   }
}

问题分析

你的代码有两个核心问题:

  1. 格式符错误:用%d(整数格式)打印float类型的矩阵元素,会导致输出完全错误的数值。
  2. 矩阵存储顺序不匹配:CGLM默认采用列主序存储矩阵(和OpenGL规范一致),而你定义的数组是行主序排列的,直接赋值或memcpy会导致矩阵的行列布局颠倒。

解决方案

1. 修正打印格式

首先把printf的格式符改为%f或%g,正确打印浮点数值:

printf("%f\n", bbb[i][k]);

或者直接使用CGLM内置的打印函数,更方便且格式规范:

glm_mat4_print(bbb, stdout, NULL);

2. 匹配矩阵存储顺序

根据你的数组存储方式,选择对应的方法:

情况A:数组是列主序(和CGLM一致)

如果你的数组已经是列主序排列(即数组的前4个元素是矩阵的第一列,接下来4个是第二列,以此类推),直接用memcpy或CGLM的glm_mat4_copy函数即可:

#include "cglm/cglm.h" 
#include <stdio.h>
#include <string.h>

int main() {
    // 列主序数组:每4个元素对应矩阵的一列
    float aaa[16] = {
        1, 5, 9, 13,  // 第一列
        2, 6, 10, 14, // 第二列
        3, 7, 11, 15, // 第三列
        4, 8, 12, 16  // 第四列
    };
    mat4 bbb;
    
    // 方法1:memcpy直接复制
    memcpy(bbb, aaa, sizeof(aaa));
    
    // 方法2:用CGLM内置函数
    // glm_mat4_copy(aaa, bbb);
    
    // 打印验证
    glm_mat4_print(bbb, stdout, NULL);
    return 0;
}

情况B:数组是行主序

如果你的数组是行主序(如你代码中定义的那样,每4个元素对应矩阵的一行),需要先复制再转置矩阵,或者手动按列赋值:

方法1:复制后转置
#include "cglm/cglm.h" 
#include <stdio.h>
#include <string.h>

int main() {
    // 行主序数组:每4个元素对应矩阵的一行
    float aaa[16] = {
        1, 2, 3, 4,  // 第一行
        5, 6, 7, 8,  // 第二行
        9, 10, 11, 12,// 第三行
        13,14,15,16   // 第四行
    };
    mat4 bbb;
    
    // 先复制数组到矩阵
    memcpy(bbb, aaa, sizeof(aaa));
    // 转置矩阵,将行主序转为列主序
    glm_mat4_transpose(bbb);
    
    // 打印验证
    glm_mat4_print(bbb, stdout, NULL);
    return 0;
}
方法2:手动按列赋值

直接按照CGLM的列主序结构,从行主序数组中提取对应元素:

mat4 bbb = {
    {aaa[0], aaa[4], aaa[8], aaa[12]},  // 第一列(原数组的每行第一个元素)
    {aaa[1], aaa[5], aaa[9], aaa[13]},  // 第二列(原数组的每行第二个元素)
    {aaa[2], aaa[6], aaa[10], aaa[14]}, // 第三列(原数组的每行第三个元素)
    {aaa[3], aaa[7], aaa[11], aaa[15]}  // 第四列(原数组的每行第四个元素)
};

内容的提问来源于stack exchange,提问作者CoolGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:01:07