由於Objective-C是C的超集,所以我通常會傳遞C中具有數組的數組,因爲Objective-C是C的超集,可以很容易地在兩者之間進行切換。我想在Objective-C中編寫一個特定的函數,雖然它會將一組GLfloats(是的,我使用OpenGL)傳遞給函數進行矩陣計算。我試着這樣做:如何將數組傳遞給函數Objective-C
- (void)setIdentity:(GLfloat *)target
{
target[0] = 1;
target[1] = 0;
target[2] = 0;
target[3] = 0;
target[4] = 0;
target[5] = 1;
target[6] = 0;
target[7] = 0;
target[8] = 0;
target[9] = 0;
target[10] = 1;
target[11] = 0;
target[12] = 0;
target[13] = 0;
target[14] = 0;
target[15] = 1;
}
,然後試圖向矩陣傳遞給函數的16項長期GLfloat數組使用此:
[matrix setIdentity:ModelMat];
//Log the result
NSLog(@"ModelMat:\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f",
ModelMat[0], ModelMat[1], ModelMat[2], ModelMat[3], ModelMat[4], ModelMat[5],
ModelMat[6], ModelMat[7], ModelMat[8], ModelMat[9], ModelMat[10], ModelMat[11],
ModelMat[12], ModelMat[13], ModelMat[14], ModelMat[15]);
只是爲了確保它返回正確的價值觀但輸出只是一個0的矩陣。我在這裏做錯了什麼?
- 編輯
爲了更好地幫助別人明白我的問題,我加入了,我想設置的身份和Matrix類在那裏我有身份的場景類的源代碼,以及更多的矩陣相關項目。
Matrix.h
@interface Matrix : NSObject
- (void)copyMatrix:(GLfloat *)from to:(GLfloat *)to;
- (void)setIdentity:(GLfloat *)target;
- (void)multiplyMatrix:(GLfloat *)second by:(GLfloat *)first giving:(GLfloat *)newMatrix;
- (void)applyTranslation:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
- (void)applyScale:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
- (void)applyRotation:(GLfloat *)source pitch:(GLfloat)pitch yaw:(GLfloat)yaw roll:(GLfloat)roll;
- (void)applyRotationWithMag:(GLfloat *)source angle:(GLfloat)angle magX:(GLfloat)magX magY:(GLfloat)magY magZ:(GLfloat)magZ
- (void)setProjection:(GLfloat *)source fov:(GLfloat)fov aspect:(GLfloat)aspect near:(GLfloat)near far:(GLfloat)far;
@end
Matrix.m
#import "Matrix.h"
#define PI 3.1415926535897932384626433832795f
@implementation Matrix
- (void)copyMatrix:(GLfloat *)from to:(GLfloat *)to
{
for(int i = 0; i < 16; i++)
from[i] = to[i];
}
- (void)setIdentity:(GLfloat *)target
{
target[0] = 1;
target[1] = 0;
target[2] = 0;
target[3] = 0;
target[4] = 0;
target[5] = 1;
target[6] = 0;
target[7] = 0;
target[8] = 0;
target[9] = 0;
target[10] = 1;
target[11] = 0;
target[12] = 0;
target[13] = 0;
target[14] = 0;
target[15] = 1;
}
- (void)multiplyMatrix:(GLfloat *)second by:(GLfloat *)first giving:(GLfloat *)newMatrix
{
GLfloat tempMatrix[16];
//Column 1
tempMatrix[0] = (second[0] * first[0]) +
(second[4] * first[1]) +
(second[8] * first[2]) +
(second[12] * first[3]);
tempMatrix[1] = (second[1] * first[0]) +
(second[5] * first[1]) +
(second[9] * first[2]) +
(second[13] * first[3]);
tempMatrix[2] = (second[2] * first[0]) +
(second[6] * first[1]) +
(second[10] * first[2]) +
(second[14] * first[3]);
tempMatrix[3] = (second[3] * first[0]) +
(second[7] * first[1]) +
(second[11] * first[2]) +
(second[15] * first[3]);
//Column 2
tempMatrix[4] = (second[0] * first[4]) +
(second[4] * first[5]) +
(second[8] * first[6]) +
(second[12] * first[7]);
tempMatrix[5] = (second[1] * first[4]) +
(second[5] * first[5]) +
(second[9] * first[6]) +
(second[13] * first[7]);
tempMatrix[6] = (second[2] * first[4]) +
(second[6] * first[5]) +
(second[10] * first[6]) +
(second[14] * first[7]);
tempMatrix[7] = (second[3] * first[4]) +
(second[7] * first[5]) +
(second[11] * first[6]) +
(second[15] * first[7]);
//Column 3
tempMatrix[8] = (second[0] * first[8]) +
(second[4] * first[9]) +
(second[8] * first[10]) +
(second[12] * first[11]);
tempMatrix[9] = (second[1] * first[8]) +
(second[5] * first[9]) +
(second[9] * first[10]) +
(second[13] * first[11]);
tempMatrix[10] = (second[2] * first[8]) +
(second[6] * first[9]) +
(second[10] * first[10]) +
(second[14] * first[11]);
tempMatrix[11] = (second[3] * first[8]) +
(second[7] * first[9]) +
(second[11] * first[10]) +
(second[15] * first[11]);
//Column 4
tempMatrix[12] = (second[0] * first[12]) +
(second[4] * first[13]) +
(second[8] * first[14]) +
(second[12] * first[15]);
tempMatrix[13] = (second[1] * first[12]) +
(second[5] * first[13]) +
(second[9] * first[14]) +
(second[13] * first[15]);
tempMatrix[14] = (second[2] * first[12]) +
(second[6] * first[13]) +
(second[10] * first[14]) +
(second[14] * first[15]);
tempMatrix[15] = (second[3] * first[12]) +
(second[7] * first[13]) +
(second[11] * first[14]) +
(second[15] * first[15]);
[self copyMatrix:tempMatrix to:newMatrix];
}
- (void)applyTranslation:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
{
GLfloat tempMatrix[16];
[self setIdentity:tempMatrix];
tempMatrix[12] = x;
tempMatrix[13] = y;
tempMatrix[14] = z;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
- (void)applyScale:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
{
GLfloat tempMatrix[16];
[self setIdentity:tempMatrix];
tempMatrix[0] = x;
tempMatrix[5] = y;
tempMatrix[10] = z;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
- (void)applyRotation:(GLfloat *)source pitch:(GLfloat)pitch yaw:(GLfloat)yaw roll:(GLfloat)roll
{
GLfloat tempMatrix[16];
if (pitch != 0) {
GLfloat c = cosf(pitch);
GLfloat s = sinf(pitch);
[self setIdentity:tempMatrix];
tempMatrix[5] = c;
tempMatrix[6] = -s;
tempMatrix[9] = s;
tempMatrix[10] = c;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
if (yaw != 0) {
GLfloat c = cosf(yaw);
GLfloat s = sinf(yaw);
[self setIdentity:tempMatrix];
tempMatrix[0] = c;
tempMatrix[2] = s;
tempMatrix[8] = -s;
tempMatrix[10] = c;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
if (roll != 0) {
GLfloat c = cosf(roll);
GLfloat s = sinf(roll);
[self setIdentity:tempMatrix];
tempMatrix[0] = c;
tempMatrix[1] = -s;
tempMatrix[4] = s;
tempMatrix[5] = c;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
}
- (void)applyRotationWithMag:(GLfloat *)source angle:(GLfloat)angle magX:(GLfloat)magX magY:(GLfloat)magY magZ:(GLfloat)magZ
{
GLfloat tempMatrix[16];
GLfloat sinAngle, cosAngle;
GLfloat magnitude;
magnitude = sqrtf((magX * magX) + (magY * magY) + (magZ * magZ));
sinAngle = sinf(angle * PI/180.0f);
cosAngle = cosf(angle * PI/180.0f);
if (magnitude > 0) {
GLfloat xx, yy, zz, xy, xz, yz, xs, ys, zs;
GLfloat oneMinusCos;
magX /= magnitude;
magY /= magnitude;
magZ /= magnitude;
xx = magX * magX;
yy = magY * magY;
zz = magZ * magZ;
xy = magX * magY;
xz = magX * magZ;
yz = magY * magZ;
xs = magX * sinAngle;
ys = magY * sinAngle;
zs = magZ * sinAngle;
oneMinusCos = 1 - cosAngle;
tempMatrix[0] = (oneMinusCos * xx) + cosAngle;
tempMatrix[1] = (oneMinusCos * xy) - zs;
tempMatrix[2] = (oneMinusCos * xz) + ys;
tempMatrix[3] = 0;
tempMatrix[4] = (oneMinusCos * xy) + zs;
tempMatrix[5] = (oneMinusCos * yy) + cosAngle;
tempMatrix[6] = (oneMinusCos * yz) - xs;
tempMatrix[7] = 0;
tempMatrix[8] = (oneMinusCos * xz) - ys;
tempMatrix[9] = (oneMinusCos * yz) + xs;
tempMatrix[10] = (oneMinusCos * zz) + cosAngle;
tempMatrix[11] = 0;
tempMatrix[12] = 0;
tempMatrix[13] = 0;
tempMatrix[14] = 0;
tempMatrix[15] = 1;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
}
- (void)setProjection:(GLfloat *)source fov:(GLfloat)fov aspect:(GLfloat)aspect near:(GLfloat)near far:(GLfloat)far
{
GLfloat tempMatrix[16];
[self setIdentity:tempMatrix];
GLfloat r = fov * M_PI/180.0f;
GLfloat f = 1.0f/tanf(r/2.0f);
tempMatrix[0] = f;
tempMatrix[5] = f/aspect;
tempMatrix[10] = -(far + near)/(far - near);
tempMatrix[11] = -1;
tempMatrix[14] = -(2 * far * near)/(far - near);
tempMatrix[15] = 0;
[self multiplyMatrix:tempMatrix by:source giving:source];
}
@end
Scene.h
#import "Shader.h"
#import "Matrix.h"
@class Texture;
@interface Scene : NSObject {
Texture *texture;
GLuint textureName;
float animationPhase;
BOOL didShowInfo;
BOOL wireframe;
GLuint vaoID[1];
GLuint vboID[2];
GLuint programHandle;
GLuint shaderHandle[2];
GLuint ProjectionMatrixHandle, ViewMatrixHandle, ModelMatrixHandle;
GLfloat PerspectiveMat[16], ViewMat[16], ModelMat[16];
GLfloat updateValue;
Matrix *matrix;
Shader *shader;
}
- (id)init;
- (void)setViewportRect:(NSRect)bounds;
- (void)render;
- (void)advanceTimeBy:(float)seconds;
- (void)setAnimationPhase:(float)newAnimationPhase;
- (void)toggleWireframe;
@end
Scene.m(使用來自蘋果的全屏演示一些代碼)
#import "Scene.h"
static double dtor(double degrees)
{
return degrees * M_PI/180.0;
}
@implementation Scene
- (id) init
{
self = [super init];
if (self) {
wireframe = NO;
didShowInfo = NO;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CW);
GLfloat verts[32] =
{
-0.5, -0.5, -1.0, 1.0, 1.0f, 1.0f, 1.0f, 1.0f,
-0.5, 0.5, -1.0, 1.0, 1.0f, 1.0f, 1.0f, 1.0f,
0.5, 0.5, -1.0, 1.0, 1.0f, 1.0f, 1.0f, 1.0f,
0.5, -0.5, -1.0, 1.0, 1.0f, 1.0f, 1.0f, 1.0f
};
GLfloat indices[6] =
{
0, 1, 2,
0, 2, 3
};
[matrix setIdentity:ModelMat];
[matrix setIdentity:ViewMat];
NSLog(@"ModelMat:\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f", ModelMat[0], ModelMat[1], ModelMat[2], ModelMat[3], ModelMat[4], ModelMat[5], ModelMat[6], ModelMat[7], ModelMat[8], ModelMat[9], ModelMat[10], ModelMat[11], ModelMat[12], ModelMat[13], ModelMat[14], ModelMat[15]);
[matrix applyTranslation:ViewMat x:0 y:0 z:-2];
NSLog(@"ViewMat:\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f", ViewMat[0], ViewMat[1], ViewMat[2], ViewMat[3], ViewMat[4], ViewMat[5], ViewMat[6], ViewMat[7], ViewMat[8], ViewMat[9], ViewMat[10], ViewMat[11], ViewMat[12], ViewMat[13], ViewMat[14], ViewMat[15]);
programHandle = glCreateProgram();
shaderHandle[0] = [shader compileShader:@"shader.vert" ofType:GL_VERTEX_SHADER];
shaderHandle[1] = [shader compileShader:@"shader.frag" ofType:GL_FRAGMENT_SHADER];
glAttachShader(programHandle, shaderHandle[0]);
glAttachShader(programHandle, shaderHandle[1]);
glLinkProgram(programHandle);
ModelMatrixHandle = glGetUniformLocation(programHandle, "ModelMatrix");
ViewMatrixHandle = glGetUniformLocation(programHandle, "ViewMatrix");
ProjectionMatrixHandle = glGetUniformLocation(programHandle, "ProjectionMatrix");
glGenVertexArrays(1, &vaoID[0]);
glBindVertexArray(vaoID[0]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glGenBuffers(2, &vboID[0]);
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 4, GL_FLOAT, GL_FALSE, sizeof(verts[0]), 0);
glVertexAttribPointer((GLuint)1, 4, GL_FLOAT, GL_FALSE, sizeof(verts[0]), (GLvoid*)4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindVertexArray(0);
}
return self;
}
- (void)dealloc
{
[texture release];
[super dealloc];
}
- (void)advanceTimeBy:(float)seconds
{
float phaseDelta = seconds - floor(seconds);
float newAnimationPhase = animationPhase + 0.015625 * phaseDelta;
newAnimationPhase = newAnimationPhase - floor(newAnimationPhase);
[self setAnimationPhase:newAnimationPhase];
}
- (void)setAnimationPhase:(float)newAnimationPhase
{
animationPhase = newAnimationPhase;
}
- (void)toggleWireframe
{
wireframe = !wireframe;
}
- (void)setViewportRect:(NSRect)bounds
{
[matrix setIdentity:PerspectiveMat];
glViewport(0, 0, bounds.size.width, bounds.size.height);
[matrix setProjection:PerspectiveMat fov:60
aspect:(GLfloat)bounds.size.width/(GLfloat)bounds.size.height
near:1.0f far:100.0f];
}
- (void)render
{
updateValue += 0.015;
if (updateValue > 1)
updateValue = 0;
glClearColor(updateValue, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programHandle);
glUniformMatrix4fv(ModelMatrixHandle, 1, GL_FALSE, ModelMat);
glUniformMatrix4fv(ViewMatrixHandle, 1, GL_FALSE, ViewMat);
glUniformMatrix4fv(ProjectionMatrixHandle, 1, GL_FALSE, PerspectiveMat);
glBindVertexArray(vaoID[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (GLvoid*)0);
glBindVertexArray(0);
glUseProgram(0);
}
@end
是的,我知道有一個更簡單的方法來記錄它,我很急 – SonarSoundProgramming
告訴我們'ModelMat'的聲明。 –
你確定'矩陣'是一個實例嗎?由於您可以在Objective-C中將消息發送到'nil',您的呼叫可能未被執行。 – Macmade