【发布时间】:2011-04-06 12:18:09
【问题描述】:
我最近开始学习编程以在 iPhone 上制作我自己的 3D OpenGL 游戏,并且到目前为止取得了相当不错的进展。我开始使用 iPhone SDK 提供的基本 OpenGL 示例,它帮助我有了一个良好的开端。然而,当我开始掌握事情的窍门时,我突然想到我在 Objective C 中进行了不必要的编程,这将使将来将游戏移植到其他平台变得更加困难。所以我想现在最好把它变成正确的 C++ 以避免以后做很多额外的工作。
澄清一下:我实际上并没有使用任何对 Apple(Objective C)函数或任何东西的调用,只是我所有的类都基于 Objective C 风格的 init/dealloc/etc,所以我的引擎使用时看起来像 Objective C 类。我的目标是用 C++ 等价物替换所有客观的 C 东西......问题是,对于 C++ 来说还很新,我不确定什么对应于什么!
这是我的一个类 (myLight) 的一个简单示例,在其当前的 Objective C 化身中:
// myLight.h
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
@interface myLight : NSObject {
char *name;
GLfloat *ambient, *diffuse, *specular, *position, *spotDirection;
GLfloat spotRadius;
GLfloat *matAmbient, *matDiffuse, *matSpecular;
GLfloat shininess;
Byte lightType;
}
@property (readonly) char *name;
@property (assign) GLfloat *position;
@property (assign) GLfloat *spotDirection;
@property (assign) GLfloat *ambient;
@property (assign) GLfloat *diffuse;
@property (assign) GLfloat *specular;
- (id)initWithContentsFromDatastream:(NSData *)fileData;
- (void)set;
@end
以及对应的.mm文件:
// myLight.m
#import "myLight.h"
@implementation myLight
@synthesize name, ambient, diffuse, specular, position, spotDirection;
- (id)initWithContentsFromDatastream:(NSData *)fileData {
self = [super init];
NSData *fileContents = fileData;
uint ptr = 0;
Byte nameLength;
[fileContents getBytes:&nameLength range: NSMakeRange(ptr, sizeof(Byte))];
ptr++;
name = new char[nameLength];
[fileContents getBytes:name range: NSMakeRange(ptr, (nameLength * sizeof(char)) )];
ptr = ptr + (nameLength * sizeof(char) );
[fileContents getBytes:&lightType range: NSMakeRange(ptr, sizeof(Byte))];
ptr++;
position = new GLfloat[4];
for(int j = 0; j < (4); j++)
[fileContents getBytes:&position[j] range: NSMakeRange( (j* sizeof(float) ) + ptr, sizeof(float))];
ptr = ptr + (4 * sizeof(float));
if(lightType==2){
spotDirection = new GLfloat[3];
for(int j = 0; j < (3); j++)
[fileContents getBytes:&spotDirection[j] range: NSMakeRange( (j* sizeof(float) ) + ptr, sizeof(float))];
ptr = ptr + (3 * sizeof(float));
[fileContents getBytes:&spotRadius range: NSMakeRange(ptr, sizeof(float))];
ptr = ptr + sizeof(float);
} else
spotDirection = NULL;
diffuse = new GLfloat[4];
for(int j = 0; j < (4); j++)
[fileContents getBytes:&diffuse[j] range: NSMakeRange( (j* sizeof(float) ) + ptr, sizeof(float))];
ptr = ptr + (4 * sizeof(float));
ambient = new GLfloat[4];
for(int j = 0; j < (4); j++)
[fileContents getBytes:&ambient[j] range: NSMakeRange( (j* sizeof(float) ) + ptr, sizeof(float))];
ptr = ptr + (4 * sizeof(float));
specular = new GLfloat[4];
for(int j = 0; j < (4); j++)
[fileContents getBytes:&specular[j] range: NSMakeRange( (j* sizeof(float) ) + ptr, sizeof(float))];
ptr = ptr + (4 * sizeof(float));
[self set];
return self;
}
- (void)set{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_POSITION, position);
if(lightType==2)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection);
}
- (void)dealloc {
delete[] specular;
delete[] ambient;
delete[] diffuse;
if (spotDirection)
delete[] spotDirection;
delete[] position;
delete[] name;
[super dealloc];
}
@end
如果有人能指出需要更改哪些行,更重要的是,应该将它们更改为什么以使其编译为纯 C++,我将不胜感激。
非常感谢!
【问题讨论】:
-
Err... 对于很多这样的事情,没有没有 C++ 等价物。 IE。 “属性”两者的对象模型完全不同。
-
这几乎是不可能的。 iPhone 使用 Objective-C 作为所有 iPhone 应用程序的 GUI 框架,用 C++ 替换它是不可能的,因为没有 C++ 替代 GUI 框架,因此你不会有任何图形。但这样做实际上使代码更容易移植到其他平台,因为 GUI 代码很容易与底层引擎(希望用 C++ 编写)区分开来。所以你只需要为你必须做的每个平台重新编写 GUI。
Note: easier not easy. -
Billy 是对的,但要更进一步:标题的几乎每一行都需要更改,并且您的实现文件也有相当一部分。 C++ 和 Objective-C 有非常不同的语法。不过,程序逻辑(例如
if(lightType==2))和对 OpenGL 的调用(例如glEnable(GL_LIGHTING))都可以,因为它们是纯 C 语言,通常直接转换为 C++。 -
是的,我最初确实低估了任务的范围,因为我可能确实认为有些事情会更加一对一地等效。也就是说,我很确定它不会“几乎不可能”......只是不像我希望的那么容易!不管怎样,谢谢你的建议,不胜感激。
标签: c++ iphone objective-c xcode