Android ndk C矩阵库,适用于Android上的opengl(NDK)

Android ndk C矩阵库,适用于Android上的opengl(NDK),android-ndk,opengl-es-2.0,Android Ndk,Opengl Es 2.0,我正在用C编写一个使用OpenGLES2.0和NDK的渲染例程。我对用于矩阵图形转换的(速度高于精度)库以及您可以推荐的任何最佳实践感兴趣 编写我自己的函数并非不可能,但我想在重新发明轮子之前,我会在这里问一下。谢谢 似乎是个不错的选择。GLM数学库的功能远远不止于变换和其他矩阵运算。例如,它具有GLSL样式的mix()api,可用于在将值发送到着色器之前对其进行插值。从中获取android.opengl.matrix java代码的副本。 然后将语法从Java更改为C,就可以开始了。这是我在自

我正在用C编写一个使用OpenGLES2.0和NDK的渲染例程。我对用于矩阵图形转换的(速度高于精度)库以及您可以推荐的任何最佳实践感兴趣


编写我自己的函数并非不可能,但我想在重新发明轮子之前,我会在这里问一下。谢谢

似乎是个不错的选择。

GLM数学库的功能远远不止于变换和其他矩阵运算。例如,它具有GLSL样式的mix()api,可用于在将值发送到着色器之前对其进行插值。

从中获取android.opengl.matrix java代码的副本。 然后将语法从Java更改为C,就可以开始了。这是我在自己的项目中使用的代码。不过,它不是一套完整的Opengl矩阵函数

#include <stdlib.h>
#include <math.h>

#define PI 3.1415926f
#define normalize(x, y, z)                  \
{                                               \
        float norm = 1.0f / sqrt(x*x+y*y+z*z);  \
        x *= norm; y *= norm; z *= norm;        \
}
#define I(_i, _j) ((_j)+4*(_i))

void matrixSetIdentityM(float *m)
{
        memset((void*)m, 0, 16*sizeof(float));
        m[0] = m[5] = m[10] = m[15] = 1.0f;
}

void matrixSetRotateM(float *m, float a, float x, float y, float z)
{
        float s, c;

        memset((void*)m, 0, 15*sizeof(float));
        m[15] = 1.0f;

        a *= PI/180.0f;
        s = sin(a);
        c = cos(a);

        if (1.0f == x && 0.0f == y && 0.0f == z) {
                m[5] = c; m[10] = c;
                m[6] = s; m[9]  = -s;
                m[0] = 1;
        } else if (0.0f == x && 1.0f == y && 0.0f == z) {
                m[0] = c; m[10] = c;
                m[8] = s; m[2]  = -s;
                m[5] = 1;
        } else if (0.0f == x && 0.0f == y && 1.0f == z) {
                m[0] = c; m[5] = c;
                m[1] = s; m[4] = -s;
                m[10] = 1;
        } else {
                normalize(x, y, z);
                float nc = 1.0f - c;
                float xy = x * y;
                float yz = y * z;
                float zx = z * x;
                float xs = x * s;
                float ys = y * s;
                float zs = z * s;
                m[ 0] = x*x*nc +  c;
                m[ 4] =  xy*nc - zs;
                m[ 8] =  zx*nc + ys;
                m[ 1] =  xy*nc + zs;
                m[ 5] = y*y*nc +  c;
                m[ 9] =  yz*nc - xs;
                m[ 2] =  zx*nc - ys;
                m[ 6] =  yz*nc + xs;
                m[10] = z*z*nc +  c;
        }
}

void matrixMultiplyMM(float *m, float *lhs, float *rhs)
{
        float t[16];
        for (int i = 0; i < 4; i++) {
                register const float rhs_i0 = rhs[I(i, 0)];
                register float ri0 = lhs[ I(0,0) ] * rhs_i0;
                register float ri1 = lhs[ I(0,1) ] * rhs_i0;
                register float ri2 = lhs[ I(0,2) ] * rhs_i0;
                register float ri3 = lhs[ I(0,3) ] * rhs_i0;
                for (int j = 1; j < 4; j++) {
                        register const float rhs_ij = rhs[ I(i,j) ];
                        ri0 += lhs[ I(j,0) ] * rhs_ij;
                        ri1 += lhs[ I(j,1) ] * rhs_ij;
                        ri2 += lhs[ I(j,2) ] * rhs_ij;
                        ri3 += lhs[ I(j,3) ] * rhs_ij;
                }
                t[ I(i,0) ] = ri0;
                t[ I(i,1) ] = ri1;
                t[ I(i,2) ] = ri2;
                t[ I(i,3) ] = ri3;
        }
        memcpy(m, t, sizeof(t));
}

