SCNBook-code icon indicating copy to clipboard operation
SCNBook-code copied to clipboard

How to call glPointSize() (or the SceneKit equivalent) when making custom geometries using SceneKit and SCNGeometryPrimitiveTypePoint

Open abrahamavnisan opened this issue 9 years ago • 3 comments

I'm riffing off of Chapter 7, page 97 and have run into an issue I can't figure out. I've posted my question to SO as well, but will repost here. Thanks again for this great book @d-ronnqvist!

I'm writing an iOS app that renders a pointcloud in SceneKit using a custom geometry. This post was super helpful in getting me there (though I translated this to Objective-C), as was David Rönnqvist's book 3D Graphics with SceneKit (see chapter on custom geometries). The code works fine, but I'd like to make the points render at a larger point size - at the moment the points are super tiny.

According to the OpenGL docs, you can do this by calling glPointSize(). From what I understand, SceneKit is built on top of OpenGL so I'm hoping there is a way to access this function or do the equivalent using SceneKit. Any suggestions would be much appreciated!

My code is below. I've also posted a small example app on bitbucket accessible here.

// set the number of points
NSUInteger numPoints = 10000;

// set the max distance points
int randomPosUL = 2;
int scaleFactor = 10000; // because I want decimal points
                         // but am getting random values using arc4random_uniform

PointcloudVertex pointcloudVertices[numPoints];

for (NSUInteger i = 0; i < numPoints; i++) {

    PointcloudVertex vertex;

    float x = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));
    float y = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));
    float z = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));

    vertex.x = (x - randomPosUL * scaleFactor) / scaleFactor;
    vertex.y = (y - randomPosUL * scaleFactor) / scaleFactor;
    vertex.z = (z - randomPosUL * scaleFactor) / scaleFactor;

    vertex.r = arc4random_uniform(255) / 255.0;
    vertex.g = arc4random_uniform(255) / 255.0;
    vertex.b = arc4random_uniform(255) / 255.0;

    pointcloudVertices[i] = vertex;

    //        NSLog(@"adding vertex #%lu with position - x: %.3f y: %.3f z: %.3f | color - r:%.3f g: %.3f b: %.3f",
    //              (long unsigned)i,
    //              vertex.x,
    //              vertex.y,
    //              vertex.z,
    //              vertex.r,
    //              vertex.g,
    //              vertex.b);
}

// convert array to point cloud data (position and color)
NSData *pointcloudData = [NSData dataWithBytes:&pointcloudVertices length:sizeof(pointcloudVertices)];

// create vertex source
SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithData:pointcloudData
                                                                   semantic:SCNGeometrySourceSemanticVertex
                                                                vectorCount:numPoints
                                                            floatComponents:YES
                                                        componentsPerVector:3
                                                          bytesPerComponent:sizeof(float)
                                                                 dataOffset:0
                                                                 dataStride:sizeof(PointcloudVertex)];

// create color source
SCNGeometrySource *colorSource = [SCNGeometrySource geometrySourceWithData:pointcloudData
                                                                  semantic:SCNGeometrySourceSemanticColor
                                                               vectorCount:numPoints
                                                           floatComponents:YES
                                                       componentsPerVector:3
                                                         bytesPerComponent:sizeof(float)
                                                                dataOffset:sizeof(float) * 3
                                                                dataStride:sizeof(PointcloudVertex)];

// create element
SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:nil
                                                            primitiveType:SCNGeometryPrimitiveTypePoint
                                                           primitiveCount:numPoints
                                                            bytesPerIndex:sizeof(int)];

// create geometry
SCNGeometry *pointcloudGeometry = [SCNGeometry geometryWithSources:@[ vertexSource, colorSource ] elements:@[ element]];

// add pointcloud to scene
SCNNode *pointcloudNode = [SCNNode nodeWithGeometry:pointcloudGeometry];
[self.myView.scene.rootNode addChildNode:pointcloudNode];

abrahamavnisan avatar Jul 08 '16 00:07 abrahamavnisan

Pretty sure they’ve moved over to metal, especially on iOS. You may want to check on how to do it in Metal..

On Jul 7, 2016, at 5:45 PM, Abraham Avnisan [email protected] wrote:

I'm riffing off of Chapter 7, page 97 and have run into an issue I can't figure out. I've posted my question to SO http://stackoverflow.com/questions/38257339/how-to-call-glpointsize-or-the-scenekit-equivalent-when-making-custom-geomet as well, but will repost here. Thanks again for this great book @d-ronnqvist https://github.com/d-ronnqvist!

