microsoft / HoloJS

Provides a framework for creating holographic apps using JavaScript and WebGL.
MIT License
1.19k stars 114 forks source link

THREE.Line support #31

Closed nsipplswezey closed 7 years ago

nsipplswezey commented 7 years ago

Hey HoloJS maintainers. I'm trying to build some lines. I'm starthing with this simple snippet for lines in THREE.js: https://threejs.org/docs/api/objects/Line.html

And then converting it into BufferGeometry

    var material = new THREE.LineBasicMaterial({
        color: 0x0000ff
    });
    var geometry = new THREE.BufferGeometry();
    var vertices = new Float32Array( [
        -10.0, 0.0,  0.0,
        0.0, -10.0,  0.0,
        10.0,  0.0,  0.0,
    ] )

    geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) )

    var line = new THREE.Line( geometry,  );
    line.name = "LINE";
    scene.add( line );

Works just fine in a Fiddle both in Chrome and Edge.

https://jsfiddle.net/epr46k0z/1/

But fails in HoloJS.

I'm working with the demo ThreeJS example included in the repo, so I've got the sphere, camera and point light objects. Removed the others for simplicity. And I'm logging the different objects in the .updateMatrixWorld() method that starts at line 11028 in the THREE.js release provided in the repo, and it looks like the issue occurs after updating the last of the 4 objects, or before the next update of the line object.

log: update children
log: LINE
log: update children
log: SPHERE
log: update children
log: CAMERA
log: update children
log: POINT
D3D11 ERROR: ID3D11Device::CreateVertexShader: Shader uses ability to feed viewport and/or array index from any shader feeding the rasterizer, but the device does not support this. To check for support, check device caps via the CheckFeatureSupport() API [ STATE_CREATION ERROR #166: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
Exception thrown at 0x77222052 in ThreeJSApp.exe: Microsoft C++ exception: _com_error at memory location 0x01ED8990.
D3D11 ERROR: ID3D11Device::CreateVertexShader: Shader uses ability to feed viewport and/or array index from any shader feeding the rasterizer, but the device does not support this. To check for support, check device caps via the CheckFeatureSupport() API [ STATE_CREATION ERROR #166: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
Exception thrown at 0x77222052 in ThreeJSApp.exe: Microsoft C++ exception: _com_error at memory location 0x01ED8990.
Exception thrown at 0x77222052 in ThreeJSApp.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x01EDA534.
Failure in file c:\users\nick sippl\desktop\projects\holojs\holojs\holojshost\objectevents.h, line 52
Failure in file c:\users\nick sippl\desktop\projects\holojs\holojs\holojshost\windowelement.cpp, line 149
Failure in file c:\users\nick sippl\desktop\projects\holojs\holojs\holojshost\windowelement.cpp, line 149

I also noticed this note in the three.js docs https://threejs.org/docs/api/materials/LineBasicMaterial.html

.linewidth

Controls line thickness. Default is 1.

Due to limitations in the ANGLE layer, with the WebGL renderer on Windows platforms linewidth will always be 1 regardless of the set value.

Which doesn't explain the issue as far as I can tell... but does allude to some specifics of ANGLE. I'm going to dive into https://github.com/Microsoft/angle/tree/88a9dfb0dcaa57f7be41dda39bde901b21b67364/samples a bit to see if I can get a better sense of what's going on, but seems like Line geometries ought to be supported.

PepsRyuu commented 7 years ago

Hey Nick!

I had an issue as well before rendering wireframes, and if I recall correctly, it was because the "lineWidth" function was not implemented. Despite the width always being 1, THREE.js still tries to call it from the JavaScript each time it renders a frame. So because of that, you're seeing the "Failure in file ... windowelement.cpp". It's possible to get more descriptive error messages by modifying the JsCallFunction and JsRunScript calls (here's a sample with exception handling).

Below is what I done to implement the lineWidth function. It's basically a copy and paste of the other functions just changing the name to lineWidth and calling the glLineWidth function in the actual implementation.

WebGL.js

this.lineWidth = function (width) {
    return nativeInterface.webgl.lineWidth(this.glContext, width);
};

WebGLProjections.cpp

RETURN_IF_FALSE(ScriptHostUtilities::ProjectFunction(L"lineWidth", L"webgl", lineWidth));

JsValueRef
CHAKRA_CALLBACK
WebGLProjections::lineWidth(
    JsValueRef callee,
    bool isConstructCall,
    JsValueRef* arguments,
    unsigned short argumentCount,
    PVOID callbackData
)
{
    RETURN_INVALID_REF_IF_FALSE(argumentCount == 3);

    WebGLRenderingContext* context = ScriptResourceTracker::ExternalToObject<WebGLRenderingContext>(arguments[1]);
    RETURN_INVALID_REF_IF_NULL(context);

    GLfloat width = ScriptHostUtilities::GLfloatFromJsRef(arguments[2]);
    context->lineWidth(width);

    return JS_INVALID_REFERENCE;
}

WebGLProjections.h

static JsValueRef CHAKRA_CALLBACK lineWidth(
    JsValueRef callee,
    bool isConstructCall,
    JsValueRef* arguments,
    unsigned short argumentCount,
    PVOID callbackData
);

WebGLRenderingContext.cpp

void WebGLRenderingContext::lineWidth(GLfloat width) {
    glLineWidth(width);
 }

WebGLRenderingContext.h

void lineWidth(GLfloat width);

Hope this helps!

Almost-Done commented 7 years ago

@PepsRyuu Thank you for the fix! It would be great to merge this into the master branch. Do you want to submit a pull request for it? Alternatively I could merge the fix myself.

PepsRyuu commented 7 years ago

@Almost-Done I don't mind writing a few pull requests, just wasn't sure if the project was still alive! There was a few things I wanted to contribute (proper error logging, mapping surface data to JS, and other various bug fixes). Some of these were based on issue #24. There's huge potential for this project as a platform, so if I get a chance I'll see what I can do. :)

nsipplswezey commented 7 years ago

@Almost-Done @PepsRyuu Great to see life in this thread! Personally, error logging would be a great step forward, I'm sure along with @PepsRyuu other intended contributions. Would love to come back around to building with HoloJS. Agree that there's potential for this project as a platform.

Almost-Done commented 7 years ago

I created a PR with Paul's code from above to resolve this issue.