void matrixScaleM(float *m, float x, float y, float z)
{
        for (int i = 0; i < 4; i++)
        {
                m[i] *= x; m[4+i] *=y; m[8+i] *= z;
        }
}

void matrixTranslateM(float *m, float x, float y, float z)
{
        for (int i = 0; i < 4; i++)
        {
                m[12+i] += m[i]*x + m[4+i]*y + m[8+i]*z;
        }
}

void matrixRotateM(float *m, float a, float x, float y, float z)
{
        float rot[16], res[16];
        matrixSetRotateM(rot, a, x, y, z);
        matrixMultiplyMM(res, m, rot);
        memcpy(m, res, 16*sizeof(float));
}

void matrixLookAtM(float *m,
                float eyeX, float eyeY, float eyeZ,
                float cenX, float cenY, float cenZ,
                float  upX, float  upY, float  upZ)
{
        float fx = cenX - eyeX;
        float fy = cenY - eyeY;
        float fz = cenZ - eyeZ;
        normalize(fx, fy, fz);
        float sx = fy * upZ - fz * upY;
        float sy = fz * upX - fx * upZ;
        float sz = fx * upY - fy * upX;
        normalize(sx, sy, sz);
        float ux = sy * fz - sz * fy;
        float uy = sz * fx - sx * fz;
        float uz = sx * fy - sy * fx;

        m[ 0] = sx;
        m[ 1] = ux;
        m[ 2] = -fx;
        m[ 3] = 0.0f;
        m[ 4] = sy;
        m[ 5] = uy;
        m[ 6] = -fy;
        m[ 7] = 0.0f;
        m[ 8] = sz;
        m[ 9] = uz;
        m[10] = -fz;
        m[11] = 0.0f;
        m[12] = 0.0f;
        m[13] = 0.0f;
        m[14] = 0.0f;
        m[15] = 1.0f;
        matrixTranslateM(m, -eyeX, -eyeY, -eyeZ);
}