I'm writing an iOS app that renders a pointcloud in SceneKit using a custom geometry. This post http://stackoverflow.com/questions/32712268/how-to-use-scenekit-to-display-a-colorful-point-cloud-using-custom-scngeometry/38252032#38252032 was super helpful in getting me there (though I translated this to Objective-C), as was David Rönnqvist's book 3D Graphics with SceneKit http://scenekitbook.com/ (see chapter on custom geometries). The code works fine, but I'd like to make the points render at a larger point size - at the moment the points are super tiny.

According to the OpenGL docs, you can do this by calling glPointSize(). From what I understand, SceneKit is built on top of OpenGL so I'm hoping there is a way to access this function or do the equivalent using SceneKit. Any suggestions would be much appreciated!

My code is below. I've also posted a small example app on bitbucket accessible here https://bitbucket.org/abrahamavnisan/scenekitpointsize.

// set the number of points NSUInteger numPoints = 10000;

// set the max distance points int randomPosUL = 2; int scaleFactor = 10000; // because I want decimal points // but am getting random values using arc4random_uniform

PointcloudVertex pointcloudVertices[numPoints];

for (NSUInteger i = 0; i < numPoints; i++) {

PointcloudVertex vertex;

float x = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));
float y = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));
float z = (float)(arc4random_uniform(randomPosUL * 2 * scaleFactor));

vertex.x = (x - randomPosUL * scaleFactor) / scaleFactor;
vertex.y = (y - randomPosUL * scaleFactor) / scaleFactor;
vertex.z = (z - randomPosUL * scaleFactor) / scaleFactor;

vertex.r = arc4random_uniform(255) / 255.0;
vertex.g = arc4random_uniform(255) / 255.0;
vertex.b = arc4random_uniform(255) / 255.0;

pointcloudVertices[i] = vertex;

//        NSLog(@"adding vertex #%lu with position - x: %.3f y: %.3f z: %.3f | color - r:%.3f g: %.3f b: %.3f",
//              (long unsigned)i,
//              vertex.x,
//              vertex.y,
//              vertex.z,
//              vertex.r,
//              vertex.g,
//              vertex.b);

}

// convert array to point cloud data (position and color) NSData *pointcloudData = [NSData dataWithBytes:&pointcloudVertices length:sizeof(pointcloudVertices)];

// create vertex source SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithData:pointcloudData semantic:SCNGeometrySourceSemanticVertex vectorCount:numPoints floatComponents:YES componentsPerVector:3 bytesPerComponent:sizeof(float) dataOffset:0 dataStride:sizeof(PointcloudVertex)];

// create color source SCNGeometrySource *colorSource = [SCNGeometrySource geometrySourceWithData:pointcloudData semantic:SCNGeometrySourceSemanticColor vectorCount:numPoints floatComponents:YES componentsPerVector:3 bytesPerComponent:sizeof(float) dataOffset:sizeof(float) * 3 dataStride:sizeof(PointcloudVertex)];

// create element SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:nil primitiveType:SCNGeometryPrimitiveTypePoint primitiveCount:numPoints bytesPerIndex:sizeof(int)];

// create geometry SCNGeometry *pointcloudGeometry = [SCNGeometry geometryWithSources:@[ vertexSource, colorSource ] elements:@[ element]];

// add pointcloud to scene SCNNode *pointcloudNode = [SCNNode nodeWithGeometry:pointcloudGeometry]; [self.myView.scene.rootNode addChildNode:pointcloudNode]; — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/d-ronnqvist/SCNBook-code/issues/17, or mute the thread https://github.com/notifications/unsubscribe/ABmgOnWE9hN58WXXOOAwIGPc9WeDn91lks5qTZ2_gaJpZM4JHobX.

drwave avatar Jul 08 '16 00:07 drwave

Thanks for the prompt reply @drwave, I'll look into it and see what I can dig up!

abrahamavnisan avatar Jul 08 '16 00:07 abrahamavnisan

pointcloudGeometry.firstMaterial.shaderModifiers = [SCNShaderModifierEntryPoint.geometry: "gl_PointSize = 2.5;"] Worked for me in simulator, but on ios device I got "Big Green Flashing Pixels"

paulsoning avatar Jun 27 '17 17:06 paulsoning