Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8217472: Add attenuation for PointLight #43

Open
wants to merge 11 commits into
base: master
from
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,12 @@ protected NGNode createPeerImpl(Node node) {
return pointLightAccessor.doCreatePeer(node);
}

@Override
protected void updatePeerImpl(Node node) {
super.updatePeerImpl(node);
pointLightAccessor.doUpdatePeer(node);
}

public static void setPointLightAccessor(final PointLightAccessor newAccessor) {
if (pointLightAccessor != null) {
throw new IllegalStateException();
@@ -66,7 +72,6 @@ public static void setPointLightAccessor(final PointLightAccessor newAccessor) {

public interface PointLightAccessor {
NGNode doCreatePeer(Node node);
void doUpdatePeer(Node node);
}

}

}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,93 @@
package com.sun.javafx.sg.prism;

/**
* TODO: 3D - Need documentation
* The peer of the {@code PointLight} class. Holds the default values of {@code PointLight}'s
* properties and updates the visuals via {@link NGNode#visualsChanged} when one of the current
* values changes. The peer receives its changes by {@code PointLight.doUpdatePeer} calls.
*/
public class NGPointLight extends NGLightBase {

/** Constant attenuation factor default value */
private static final float DEFAULT_CA = 1;
/** Linear attenuation factor default value */
private static final float DEFAULT_LA = 0;
/** Quadratic attenuation factor default value */
private static final float DEFAULT_QA = 0;
/** Max range default value */
private static final float DEFAULT_MAX_RANGE = Float.POSITIVE_INFINITY;

This conversation was marked as resolved by kevinrushforth

This comment has been minimized.

Copy link
@arapte

arapte Jan 3, 2020

Will it be a good idea to move these constants to PointLight class?
However they look good here too.

This comment has been minimized.

Copy link
@nlisker

nlisker Jan 3, 2020

Author Contributor

If they are in PointLight it will be difficult for the peer to access them (will need to do through the accessor). Also, the parent NGLightBase holds the defaults for color and lightOn.

public NGPointLight() {
}

}
public static float getDefaultCa() {
return DEFAULT_CA;
}

public static float getDefaultLa() {
return DEFAULT_LA;
}

public static float getDefaultQa() {
return DEFAULT_QA;
}

public static float getDefaultMaxRange() {
return DEFAULT_MAX_RANGE;
}


private float ca = DEFAULT_CA;

public float getCa() {
return ca;
}

public void setCa(float ca) {
if (this.ca != ca) {
this.ca = ca;
visualsChanged();
}
}


private float la = DEFAULT_LA;

public float getLa() {
return la;
}

public void setLa(float la) {
if (this.la != la) {
this.la = la;
visualsChanged();
}
}


private float qa = DEFAULT_QA;

public float getQa() {
return qa;
}

public void setQa(float qa) {
if (this.qa != qa) {
this.qa = qa;
visualsChanged();
}
}


private float maxRange = DEFAULT_MAX_RANGE;

public float getMaxRange() {
return maxRange;
}

public void setMaxRange(float maxRange) {
if (this.maxRange != maxRange) {
this.maxRange = maxRange < 0 ? 0 : maxRange;
visualsChanged();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -109,14 +109,18 @@ private void renderMeshView(Graphics g) {
int pointLightIdx = 0;
if (g.getLights() == null || g.getLights()[0] == null) {
// If no lights are in scene apply default light. Default light
// is a single point white point light at camera eye position.
// is a single white point light at camera eye position.
meshView.setAmbientLight(0.0f, 0.0f, 0.0f);
Vec3d cameraPos = g.getCameraNoClone().getPositionInWorld(null);
meshView.setPointLight(pointLightIdx++,
(float)cameraPos.x,
(float)cameraPos.y,
(float)cameraPos.z,
1.0f, 1.0f, 1.0f, 1.0f);
1.0f, 1.0f, 1.0f, 1.0f,
NGPointLight.getDefaultCa(),
NGPointLight.getDefaultLa(),
NGPointLight.getDefaultQa(),
NGPointLight.getDefaultMaxRange());
} else {
float ambientRed = 0.0f;
float ambientBlue = 0.0f;
@@ -132,7 +136,7 @@ private void renderMeshView(Graphics g) {
float gL = lightBase.getColor().getGreen();
float bL = lightBase.getColor().getBlue();
/* TODO: 3D
* There is a limit on the number of lights that can affect
* There is a limit on the number of point lights that can affect
* a 3D shape. (Currently we simply select the first 3)
* Thus it is important to select the most relevant lights.
*
@@ -155,7 +159,11 @@ private void renderMeshView(Graphics g) {
(float)lightWT.getMxt(),
(float)lightWT.getMyt(),
(float)lightWT.getMzt(),
rL, gL, bL, 1.0f);
rL, gL, bL, 1.0f,
light.getCa(),
light.getLa(),
light.getQa(),
light.getMaxRange());
}
} else if (lightBase instanceof NGAmbientLight) {
// Accumulate ambient lights
@@ -173,7 +181,10 @@ private void renderMeshView(Graphics g) {
// TODO: 3D Required for D3D implementation of lights, which is limited to 3
while (pointLightIdx < 3) {
// Reset any previously set lights
meshView.setPointLight(pointLightIdx++, 0, 0, 0, 0, 0, 0, 0);
meshView.setPointLight(pointLightIdx++,
0, 0, 0, // x y z
0, 0, 0, 0, // r g b w
1, 0, 0, 0); // ca la qa maxRange
}

meshView.render(g);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,8 @@

public void setPointLight(int index,
float x, float y, float z,
float r, float g, float b, float w);
float r, float g, float b, float w,
float ca, float la, float qa, float maxRange);

public void render(Graphics g);
}
@@ -426,7 +426,8 @@ private static native void nSetWireframe(long pContext, long nativeMeshView,
private static native void nSetAmbientLight(long pContext, long nativeMeshView,
float r, float g, float b);
private static native void nSetPointLight(long pContext, long nativeMeshView,
int index, float x, float y, float z, float r, float g, float b, float w);
int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange);
private static native void nRenderMeshView(long pContext, long nativeMeshView);
private static native int nDrawIndexedQuads(long pContext,
float coords[], byte colors[], int numVertices);
@@ -551,8 +552,9 @@ void setAmbientLight(long nativeMeshView, float r, float g, float b) {
nSetAmbientLight(pContext, nativeMeshView, r, g, b);
}

void setPointLight(long nativeMeshView, int index, float x, float y, float z, float r, float g, float b, float w) {
nSetPointLight(pContext, nativeMeshView, index, x, y, z, r, g, b, w);
void setPointLight(long nativeMeshView, int index, float x, float y, float z,
float r, float g, float b, float w, float ca, float la, float qa, float maxRange) {
nSetPointLight(pContext, nativeMeshView, index, x, y, z, r, g, b, w, ca, la, qa, maxRange);
}

@Override
@@ -81,10 +81,11 @@ public void setAmbientLight(float r, float g, float b) {
}

@Override
public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w) {
public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange) {
// NOTE: We only support up to 3 point lights at the present
if (index >= 0 && index <= 2) {
context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w, ca, la, qa, maxRange);
}
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -449,8 +449,9 @@ void setAmbientLight(long nativeHandle, float r, float g, float b) {
glContext.setAmbientLight(nativeHandle, r, g, b);
}

void setPointLight(long nativeHandle, int index, float x, float y, float z, float r, float g, float b, float w) {
glContext.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
void setPointLight(long nativeHandle, int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange) {
glContext.setPointLight(nativeHandle, index, x, y, z, r, g, b, w, ca, la, qa, maxRange);
}

@Override
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,14 +32,19 @@

float x, y, z = 0;
float r, g, b, w = 1;
float ca, la, qa, maxRange;

ES2Light(float ix, float iy, float iz, float ir, float ig, float ib, float iw) {
ES2Light(float ix, float iy, float iz, float ir, float ig, float ib, float iw, float ca, float la, float qa, float maxRange) {
x = ix;
y = iy;
z = iz;
r = ir;
g = ig;
b = ib;
w = iw;
this.ca = ca;
this.la = la;
this.qa = qa;
this.maxRange = maxRange;
}
}
@@ -101,11 +101,12 @@ float getAmbientLightBlue() {
}

@Override
public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w) {
public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange) {
// NOTE: We only support up to 3 point lights at the present
if (index >= 0 && index <= 2) {
lights[index] = new ES2Light(x, y, z, r, g, b, w);
context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
lights[index] = new ES2Light(x, y, z, r, g, b, w, ca, la, qa, maxRange);
context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w, ca, la, qa, maxRange);
}
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -204,10 +204,12 @@ static void setShaderParamaters(ES2Shader shader, ES2MeshView meshView, ES2Conte
meshView.getAmbientLightGreen(), meshView.getAmbientLightBlue());

int i = 0;
for(ES2Light light : meshView.getPointLights()) {
for (ES2Light light : meshView.getPointLights()) {
if (light != null && light.w > 0) {
shader.setConstant("lights[" + i + "].pos", light.x, light.y, light.z, light.w);
shader.setConstant("lights[" + i + "].color", light.r, light.g, light.b);
shader.setConstant("lights[" + i + "].attn", light.ca, light.la, light.qa);
shader.setConstant("lights[" + i + "].range", light.maxRange);
i++;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -252,7 +252,8 @@ private static native void nSetWireframe(long nativeCtxInfo, long nativeMeshView
private static native void nSetAmbientLight(long nativeCtxInfo, long nativeMeshViewInfo,
float r, float g, float b);
private static native void nSetPointLight(long nativeCtxInfo, long nativeMeshViewInfo,
int index, float x, float y, float z, float r, float g, float b, float w);
int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange);
private static native void nRenderMeshView(long nativeCtxInfo, long nativeMeshViewInfo);
private static native void nBlit(long nativeCtxInfo, int srcFBO, int dstFBO,
int srcX0, int srcY0, int srcX1, int srcY1,
@@ -808,8 +809,9 @@ void setAmbientLight(long nativeMeshViewInfo, float r, float g, float b) {
nSetAmbientLight(nativeCtxInfo, nativeMeshViewInfo, r, g, b);
}

void setPointLight(long nativeMeshViewInfo, int index, float x, float y, float z, float r, float g, float b, float w) {
nSetPointLight(nativeCtxInfo, nativeMeshViewInfo, index, x, y, z, r, g, b, w);
void setPointLight(long nativeMeshViewInfo, int index, float x, float y, float z, float r, float g, float b, float w,
float ca, float la, float qa, float maxRange) {
nSetPointLight(nativeCtxInfo, nativeMeshViewInfo, index, x, y, z, r, g, b, w, ca, la, qa, maxRange);
}

void renderMeshView(long nativeMeshViewInfo) {
@@ -44,8 +44,10 @@
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
@@ -277,6 +279,20 @@ void scenesChanged(final Scene newScene, final SubScene newSubScene,
}
}

/**
* For use by implementing subclasses. Treat as protected.
*
* Creates and returns a SimpleDoubleProperty with an invalidation scheme.
*/
DoubleProperty getLightDoubleProperty(String name, double initialValue) {
return new SimpleDoubleProperty(this, name, initialValue) {
@Override
protected void invalidated() {
NodeHelper.markDirty(LightBase.this, DirtyBits.NODE_LIGHT);
}
};
}

private void markOwnerDirty() {
// if the light is part of the scene/subScene, we will need to notify
// the owner to mark the entire scene/subScene dirty.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.