我正在制作一个简单的游戏并遇到了问题。 我收到了这个错误:
重复符号_vertices: / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/ViewController.o / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/Block.o 重复符号_indices: / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/ViewController.o / Users / - / Library / Developer / Xcode / DerivedData / WorkingTitle_skeleton-gcgtpewqagbzyxbauptoayplozbs / Build / Intermediates / WorkingTitle skeleton.build/Debug-iphonesimulator/WorkingTitle skeleton.build/Objects-normal/i386/Block.o ld:2个用于体系结构i386的重复符号 clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)
我尝试过开始一个新项目并再次尝试,但还没有任何工作。 我有一个C ++背景,有点刚刚跳进Objective-C,所以可能就是这样。
这是我的代码:
ViewController.m:
#import "ViewController.h"
@interface ViewController () {
Block *testBlock;
}
@property (strong, nonatomic) EAGLContext *context;
- (void)setupGL;
- (void)teardownGL;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableMultisample = GLKViewDrawableMultisample4X;
view.drawableStencilFormat = GLKViewDrawableStencilFormatNone;
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[EAGLContext setCurrentContext:self.context];
self.preferredFramesPerSecond = 60;
self.pauseOnWillResignActive = YES;
self.resumeOnDidBecomeActive = NO;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:tapGesture];
[self setupGL];
}
- (void)dealloc
{
[self teardownGL];
if ([EAGLContext currentContext] == self.context)
[EAGLContext setCurrentContext:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && ([[self view] window] == nil))
self.view = nil;
[self teardownGL];
if ([EAGLContext currentContext] == self.context)
[EAGLContext setCurrentContext:nil];
self.context = nil;
// Dispose of any resources that can be recreated.
}
- (void)setupGL
{
[EAGLContext setCurrentContext:self.context];
testBlock = [[Block alloc] initWithType:BT_STONE andAccessory:BA_NONE];
}
- (void)teardownGL
{
[EAGLContext setCurrentContext:self.context];
[testBlock tearDown];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.paused = !self.paused;
}
- (void)handleTapGesture:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateRecognized) {
}
}
#pragma mark - GLKView and GLKViewController delegate methods
- (void)update
{
aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
timeSinceLastUpdate = self.timeSinceLastUpdate;
[testBlock update];
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
[testBlock draw];
}
@end
Defines.h:
#import <Foundation/Foundation.h>
#import <GLKit/GLKit.h>
enum BlockType {
BT_NONE,
BT_AIR,
BT_GRASS,
BT_DIRT,
BT_STONE,
BT_WATER,
BT_SNOW,
BT_WOOD,
BT_LEAVES,
BT_SAND,
BT_GRAVEL
};
enum BlockAccessory {
BA_NONE,
BA_LADDER,
BA_SNOW
};
enum Biome {
BI_SNOWY,
BI_PLAINS,
BI_BEACH,
BI_DESERT,
BI_FOREST,
BI_SAVANNA,
};
typedef enum BlockType BlockType;
typedef enum BlockAccessory BlockAccessory;
typedef enum Biome Biome;
typedef struct
{
GLKVector3 positionCoordinates;
GLKVector4 colorRGBA;
GLKVector2 textCoord;
GLKVector3 vertNorm;
} VertexData;
float aspect;
NSTimeInterval timeSinceLastUpdate;
VertexData vertices[] = {
// Front
{{1, -1, 1}, {1, 0, 0, 1}, {1, 0}, {0, 0, 1}},
{{1, 1, 1}, {0, 1, 0, 1}, {1, 1}, {0, 0, 1}},
{{-1, 1, 1}, {0, 0, 1, 1}, {0, 1}, {0, 0, 1}},
{{-1, -1, 1}, {0, 0, 0, 1}, {0, 0}, {0, 0, 1}},
// Back
{{1, 1, -1}, {1, 0, 0, 1}, {0, 1}, {0, 0, -1}},
{{-1, -1, -1}, {0, 1, 0, 1}, {1, 0}, {0, 0, -1}},
{{1, -1, -1}, {0, 0, 1, 1}, {0, 0}, {0, 0, -1}},
{{-1, 1, -1}, {0, 0, 0, 1}, {1, 1}, {0, 0, -1}},
// Left
{{-1, -1, 1}, {1, 0, 0, 1}, {1, 0}, {-1, 0, 0}},
{{-1, 1, 1}, {0, 1, 0, 1}, {1, 1}, {-1, 0, 0}},
{{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}, {-1, 0, 0}},
{{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}, {-1, 0, 0}},
// Right
{{1, -1, -1}, {1, 0, 0, 1}, {1, 0}, {1, 0, 0}},
{{1, 1, -1}, {0, 1, 0, 1}, {1, 1}, {1, 0, 0}},
{{1, 1, 1}, {0, 0, 1, 1}, {0, 1}, {1, 0, 0}},
{{1, -1, 1}, {0, 0, 0, 1}, {0, 0}, {1, 0, 0}},
// Top
{{1, 1, 1}, {1, 0, 0, 1}, {1, 0}, {0, 1, 0}},
{{1, 1, -1}, {0, 1, 0, 1}, {1, 1}, {0, 1, 0}},
{{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}, {0, 1, 0}},
{{-1, 1, 1}, {0, 0, 0, 1}, {0, 0}, {0, 1, 0}},
// Bottom
{{1, -1, -1}, {1, 0, 0, 1}, {1, 0}, {0, -1, 0}},
{{1, -1, 1}, {0, 1, 0, 1}, {1, 1}, {0, -1, 0}},
{{-1, -1, 1}, {0, 0, 1, 1}, {0, 1}, {0, -1, 0}},
{{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}, {0, -1, 0}}
};
GLubyte indices[] = {
0, 1, 2,
2, 3, 0,
// Back
4, 6, 5,
4, 5, 7,
// Left
8, 9, 10,
10, 11, 8,
// Right
12, 13, 14,
14, 15, 12,
// Top
16, 17, 18,
18, 19, 16,
// Bottom
20, 21, 22,
22, 23, 20
};
Block.h:
#import <Foundation/Foundation.h>
#import "Defines.h"
@interface Block : NSObject
{
}
- (id)init;
- (id)initWithType:(BlockType)blockTypee andAccessory:(BlockAccessory)blockAccessorye;
- (void)setupEverythingElse;
- (void)setupVBOs;
- (void)draw;
- (void)update;
- (void)tearDown;
@end
Block.m:
#import "Block.h"
@interface Block ()
{
BlockType blockType;
BlockAccessory blockAccessory;
GLuint _vertexBuffer;
GLuint _indexBuffer;
GLuint _vertexArray;
float _rotation;
}
@property (strong, nonatomic) GLKBaseEffect *effect;
@end
@implementation Block
- (id)init
{
self = [super init];
if (self) {
blockType = BT_NONE;
blockAccessory = BA_NONE;
}
return self;
}
- (id)initWithType:(BlockType)blockTypee andAccessory:(BlockAccessory)blockAccessorye
{
self = [super init];
if (self) {
blockType = blockTypee;
blockAccessory = blockAccessorye;
}
return self;
}
- (void)dealloc
{
[self tearDown];
}
- (void)tearDown
{
glDeleteBuffers(1, &_vertexBuffer);
glDeleteBuffers(1, &_indexBuffer);
self.effect = nil;
}
- (void)setupEverythingElse
{
glEnable(GL_CULL_FACE);
self.effect = [[GLKBaseEffect alloc] init];
self.effect.colorMaterialEnabled = NO;
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft: @YES};
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
GLKTextureInfo *info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if (info == nil)
NSLog(@"Error loading file: %@", [error localizedDescription]);
self.effect.texture2d0.name = info.name;
self.effect.texture2d0.enabled = true;
// Setup texture 2 if necessary (like a ladder on this block)
[self setupVBOs];
}
- (void)setupVBOs
{
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, positionCoordinates));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, colorRGBA));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, textCoord));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) offsetof(VertexData, vertNorm));
glBindVertexArrayOES(0);
}
- (void)draw
{
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_TRIANGLES, (sizeof(indices) / sizeof(indices[0])), GL_UNSIGNED_BYTE, 0);
// Draw VertexData array
}
- (void)update
{
// Setup texture 2 if necessary (like a ladder on this block)
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 10.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f);
_rotation = 90 * timeSinceLastUpdate;
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(25), 1, 0, 0);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 1, 0);
self.effect.transform.modelviewMatrix = modelViewMatrix;
}
@end
抱歉这么长时间。感谢您阅读所有内容,或尽可能多地阅读。如果您需要更多详细信息,请告诉我。
答案 0 :(得分:5)
您可能忘记添加所需的Frameworks
找到您需要导入和添加的框架,就像在屏幕截图
中一样错过的框架可能会OpenGLES.framework
尝试将其添加为下面的图片中
请参阅下面的图片
如果您对添加框架仍有任何疑问,请继续link
答案 1 :(得分:1)
您的“define.h”文件包含vertices
和indices
的实际符号定义,而不仅仅是声明。任何在多个编译单元中导入/包含该文件的尝试都将导致重复的符号。
您需要将实际代码生成部分移动到实现文件而不是标题。