SceneKit中的iOS自定义几何体

SceneKit中的iOS自定义几何体,ios,objective-c,scenekit,Ios,Objective C,Scenekit,我在尝试在iOS模拟器上运行带有纹理贴图的简单四边形时遇到困难。我已经阅读了关于这里的所有其他问题,这些问题涉及类似的事情,我被卡住了。输出如下所示: 纹理是这样的: // v1 +----+ v0 // | | // v2 +----+ v3 SCNVector3 vertices[] = { SCNVector3Make( 5.0, 5.0, 0.0), SCNVector3Make( -5.0,

我在尝试在iOS模拟器上运行带有纹理贴图的简单四边形时遇到困难。我已经阅读了关于这里的所有其他问题,这些问题涉及类似的事情,我被卡住了。输出如下所示:

纹理是这样的:

  // v1 +----+ v0
  //    |    |
  // v2 +----+ v3



  SCNVector3 vertices[] = { SCNVector3Make(  5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0, -5.0, 0.0),
                            SCNVector3Make(  5.0, -5.0, 0.0)
  };

  SCNVector3 normals[] = { SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0)
  };

  CGPoint textureCoordinates[] = { CGPointMake( 1.0, 1.0),
                                   CGPointMake( 0.0, 1.0),
                                   CGPointMake( 0.0, 0.0),
                                   CGPointMake( 1.0, 0.0)
  };

  NSUInteger vertexCount = 4;


  NSMutableData *indicesData = [NSMutableData data];
  UInt8 indices[] = { 0, 1, 2, 0, 2, 3};
  [indicesData appendBytes:indices length:sizeof(UInt8)*6];
  SCNGeometryElement *indicesElement = [SCNGeometryElement geometryElementWithData:indicesData
                                                                     primitiveType:SCNGeometryPrimitiveTypeTriangles
                                                                    primitiveCount:2
                                                                     bytesPerIndex:sizeof(UInt8)];

  NSMutableData *vertexData = [NSMutableData dataWithBytes:vertices length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *verticesSource = [SCNGeometrySource geometrySourceWithData:vertexData
                                                                       semantic:SCNGeometrySourceSemanticVertex
                                                                    vectorCount:vertexCount
                                                                floatComponents:YES
                                                            componentsPerVector:3
                                                              bytesPerComponent:sizeof(float)
                                                                     dataOffset:0
                                                                     dataStride:sizeof(SCNVector3)];

  NSMutableData *normalData = [NSMutableData dataWithBytes:normals length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *normalsSource = [SCNGeometrySource geometrySourceWithData:normalData
                                                                      semantic:SCNGeometrySourceSemanticNormal
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:3
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(SCNVector3)];

  NSMutableData *textureData = [NSMutableData dataWithBytes:textureCoordinates length:vertexCount * sizeof(CGPoint)];

  SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:textureData
                                                                      semantic:SCNGeometrySourceSemanticTexcoord
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:2
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(CGPoint)];
 SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[verticesSource, normalsSource, textureSource]
                                                  elements:@[indicesElement]];


  SCNMaterial *material = [SCNMaterial material];
  //material.diffuse.contents = [UIColor redColor];
  material.diffuse.contents = [UIImage imageNamed:@"diffuse.jpg"];
  material.diffuse.wrapS = SCNWrapModeRepeat;
  material.diffuse.wrapT = SCNWrapModeRepeat;
  material.diffuse.contentsTransform = SCNMatrix4MakeScale( 1.0f, 1.0f, 1.0f);
  material.doubleSided = YES;

  material.normal.wrapS = SCNWrapModeRepeat;
  material.normal.wrapT = SCNWrapModeRepeat;
  //    material.litPerPixel = YES;

  geometry.materials = @[material];

