Массивы Objective-C и переменные класса - PullRequest
0 голосов
/ 04 сентября 2010

Я портирую приложение для Android, которое я сделал, на iPhone и сталкиваюсь с проблемами с синтаксисом (я думаю)

Я основываю проект на примере с http://iphonedevelopment.blogspot.com/2009/04/opengl-es-from-ground-up-part-2-look-at.html

Я хотел бы извлечь геометрию из процесса рендеринга, чтобы сохранить код модульным, но я не могу заставить его работать.Я создал класс под названием Icosahedron (комментарии - мое понимание того, что происходит) Icosahedron.h

#import <Foundation/Foundation.h>
#import "OpenGLCommon.h"



@interface Icosahedron : NSObject {
 Vertex3D *vertices[12]; //allocate a group of 12 Vertex3D pointers
 Vertex3D *normals[12]; // ditto
 GLubyte *faces[60]; // ditto but with 60 face values
}

// Declare methods
-(Vertex3D *) vertices; 
-(void) setVertices:(Vector3D *)setVerts; 

-(Vertex3D *) normals;
-(void) setNormals:(Vector3D *)setNorms;

-(GLubyte *) faces;
-(void) setFaces:(GLubyte *)setFaces;

@end

Icosahedron.m

#import "Icosahedron.h"


@implementation Icosahedron

// Returns the pointer to the vertices instance variable
-(Vector3D *) vertices{
 return *vertices;
}

-(void) setVertices:(Vector3D *)setVerts
{
 //vertices=setVerts[0];
}

-(Vector3D *) normals{
 return *normals;
}

-(void) setNormals:(Vector3D *)setNorms
{
 //normals=setNorms;
}

-(GLubyte *) faces{
 return *faces;
}

-(void) setFaces:(GLubyte *)setFaces
{
 //faces=setFaces;
}
/**/
-(id)init
{
 // super method
 self=[super init];

    // create 12 Vector3D objects and populate them...
 Vector3D tempVert[12]={
        {0, -0.525731, 0.850651},             // vertices[0]
        {0.850651, 0, 0.525731},              // vertices[1]
        {0.850651, 0, -0.525731},             // vertices[2]
        {-0.850651, 0, -0.525731},            // vertices[3]
        {-0.850651, 0, 0.525731},             // vertices[4]
        {-0.525731, 0.850651, 0},             // vertices[5]
        {0.525731, 0.850651, 0},              // vertices[6]
        {0.525731, -0.850651, 0},             // vertices[7]
        {-0.525731, -0.850651, 0},            // vertices[8]
        {0, -0.525731, -0.850651},            // vertices[9]
        {0, 0.525731, -0.850651},             // vertices[10]
        {0, 0.525731, 0.850651}               // vertices[11]
    };
    // same...
 Vector3D tempNorm[12]={
        {0.000000, -0.417775, 0.675974},
        {0.675973, 0.000000, 0.417775},
        {0.675973, -0.000000, -0.417775},
        {-0.675973, 0.000000, -0.417775},
        {-0.675973, -0.000000, 0.417775},
        {-0.417775, 0.675974, 0.000000},
        {0.417775, 0.675973, -0.000000},
        {0.417775, -0.675974, 0.000000},
        {-0.417775, -0.675974, 0.000000},
        {0.000000, -0.417775, -0.675973},
        {0.000000, 0.417775, -0.675974},
        {0.000000, 0.417775, 0.675973},
    };


 // face values
 GLubyte tempFaces[60]={
        1, 2, 6,
        1, 7, 2,
        3, 4, 5,
        4, 3, 8,
        6, 5, 11,
        5, 6, 10,
        9, 10, 2,
        10, 9, 3,
        7, 8, 9,
        8, 7, 0,
        11, 0, 1,
        0, 11, 4,
        6, 2, 10,
        1, 6, 11,
        3, 5, 10,
        5, 4, 11,
        2, 7, 9,
        7, 1, 0,
        3, 9, 8,
        4, 8, 0,
    };

   // set the instance pointers to the temp values
 *vertices=tempVert;
 *normals=tempNorm;
 *faces=tempFaces;

, на данный момент значения НЕ правильныезаполнено, только первое значение является правильным.

 return self;

}

@end

Все, что я хочу сделать, - это иметь возможность вызывать что-то вроде

...
ico=[[Icosahedron alloc] init];
glVertexPointer(3, GL_FLOAT, 0, [ico vertices]);
...

в секции рендеринга, но это самое дальнее, что яя смог установить первое значение Vertex3D внутри класса Icosahedron, и я получаю «out of scope» в отладчике для любого значения Icosahedron в классе рендеринга.

Я подозреваю, что этотолько я изучаю причуды Objective-C, но я пробовал много разных подходов в течение нескольких дней, и ничто, кажется, никуда меня не привело.

Пожалуйста, помогите мне Переполнение-Ван, ты моя единственная надежда.

Ответы [ 3 ]

2 голосов
/ 04 сентября 2010

Вы перепутали свои указатели и массивы.Вы бы хотели что-то вроде этого:

Vertex3D vertices[12];

- (void) setVertices: (Vertex3D *)newVertices;
{
    memcpy( vertices, newVertices, 12 * sizeof( Vertex3D ) );
}

- (Vertex3D *) vertices;
{
    return vertices;
}

Для копирования массивов в C вы должны использовать memcpy (или рукописный цикл), вы не можете сделать это с помощью оператора присваивания.

2 голосов
/ 04 сентября 2010

Во-первых, вы, кажется, используете "Vertex3D" и "Vector3D" взаимозаменяемо.Я не знаю, действительно ли это проблема ...

Я думаю, что массивы следует объявлять как массивы значений, а не как массивы указателей.Итак ...

Vertex3D vertices[12]; //allocate a group of 12 Vertex3D pointers
Vertex3D normals[12]; // ditto
GLubyte faces[60]; // ditto but with 60 face values

Таким образом, у вас есть место для всех значений, а не только для указателей на другие векторы (которые вы не распределили).

В общем, типичныйпоследовательность инициализации:

-(id)init
{
    if (self = [super init])
    {
         //do initialization stuff
    }
    return self;
}

Более аккуратно обрабатывает ошибки.

1 голос
/ 04 сентября 2010

Ваши объявления vertices, normals и faces относятся к массивам указателей на соответствующие объекты.В то время как кажется, что вы действительно хотите иметь массивы самих структур / ценностей.Поэтому ваш интерфейс должен сказать:

Vertex3D vertices[12];
Vertex3D normals[12];
GLubyte faces[60];

В этом случае вашему объекту будет принадлежать кусок памяти, содержащий 12 вершин, 12 нормалей и 60 граней (в любом случае, независимо от того, какие это значения - GLubyte).1010 *

Указатели и массивы вроде взаимозаменяемы в C / Objective-C.Таким образом, vertices и normals также могут рассматриваться как Vertex3D* значения, а faces - как GLubyte*, и они могут передаваться как таковые функциям, которые хотят эти типы.

ToПоясните, что к чему, было бы лучше иметь начальные значения в виде отдельных static const массивов на верхнем уровне вашего файла реализации, а затем скопировать эти значения в массивы, принадлежащие объекту, во время инициализации.Вы можете сделать это несколькими способами, но, возможно, самый простой - использовать memcpy, как в ответ Свена .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...