2014-11-02 4 views
7

Я пытаюсь реплицировать эту форму изображения куба (с разрешения original creator) с использованием набора сюжетов.Ширина обводки с примитивным типом линии SceneKit

enter image description here

До сих пор, у меня есть код рисования для линий и вершин. Я не могу использовать изображение, потому что фон должен быть прозрачным.

Конкретно я пытаюсь решить прямо сейчас, как отредактировать ширину хода для элемента SCNGeometryPrimitiveType.Line.

Основным способом я создаю линии, как это:

private func squareVertices(length: Float) -> [SCNVector3] { 
    let m = length/Float(2) 

    let topLeft =  SCNVector3Make(-m-q, m+q, m+q) 
    let topRight =  SCNVector3Make(m+q, m+q, m+q) 
    let bottomLeft = SCNVector3Make(-m-q, -m-q, m+q) 
    let bottomRight = SCNVector3Make(m+q, -m-q, m+q) 

    return [topLeft, topRight, bottomLeft, bottomRight] 
} 

private func cubeFace() -> SCNGeometry { 

    let vertices : [SCNVector3] = squareVertices(l) 
    let geoSrc = SCNGeometrySource(vertices: UnsafePointer<SCNVector3>(vertices), count: vertices.count) 

    // index buffer 
    let idx1 : [Int32] = [0, 3] 
    let data1 = NSData(bytes: idx1, length: (sizeof(Int32) * idx1.count)) 
    let geoElements1 = SCNGeometryElement(data: data1, primitiveType: SCNGeometryPrimitiveType.Line, primitiveCount: idx1.count, bytesPerIndex: sizeof(Int32)) 

    let idx2 : [Int32] = [1, 2] 
    let data2 = NSData(bytes: idx2, length: (sizeof(Int32) * idx2.count)) 
    let geoElements2 = SCNGeometryElement(data: data2, primitiveType: SCNGeometryPrimitiveType.Line, primitiveCount: idx2.count, bytesPerIndex: sizeof(Int32)) 

    let geo = SCNGeometry(sources: [geoSrc], elements: [geoElements1, geoElements2]) 

    return geo 
} 

    private func setupFaceNodes() { 
    // sides 
    for i in 0..<4 { 
     let face = SCNNode(geometry: cubeFace()) 
     face.rotation = SCNVector4Make(0, 1, 0, Float(i) * Float(M_PI_2)) 
     rootNode.addChildNode(face) 
    } 
    // top/bottom 
    for i in [1, 3] { 
     let face = SCNNode(geometry: cubeFace()) 
     face.rotation = SCNVector4Make(1, 0, 0, Float(i) * Float(M_PI_2)) 
     rootNode.addChildNode(face) 
    } 
} 

У меня есть то, что выглядит, как это с правильной общей форме:

enter image description here

, но я не могу понять как увеличить ширину линий, создаваемых с помощью SceneKit. Как я могу это достичь?

Для интересующихся, here является образцом проекта.

ответ

8

SceneKit не обеспечивает контроль за этим. Однако SceneKit использует OpenGL ES, что и делает.

Когда вы рисуете GL в режиме GL_LINES, вызов glLineWidth меняет ширину линии. (Осторожно: аргумент в реальных пикселях, а не в точках UI-макета, поэтому вам понадобится большая ширина, чем вы могли бы подумать, если вы не хотите, чтобы на экране Retina были супертонкие линии волос.)

So , где вы называете это в своем приложении SceneKit? У вас есть несколько вариантов. В простой сцене, такой как ваш, где вы только делаете одну вещь, вы можете просто установить ее перед рендерингом сцены. Задайте delegate для просмотра, затем выполните renderer:willRenderSceneAtTime: и позвоните по телефону glLineWidth.

Однако рендеринг линии OpenGL довольно ограничен - если вы хотите настроить рендеринг больше, вам понадобится другой подход. Просто какой подход лучше всего работает, зависит от того, что вы собираетесь, так что здесь несколько идей для вас исследование:

  • Сделайте свою «линию» из узких треугольных полос
  • сделать их от примитивного геометрического SCN как коробки и цилиндры
  • Ведите простую геометрию куба, но и использовать фрагмент шейдеров (или шейдера модификатор сниппет) рисовать только вблизи краев каждого полигона
+0

«Ведите простую геометрию куба, но и использовать фрагмент шейдеров (или фрагмент модификатора шейдера), чтобы рисовать только рядом с краями каждого многоугольника «Как было бы u делать это с помощью фрагментарного шейдера?Не проблема ли рисования каркасов с более сложными решениями шейдеров? [Шейдер каркасного каркаса] (http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/) – tsp

+0

Это может быть более сложным, но также обеспечивает большую гибкость. нечеткие/светящиеся края. И в зависимости от ваших потребностей вам не нужно передавать другой атрибут (источник геометрии в SceneKit) по конвейеру для барицентрических коордов - если вы хотите выделить края квадроцикла, забудьте, что это фактически два треугольника и просто посмотрите на texcoords. (Предполагая, что ваши texcoords настроены для перехода на квад.) – rickster

+0

Я пробовал этот подход, добавляя вызов glLineWidth в методе делегата, и он работает на симуляторе, но не влияет на устройство. Вы видели такое же поведение? Странно, что если я использую GLES напрямую вместо SceneKit, я могу заставить glLineWidth работать с устройством с довольно толстыми линиями. – eddy

3

Вы можете использовать glLineWidth для установки ширины линии.
Обязательно включите OpenGLES в свой проект.

Line Width 8

Вот как ваш куб выглядит с ширина линии устанавливается на 8.

Смежные вопросы