我的代码是:

  // v1 +----+ v0
  //    |    |
  // v2 +----+ v3



  SCNVector3 vertices[] = { SCNVector3Make(  5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0, -5.0, 0.0),
                            SCNVector3Make(  5.0, -5.0, 0.0)
  };

  SCNVector3 normals[] = { SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0)
  };

  CGPoint textureCoordinates[] = { CGPointMake( 1.0, 1.0),
                                   CGPointMake( 0.0, 1.0),
                                   CGPointMake( 0.0, 0.0),
                                   CGPointMake( 1.0, 0.0)
  };

  NSUInteger vertexCount = 4;


  NSMutableData *indicesData = [NSMutableData data];
  UInt8 indices[] = { 0, 1, 2, 0, 2, 3};
  [indicesData appendBytes:indices length:sizeof(UInt8)*6];
  SCNGeometryElement *indicesElement = [SCNGeometryElement geometryElementWithData:indicesData
                                                                     primitiveType:SCNGeometryPrimitiveTypeTriangles
                                                                    primitiveCount:2
                                                                     bytesPerIndex:sizeof(UInt8)];

  NSMutableData *vertexData = [NSMutableData dataWithBytes:vertices length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *verticesSource = [SCNGeometrySource geometrySourceWithData:vertexData
                                                                       semantic:SCNGeometrySourceSemanticVertex
                                                                    vectorCount:vertexCount
                                                                floatComponents:YES
                                                            componentsPerVector:3
                                                              bytesPerComponent:sizeof(float)
                                                                     dataOffset:0
                                                                     dataStride:sizeof(SCNVector3)];

  NSMutableData *normalData = [NSMutableData dataWithBytes:normals length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *normalsSource = [SCNGeometrySource geometrySourceWithData:normalData
                                                                      semantic:SCNGeometrySourceSemanticNormal
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:3
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(SCNVector3)];

  NSMutableData *textureData = [NSMutableData dataWithBytes:textureCoordinates length:vertexCount * sizeof(CGPoint)];

  SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:textureData
                                                                      semantic:SCNGeometrySourceSemanticTexcoord
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:2
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(CGPoint)];
 SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[verticesSource, normalsSource, textureSource]
                                                  elements:@[indicesElement]];


  SCNMaterial *material = [SCNMaterial material];
  //material.diffuse.contents = [UIColor redColor];
  material.diffuse.contents = [UIImage imageNamed:@"diffuse.jpg"];
  material.diffuse.wrapS = SCNWrapModeRepeat;
  material.diffuse.wrapT = SCNWrapModeRepeat;
  material.diffuse.contentsTransform = SCNMatrix4MakeScale( 1.0f, 1.0f, 1.0f);
  material.doubleSided = YES;

  material.normal.wrapS = SCNWrapModeRepeat;
  material.normal.wrapT = SCNWrapModeRepeat;
  //    material.litPerPixel = YES;

  geometry.materials = @[material];
[编辑]我用这段代码尝试了许多不同的方法,但似乎没有任何效果。我还没有在Objective-C中看到一个可以在iOS上运行的示例。对material.diffuse.wrapps的任何更改均无效


我以前在OpenGL中做过这样的事情,没有任何问题,但我已经盯着这段代码看了好几天,看不出我的错误。非常感谢您的帮助。

@Paul Jan让我走上了正确的道路,这让我找到了以下答案:

将我的纹理坐标从CGPoint更改为float可以修复它

  float textureCoordinates[] = {  1.0, 1.0,
                                  0.0, 1.0,
                                  0.0, 0.0,
                                  1.0, 0.0
  };

  NSMutableData *textureData = [NSMutableData dataWithBytes:textureCoordinates length:vertexCount * sizeof(float) * 2];

  SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:textureData
                                                                      semantic:SCNGeometrySourceSemanticTexcoord
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:2
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(float) * 2];
结果:


在64位iOS上,CGFloat不是双精度的吗?您为textureSource的
byesPerComponent
指定sizeof(float)。很遗憾,没有区别,只是尝试了一下。谢谢您的快速回复。@Paul Jan请看下面我的答案,当我尝试您的建议时,我只在textureSource中更改了它,而没有在textureData中更改。再看一次,两个地方都变了,结果都成功了。如果你想把它写下来作为答案,我会接受,否则我会接受我自己的答案。这将给Paul Jan一个机会,让他先写下他的评论作为答案。请接受你自己的答案,你做了所有艰苦的工作,现在你的问答为知识的堆积如山增添了一笔:)