void matrixFrustumM(float *m, float left, float right, float bottom, float top, float near, float far)
{
        float r_width  = 1.0f / (right - left);
        float r_height = 1.0f / (top - bottom);
        float r_depth  = 1.0f / (near - far);
        float x = 2.0f * (near * r_width);
        float y = 2.0f * (near * r_height);
        float A = 2.0f * ((right+left) * r_width);
        float B = (top + bottom) * r_height;
        float C = (far + near) * r_depth;
        float D = 2.0f * (far * near * r_depth);

        memset((void*)m, 0, 16*sizeof(float));
        m[ 0] = x;
        m[ 5] = y;
        m[ 8] = A;
        m[ 9] = B;
        m[10] = C;
        m[14] = D;
        m[11] = -1.0f;
}
#包括
#包括
#定义PI 3.1415926f
#定义规格化(x、y、z)\
{                                               \
浮动标准=1.0f/sqrt(x*x+y*y+z*z)\
x*=范数;y*=范数;z*=范数\
}
#定义I(_I,_j)(_j)+4*(_I))
无效矩阵有效性(浮动*m)
{
memset((void*)m,0,16*sizeof(float));
m[0]=m[5]=m[10]=m[15]=1.0f;
}
无效矩阵状态m(浮点*m、浮点a、浮点x、浮点y、浮点z)
{
浮点数s,c;
memset((void*)m,0,15*sizeof(float));
m[15]=1.0f;
a*=PI/180.0f;
s=sin(a);
c=cos(a);
如果(1.0f==x&&0.0f==y&&0.0f==z){
m[5]=c;m[10]=c;
m[6]=s;m[9]=s;
m[0]=1;
}else如果(0.0f==x&&1.0f==y&&0.0f==z){
m[0]=c;m[10]=c;
m[8]=s;m[2]=s;
m[5]=1;
}else如果(0.0f==x&&0.0f==y&&1.0f==z){
m[0]=c;m[5]=c;
m[1]=s;m[4]=s;
m[10]=1;
}否则{
归一化(x,y,z);
浮动nc=1.0f-c;
浮动xy=x*y;
浮动yz=y*z;
浮点数zx=z*x;
浮点数xs=x*s;
浮动ys=y*s;
浮点数zs=z*s;
m[0]=x*x*nc+c;
m[4]=xy*nc-zs;
m[8]=zx*nc+ys;
m[1]=xy*nc+zs;
m[5]=y*y*nc+c;
m[9]=yz*nc-xs;
m[2]=zx*nc-ys;
m[6]=yz*nc+xs;
m[10]=z*z*nc+c;
}
}
无效矩阵多重符号(浮点*m,浮点*lhs,浮点*rhs)
{
浮点数t[16];
对于(int i=0;i<4;i++){
寄存器常量浮点rhs_i0=rhs[I(I,0)];
寄存器浮点ri0=lhs[I(0,0)]*rhs_i0;
寄存器浮点ri1=lhs[I(0,1)]*rhs_i0;
寄存器浮点ri2=lhs[I(0,2)]*rhs_i0;
寄存器浮点ri3=lhs[I(0,3)]*rhs_i0;
对于(int j=1;j<4;j++){
寄存器常量浮点rhs_ij=rhs[I(I,j)];
ri0+=lhs[I(j,0)]*rhs_ij;
ri1+=lhs[I(j,1)]*rhs_ij;
ri2+=lhs[I(j,2)]*rhs_ij;
ri3+=lhs[I(j,3)]*rhs_ij;
}
t[I(I,0)]=ri0;
t[I(I,1)]=ri1;
t[I(I,2)]=ri2;
t[I(I,3)]=ri3;
}
memcpy(m,t,sizeof(t));
}
无效矩阵calem(浮点*m,浮点x,浮点y,浮点z)
{
对于(int i=0;i<4;i++)
{
m[i]*=x;m[4+i]*=y;m[8+i]*=z;
}
}
无效矩阵转换(浮点*m,浮点x,浮点y,浮点z)
{
对于(int i=0;i<4;i++)
{
m[12+i]+=m[i]*x+m[4+i]*y+m[8+i]*z;
}
}
无效矩阵旋转em(浮动*m、浮动a、浮动x、浮动y、浮动z)
{
浮子腐烂[16],res[16];
基质反酸盐(rot,a,x,y,z);
矩阵多重矩阵(res,m,rot);
memcpy(m,res,16*sizeof(float));
}
无效矩阵lookatm(浮动*m,
浮眼,浮眼,浮眼,
浮点数cenX,浮点数cenY,浮点数cenZ,
浮动upX、浮动upY、浮动upZ)
{
浮动汇率=cenX-eyeX;
浮动fy=中心-眼睛;
浮动fz=cenZ-eyeZ;
正常化(外汇、fy、fz);
浮点数sx=fy*upZ-fz*upY;
浮动sy=fz*upX-fx*upZ;
浮动汇率sz=fx*upY-fy*upX;
正常化(sx,sy,sz);
浮动ux=sy*fz-sz*fy;
浮动uy=sz*fx-sx*fz;
浮点数uz=sx*fy-sy*fx;
m[0]=sx;
m[1]=ux;
m[2]=-fx;
m[3]=0.0f;
m[4]=sy;
m[5]=uy;
m[6]=-fy;
m[7]=0.0f;
m[8]=sz;
m[9]=uz;
m[10]=-fz;
m[11]=0.0f;
m[12]=0.0f;
m[13]=0.0f;
m[14]=0.0f;
m[15]=1.0f;
矩阵变换(m,-eyeX,-eyeY,-eyeZ);
}
空隙矩阵除锈(浮动*m、浮动左、浮动右、浮动底、浮动顶、浮动近、浮动远)
{
浮动r_宽度=1.0f/(右-左);
浮子r_高度=1.0f/(顶部-底部);
浮动r_深度=1.0f/(近-远);
浮动x=2.0f*(接近*r_宽度);
浮动y=2.0f*(接近r_高度);
浮动A=2.0f*((右+左)*r_宽度);
浮子B=(顶部+底部)*r_高度;
浮点数C=(远+近)*r_深度;
浮动D=2.0f*(远*近*r_深度);
memset((void*)m,0,16*sizeof(float));
m[0]=x;
m[5]=y;
m[8]=A;
m[9]=B;
m[10]=C;
m[14]=D;
m[11]=-1.0f;
}

有点晚,但可能与选择使用C的人有关:

我发现了一个文件头,它可以很好地写出所需的所有线性功能

<
mat4x4 projection;
mat4x4 modelview;

// other stuff such as initialization etc

mat4x4_frustum(projection, -1, 1, -1, 1, 0.5, 100);
mat4x4_translate(modelview, 0, 0, -1);

// ...

// Render Operation: mvMatrixHandle and pMatrixHandle are defined previously
glUniformMatrix4fv(mvMatrixHandle, 1, GL_FALSE, modelview);
glUniformMatrix4fv(pMatrixHandle, 1, GL_FALSE, projection);