2011-03-05 48 views
4

我正在用C使用opengl es 2.0和NDK编写渲染例程。我对基于矩阵的图形转换(速度超过精度)库以及任何可推荐的最佳实践感兴趣。C矩阵库,适合​​在Android上使用opengl(NDK)

写我自己的功能并不是不可能的,但我想我会在重新发明车轮之前问这里。谢谢。

+0

要回答我自己的问题,我可能会写我自己的例程,使用这个写得很好的代码作为参考。 https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/google/resources/moz/matrix4x4.js – LazyBitStream 2011-03-05 05:17:21

回答

5

OpenGL Mathematics (GLM)似乎是一个不错的选择。

+0

谢谢,这个结果很好。虽然我要求一个C库,但是cpp的方向值得采纳。仅供参考:要使用此库,请务必使用stlport,请参阅CPLUSPLUS-SUPPORT文档了解操作方法。 – LazyBitStream 2011-03-07 01:46:08

+0

我无法使用NDK进行编译。我在'sizeof'之前得到错误,比如'func_common.hpp:240:错误:在'sizeof'或'func_common.inl:1217:error:expected')之前预期的不合格id。 – j00hi 2011-09-15 16:57:22

-1

你不能只使用内建的Java矩阵类(例如http://developer.android.com/reference/android/opengl/Matrix.html)来进行转换吗?

你特别想做什么(即什么类型的变换)?已经建立了许多常见的转换:(例如参见this

+0

感谢您的回复,但不幸的是您的示例涵盖了opengl es 1.0(固定功能流水线)。这些内置函数在opengl es 2.0中不存在。 – LazyBitStream 2011-03-05 05:16:12

+0

对于矩阵库,这是非常有用的,但看看它的来源,它是一些本地调用的Java混合。我想尽可能避免从C中调用java。 – LazyBitStream 2011-03-05 05:20:40

0

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

3

here获取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; 
} 
0

有点晚,但可能对那些谁选择用C相关:

我发现所有必要的线性功能编写出很好的单文件头。

https://github.com/datenwolf/linmath.h/blob/master/linmath.h

它包含了所有必需的矩阵/矢量类型的,和正常工作与Android NDK/GL2。例如:

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); 
+2

请添加一些解释。如果没有,您的答案可能会被标记为“低质量”并最终被删除。由于链接可能会中断,并且答案变得毫无价值,Stackoverflow不会太热情地链接回答。 – 2016-03-05 21:22:28