TranslucentBucket :
- Added a translucent bucket that is rendered after the processors (usefull for shadows) - For filters, rendering this bucket is a bit particular, so you can use the TranslucentBucketFilter to render the translucent bucket in the middle of the fillter stack (doc is comming up in the wiki) - renamed Filter's preRender method to postQueue for consistancy with processors - added translucent objects in TestPostWater, added a fire (particles) in test transparent shadows git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7540 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
29a4e7e01c
commit
2d4896942d
@ -1259,6 +1259,9 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
|
||||||
logger.warning("copyFrameBuffer is not supported.");
|
logger.warning("copyFrameBuffer is not supported.");
|
||||||
}
|
}
|
||||||
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth){
|
||||||
|
logger.warning("copyFrameBuffer is not supported.");
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
|
||||||
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit){
|
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit){
|
||||||
|
@ -5,7 +5,6 @@ attribute vec2 inTexCoord;
|
|||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 pos = (g_WorldViewProjectionMatrix * inPosition).xy;
|
gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);
|
||||||
gl_Position = vec4(pos, 0.0, 1.0);
|
|
||||||
texCoord = inTexCoord;
|
texCoord = inTexCoord;
|
||||||
}
|
}
|
@ -85,7 +85,7 @@ public abstract class Filter implements Savable {
|
|||||||
} else {
|
} else {
|
||||||
renderFrameBuffer = new FrameBuffer(width, height, 1);
|
renderFrameBuffer = new FrameBuffer(width, height, 1);
|
||||||
renderedTexture = new Texture2D(width, height, textureFormat);
|
renderedTexture = new Texture2D(width, height, textureFormat);
|
||||||
// depthTexture = new Texture2D(width, height, depthBufferFormat);
|
// depthTexture = new Texture2D(width, height, depthBufferFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFrameBuffer.setColorTexture(renderedTexture);
|
renderFrameBuffer.setColorTexture(renderedTexture);
|
||||||
@ -200,7 +200,7 @@ public abstract class Filter implements Savable {
|
|||||||
* @param renderManager
|
* @param renderManager
|
||||||
* @param viewPort
|
* @param viewPort
|
||||||
*/
|
*/
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,6 +211,14 @@ public abstract class Filter implements Savable {
|
|||||||
public void preFrame(float tpf) {
|
public void preFrame(float tpf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method if you want to make a pass just after the frame has been rendered and just before the filter rendering
|
||||||
|
* @param renderManager
|
||||||
|
* @param viewPort
|
||||||
|
*/
|
||||||
|
public void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method if you want to save extra properties when the filter is saved else only basic properties of the filter will be saved
|
* Override this method if you want to save extra properties when the filter is saved else only basic properties of the filter will be saved
|
||||||
* This method should always begin by super.write(ex);
|
* This method should always begin by super.write(ex);
|
||||||
@ -268,6 +276,14 @@ public abstract class Filter implements Savable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method and return false if your Filter does not need the scene texture
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isRequiresSceneTexture() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Pass> getPostRenderPasses() {
|
public List<Pass> getPostRenderPasses() {
|
||||||
return postRenderPasses;
|
return postRenderPasses;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import com.jme3.export.InputCapsule;
|
|||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
import com.jme3.export.Savable;
|
import com.jme3.export.Savable;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.post.filters.TranslucentBucketFilter;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.renderer.Caps;
|
import com.jme3.renderer.Caps;
|
||||||
import com.jme3.renderer.RenderManager;
|
import com.jme3.renderer.RenderManager;
|
||||||
@ -80,6 +81,10 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
private int originalHeight;
|
private int originalHeight;
|
||||||
private int lastFilterIndex = -1;
|
private int lastFilterIndex = -1;
|
||||||
private boolean cameraInit = false;
|
private boolean cameraInit = false;
|
||||||
|
// private boolean handleTranslucentBucket = false;
|
||||||
|
// private FrameBuffer transFrameBuffer;
|
||||||
|
// private Material transMaterial;
|
||||||
|
// private boolean isTransparencyRendered=false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a FilterProcessor constructor
|
* Create a FilterProcessor constructor
|
||||||
@ -159,8 +164,9 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
filterCam.resize(buff.getWidth(), buff.getHeight(), true);
|
filterCam.resize(buff.getWidth(), buff.getHeight(), true);
|
||||||
fsQuad.setPosition(0, 0);
|
fsQuad.setPosition(0, 0);
|
||||||
}
|
}
|
||||||
|
if (mat.getAdditionalRenderState().isDepthWrite()) {
|
||||||
|
mat.getAdditionalRenderState().setDepthWrite(false);
|
||||||
|
}
|
||||||
fsQuad.setMaterial(mat);
|
fsQuad.setMaterial(mat);
|
||||||
fsQuad.updateGeometricState();
|
fsQuad.updateGeometricState();
|
||||||
|
|
||||||
@ -179,14 +185,16 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
for (Iterator<Filter> it = filters.iterator(); it.hasNext();) {
|
for (Iterator<Filter> it = filters.iterator(); it.hasNext();) {
|
||||||
Filter filter = it.next();
|
Filter filter = it.next();
|
||||||
if (filter.isEnabled()) {
|
if (filter.isEnabled()) {
|
||||||
filter.preRender(renderManager, viewPort);
|
filter.postQueue(renderManager, viewPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Picture pic = new Picture("debug");
|
||||||
|
|
||||||
public void renderFilterChain(Renderer r) {
|
public void renderFilterChain(Renderer r, FrameBuffer sceneFb) {
|
||||||
Texture2D tex = filterTexture;
|
Texture2D tex = filterTexture;
|
||||||
|
FrameBuffer buff = null;
|
||||||
boolean msDepth = depthTexture != null && depthTexture.getImage().getMultiSamples() > 1;
|
boolean msDepth = depthTexture != null && depthTexture.getImage().getMultiSamples() > 1;
|
||||||
for (int i = 0; i < filters.size(); i++) {
|
for (int i = 0; i < filters.size(); i++) {
|
||||||
Filter filter = filters.get(i);
|
Filter filter = filters.get(i);
|
||||||
@ -216,22 +224,27 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter.postFrame(renderManager, viewPort, buff, sceneFb);
|
||||||
|
|
||||||
Material mat = filter.getMaterial();
|
Material mat = filter.getMaterial();
|
||||||
if (msDepth && filter.isRequiresDepthTexture()) {
|
if (msDepth && filter.isRequiresDepthTexture()) {
|
||||||
mat.setInt("NumSamplesDepth", depthTexture.getImage().getMultiSamples());
|
mat.setInt("NumSamplesDepth", depthTexture.getImage().getMultiSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.isRequiresSceneTexture()) {
|
||||||
mat.setTexture("Texture", tex);
|
mat.setTexture("Texture", tex);
|
||||||
if (tex.getImage().getMultiSamples() > 1) {
|
if (tex.getImage().getMultiSamples() > 1) {
|
||||||
mat.setInt("NumSamples", tex.getImage().getMultiSamples());
|
mat.setInt("NumSamples", tex.getImage().getMultiSamples());
|
||||||
} else {
|
} else {
|
||||||
mat.clearParam("NumSamples");
|
mat.clearParam("NumSamples");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FrameBuffer buff = outputBuffer;
|
buff = outputBuffer;
|
||||||
if (i != lastFilterIndex) {
|
if (i != lastFilterIndex) {
|
||||||
buff = filter.getRenderFrameBuffer();
|
buff = filter.getRenderFrameBuffer();
|
||||||
tex = filter.getRenderedTexture();
|
tex = filter.getRenderedTexture();
|
||||||
|
|
||||||
}
|
}
|
||||||
renderProcessing(r, buff, mat);
|
renderProcessing(r, buff, mat);
|
||||||
}
|
}
|
||||||
@ -240,11 +253,13 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
|
|
||||||
public void postFrame(FrameBuffer out) {
|
public void postFrame(FrameBuffer out) {
|
||||||
|
|
||||||
|
FrameBuffer sceneBuffer = renderFrameBuffer;
|
||||||
if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL31)) {
|
if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL31)) {
|
||||||
renderer.copyFrameBuffer(renderFrameBufferMS, renderFrameBuffer);
|
renderer.copyFrameBuffer(renderFrameBufferMS, renderFrameBuffer);
|
||||||
|
} else if (renderFrameBufferMS != null) {
|
||||||
|
sceneBuffer = renderFrameBufferMS;
|
||||||
}
|
}
|
||||||
renderFilterChain(renderer);
|
renderFilterChain(renderer, sceneBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +351,6 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
renderFrameBufferMS.setColorTexture(msColor);
|
renderFrameBufferMS.setColorTexture(msColor);
|
||||||
filterTexture = msColor;
|
filterTexture = msColor;
|
||||||
depthTexture = msDepth;
|
depthTexture = msDepth;
|
||||||
// samplePositions = ((LwjglRenderer) renderer).getFrameBufferSamplePositions(renderFrameBufferMS);
|
|
||||||
} else {
|
} else {
|
||||||
renderFrameBufferMS.setDepthBuffer(Format.Depth);
|
renderFrameBufferMS.setDepthBuffer(Format.Depth);
|
||||||
renderFrameBufferMS.setColorBuffer(Format.RGBA8);
|
renderFrameBufferMS.setColorBuffer(Format.RGBA8);
|
||||||
@ -420,4 +434,12 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
|||||||
numSamples = ic.readInt("numSamples", 0);
|
numSamples = ic.readInt("numSamples", 0);
|
||||||
filters = ic.readSavableArrayList("filters", null);
|
filters = ic.readSavableArrayList("filters", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Texture2D getDepthTexture() {
|
||||||
|
return depthTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture2D getFilterTexture() {
|
||||||
|
return filterTexture;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@ public class RenderManager {
|
|||||||
camLoc = new Vector3f();
|
camLoc = new Vector3f();
|
||||||
//temp technique
|
//temp technique
|
||||||
private String tmpTech;
|
private String tmpTech;
|
||||||
|
private boolean handleTranlucentBucket = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a high-level rendering interface over the
|
* Create a high-level rendering interface over the
|
||||||
@ -607,6 +608,13 @@ public class RenderManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void renderTranslucentQueue(ViewPort vp) {
|
||||||
|
RenderQueue rq = vp.getQueue();
|
||||||
|
if (!rq.isQueueEmpty(Bucket.Translucent) && handleTranlucentBucket) {
|
||||||
|
rq.renderQueue(Bucket.Translucent, this, vp.getCamera(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setViewPort(Camera cam) {
|
private void setViewPort(Camera cam) {
|
||||||
// this will make sure to update viewport only if needed
|
// this will make sure to update viewport only if needed
|
||||||
if (cam != prevCam || cam.isViewportChanged()) {
|
if (cam != prevCam || cam.isViewportChanged()) {
|
||||||
@ -729,7 +737,8 @@ public class RenderManager {
|
|||||||
proc.postFrame(vp.getOutputFrameBuffer());
|
proc.postFrame(vp.getOutputFrameBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//renders the translucent objects queue after processors have been rendered
|
||||||
|
renderTranslucentQueue(vp);
|
||||||
// clear any remaining spatials that were not rendered.
|
// clear any remaining spatials that were not rendered.
|
||||||
clearQueue(vp);
|
clearQueue(vp);
|
||||||
}
|
}
|
||||||
@ -768,4 +777,12 @@ public class RenderManager {
|
|||||||
public void setAlphaToCoverage(boolean value) {
|
public void setAlphaToCoverage(boolean value) {
|
||||||
renderer.setAlphaToCoverage(value);
|
renderer.setAlphaToCoverage(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHandleTranslucentBucket() {
|
||||||
|
return handleTranlucentBucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandleTranslucentBucket(boolean handleTranslucentBucket) {
|
||||||
|
this.handleTranlucentBucket = handleTranslucentBucket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.renderer;
|
package com.jme3.renderer;
|
||||||
|
|
||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
@ -138,6 +137,12 @@ public interface Renderer {
|
|||||||
*/
|
*/
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst);
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies contents from src to dst, scaling if neccessary.
|
||||||
|
* set copyDepth to false ton ly copy the color
|
||||||
|
*/
|
||||||
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the framebuffer that will be drawn to.
|
* Sets the framebuffer that will be drawn to.
|
||||||
*/
|
*/
|
||||||
@ -212,5 +217,4 @@ public interface Renderer {
|
|||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
public void setAlphaToCoverage(boolean value);
|
public void setAlphaToCoverage(boolean value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.renderer.queue;
|
package com.jme3.renderer.queue;
|
||||||
|
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
@ -42,28 +41,33 @@ public class RenderQueue {
|
|||||||
private GeometryList opaqueList;
|
private GeometryList opaqueList;
|
||||||
private GeometryList guiList;
|
private GeometryList guiList;
|
||||||
private GeometryList transparentList;
|
private GeometryList transparentList;
|
||||||
|
private GeometryList translucentList;
|
||||||
private GeometryList skyList;
|
private GeometryList skyList;
|
||||||
private GeometryList shadowRecv;
|
private GeometryList shadowRecv;
|
||||||
private GeometryList shadowCast;
|
private GeometryList shadowCast;
|
||||||
|
|
||||||
public RenderQueue(){
|
public RenderQueue() {
|
||||||
this.opaqueList = new GeometryList(new OpaqueComparator());
|
this.opaqueList = new GeometryList(new OpaqueComparator());
|
||||||
this.guiList = new GeometryList(new GuiComparator());
|
this.guiList = new GeometryList(new GuiComparator());
|
||||||
this.transparentList = new GeometryList(new TransparentComparator());
|
this.transparentList = new GeometryList(new TransparentComparator());
|
||||||
|
this.translucentList = new GeometryList(new TransparentComparator());
|
||||||
this.skyList = new GeometryList(new NullComparator());
|
this.skyList = new GeometryList(new NullComparator());
|
||||||
this.shadowRecv = new GeometryList(new OpaqueComparator());
|
this.shadowRecv = new GeometryList(new OpaqueComparator());
|
||||||
this.shadowCast = new GeometryList(new OpaqueComparator());
|
this.shadowCast = new GeometryList(new OpaqueComparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Bucket {
|
public enum Bucket {
|
||||||
|
|
||||||
Gui,
|
Gui,
|
||||||
Opaque,
|
Opaque,
|
||||||
Sky,
|
Sky,
|
||||||
Transparent,
|
Transparent,
|
||||||
|
Translucent,
|
||||||
Inherit,
|
Inherit,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ShadowMode {
|
public enum ShadowMode {
|
||||||
|
|
||||||
Off,
|
Off,
|
||||||
Cast,
|
Cast,
|
||||||
Receive,
|
Receive,
|
||||||
@ -89,6 +93,8 @@ public class RenderQueue {
|
|||||||
* by material first and front to back within the same material.
|
* by material first and front to back within the same material.
|
||||||
* <li>Bucket.Transparent: {@link com.jme3.renderer.queue.TransparentComparator} which
|
* <li>Bucket.Transparent: {@link com.jme3.renderer.queue.TransparentComparator} which
|
||||||
* sorts purely back to front by leading bounding edge with no material sort.
|
* sorts purely back to front by leading bounding edge with no material sort.
|
||||||
|
* <li>Bucket.Translucent: {@link com.jme3.renderer.queue.TransparentComparator} which
|
||||||
|
* sorts purely back to front by leading bounding edge with no material sort. this bucket is rendered after post processors.
|
||||||
* <li>Bucket.Sky: {@link com.jme3.renderer.queue.NullComparator} which does no sorting
|
* <li>Bucket.Sky: {@link com.jme3.renderer.queue.NullComparator} which does no sorting
|
||||||
* at all.
|
* at all.
|
||||||
* <li>Bucket.Gui: {@link com.jme3.renderer.queue.GuiComparator} sorts geometries back to
|
* <li>Bucket.Gui: {@link com.jme3.renderer.queue.GuiComparator} sorts geometries back to
|
||||||
@ -108,15 +114,20 @@ public class RenderQueue {
|
|||||||
case Transparent:
|
case Transparent:
|
||||||
transparentList = new GeometryList(c);
|
transparentList = new GeometryList(c);
|
||||||
break;
|
break;
|
||||||
|
case Translucent:
|
||||||
|
translucentList = new GeometryList(c);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown bucket type: "+bucket);
|
throw new UnsupportedOperationException("Unknown bucket type: " + bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToShadowQueue(Geometry g, ShadowMode shadBucket){
|
public void addToShadowQueue(Geometry g, ShadowMode shadBucket) {
|
||||||
switch (shadBucket){
|
switch (shadBucket) {
|
||||||
case Inherit: break;
|
case Inherit:
|
||||||
case Off: break;
|
break;
|
||||||
|
case Off:
|
||||||
|
break;
|
||||||
case Cast:
|
case Cast:
|
||||||
shadowCast.add(g);
|
shadowCast.add(g);
|
||||||
break;
|
break;
|
||||||
@ -128,7 +139,7 @@ public class RenderQueue {
|
|||||||
shadowRecv.add(g);
|
shadowRecv.add(g);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unrecognized shadow bucket type: "+shadBucket);
|
throw new UnsupportedOperationException("Unrecognized shadow bucket type: " + shadBucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,13 +157,16 @@ public class RenderQueue {
|
|||||||
case Transparent:
|
case Transparent:
|
||||||
transparentList.add(g);
|
transparentList.add(g);
|
||||||
break;
|
break;
|
||||||
|
case Translucent:
|
||||||
|
translucentList.add(g);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown bucket type: "+bucket);
|
throw new UnsupportedOperationException("Unknown bucket type: " + bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeometryList getShadowQueueContent(ShadowMode shadBucket){
|
public GeometryList getShadowQueueContent(ShadowMode shadBucket) {
|
||||||
switch (shadBucket){
|
switch (shadBucket) {
|
||||||
case Cast:
|
case Cast:
|
||||||
return shadowCast;
|
return shadowCast;
|
||||||
case Receive:
|
case Receive:
|
||||||
@ -162,30 +176,32 @@ public class RenderQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderGeometryList(GeometryList list, RenderManager rm, Camera cam, boolean clear){
|
private void renderGeometryList(GeometryList list, RenderManager rm, Camera cam, boolean clear) {
|
||||||
list.setCamera(cam); // select camera for sorting
|
list.setCamera(cam); // select camera for sorting
|
||||||
list.sort();
|
list.sort();
|
||||||
for (int i = 0; i < list.size(); i++){
|
for (int i = 0; i < list.size(); i++) {
|
||||||
Spatial obj = list.get(i);
|
Spatial obj = list.get(i);
|
||||||
assert obj != null;
|
assert obj != null;
|
||||||
if (obj instanceof Geometry){
|
if (obj instanceof Geometry) {
|
||||||
Geometry g = (Geometry) obj;
|
Geometry g = (Geometry) obj;
|
||||||
rm.renderGeometry(g);
|
rm.renderGeometry(g);
|
||||||
// make sure to reset queue distance
|
// make sure to reset queue distance
|
||||||
}
|
}
|
||||||
if (obj != null)
|
if (obj != null) {
|
||||||
obj.queueDistance = Float.NEGATIVE_INFINITY;
|
obj.queueDistance = Float.NEGATIVE_INFINITY;
|
||||||
}
|
}
|
||||||
if (clear)
|
}
|
||||||
|
if (clear) {
|
||||||
list.clear();
|
list.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void renderShadowQueue(GeometryList list, RenderManager rm, Camera cam, boolean clear){
|
public void renderShadowQueue(GeometryList list, RenderManager rm, Camera cam, boolean clear) {
|
||||||
renderGeometryList(list, rm, cam, clear);
|
renderGeometryList(list, rm, cam, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderShadowQueue(ShadowMode shadBucket, RenderManager rm, Camera cam, boolean clear){
|
public void renderShadowQueue(ShadowMode shadBucket, RenderManager rm, Camera cam, boolean clear) {
|
||||||
switch (shadBucket){
|
switch (shadBucket) {
|
||||||
case Cast:
|
case Cast:
|
||||||
renderGeometryList(shadowCast, rm, cam, clear);
|
renderGeometryList(shadowCast, rm, cam, clear);
|
||||||
break;
|
break;
|
||||||
@ -197,8 +213,8 @@ public class RenderQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isQueueEmpty(Bucket bucket){
|
public boolean isQueueEmpty(Bucket bucket) {
|
||||||
switch (bucket){
|
switch (bucket) {
|
||||||
case Gui:
|
case Gui:
|
||||||
return guiList.size() == 0;
|
return guiList.size() == 0;
|
||||||
case Opaque:
|
case Opaque:
|
||||||
@ -207,17 +223,19 @@ public class RenderQueue {
|
|||||||
return skyList.size() == 0;
|
return skyList.size() == 0;
|
||||||
case Transparent:
|
case Transparent:
|
||||||
return transparentList.size() == 0;
|
return transparentList.size() == 0;
|
||||||
|
case Translucent:
|
||||||
|
return translucentList.size() == 0;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unsupported bucket type: "+bucket);
|
throw new UnsupportedOperationException("Unsupported bucket type: " + bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderQueue(Bucket bucket, RenderManager rm, Camera cam){
|
public void renderQueue(Bucket bucket, RenderManager rm, Camera cam) {
|
||||||
renderQueue(bucket, rm, cam, true);
|
renderQueue(bucket, rm, cam, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderQueue(Bucket bucket, RenderManager rm, Camera cam, boolean clear){
|
public void renderQueue(Bucket bucket, RenderManager rm, Camera cam, boolean clear) {
|
||||||
switch (bucket){
|
switch (bucket) {
|
||||||
case Gui:
|
case Gui:
|
||||||
renderGeometryList(guiList, rm, cam, clear);
|
renderGeometryList(guiList, rm, cam, clear);
|
||||||
break;
|
break;
|
||||||
@ -230,18 +248,22 @@ public class RenderQueue {
|
|||||||
case Transparent:
|
case Transparent:
|
||||||
renderGeometryList(transparentList, rm, cam, clear);
|
renderGeometryList(transparentList, rm, cam, clear);
|
||||||
break;
|
break;
|
||||||
|
case Translucent:
|
||||||
|
renderGeometryList(translucentList, rm, cam, clear);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unsupported bucket type: "+bucket);
|
throw new UnsupportedOperationException("Unsupported bucket type: " + bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(){
|
public void clear() {
|
||||||
opaqueList.clear();
|
opaqueList.clear();
|
||||||
guiList.clear();
|
guiList.clear();
|
||||||
transparentList.clear();
|
transparentList.clear();
|
||||||
|
translucentList.clear();
|
||||||
skyList.clear();
|
skyList.clear();
|
||||||
shadowCast.clear();
|
shadowCast.clear();
|
||||||
shadowRecv.clear();
|
shadowRecv.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,9 @@ public class NullRenderer implements Renderer {
|
|||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||||
|
}
|
||||||
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ public class BloomFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
if (glowMode != GlowMode.Scene) {
|
if (glowMode != GlowMode.Scene) {
|
||||||
backupColor = viewPort.getBackgroundColor();
|
backupColor = viewPort.getBackgroundColor();
|
||||||
viewPort.setBackgroundColor(ColorRGBA.Black);
|
viewPort.setBackgroundColor(ColorRGBA.Black);
|
||||||
|
@ -67,7 +67,7 @@ public class CartoonEdgeFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
Renderer r = renderManager.getRenderer();
|
Renderer r = renderManager.getRenderer();
|
||||||
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
||||||
renderManager.getRenderer().clearBuffers(true, true, true);
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
|
@ -76,10 +76,6 @@ public class ColorOverlayFilter extends Filter {
|
|||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
public void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
|
material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
|
||||||
|
@ -105,10 +105,6 @@ public class CrossHatchFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanUpFilter(Renderer r) {
|
public void cleanUpFilter(Renderer r) {
|
||||||
}
|
}
|
||||||
|
@ -70,10 +70,6 @@ public class DepthOfFieldFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initFilter(AssetManager assets, RenderManager renderManager,
|
public void initFilter(AssetManager assets, RenderManager renderManager,
|
||||||
ViewPort vp, int w, int h) {
|
ViewPort vp, int w, int h) {
|
||||||
|
@ -71,9 +71,6 @@ public class FadeFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
public void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
|
||||||
|
@ -84,9 +84,6 @@ public class FogFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the fog color
|
* returns the fog color
|
||||||
|
@ -88,7 +88,7 @@ public class LightScatteringFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
getClipCoordinates(lightPosition, screenLightPos, viewPort.getCamera());
|
getClipCoordinates(lightPosition, screenLightPos, viewPort.getCamera());
|
||||||
// screenLightPos.x = screenLightPos.x / viewPort.getCamera().getWidth();
|
// screenLightPos.x = screenLightPos.x / viewPort.getCamera().getWidth();
|
||||||
// screenLightPos.y = screenLightPos.y / viewPort.getCamera().getHeight();
|
// screenLightPos.y = screenLightPos.y / viewPort.getCamera().getHeight();
|
||||||
|
@ -88,9 +88,6 @@ public class PosterizationFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanUpFilter(Renderer r) {
|
public void cleanUpFilter(Renderer r) {
|
||||||
|
@ -74,9 +74,6 @@ public class RadialBlurFilter extends Filter {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getSampleDist() {
|
public float getSampleDist() {
|
||||||
return sampleDist;
|
return sampleDist;
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.post.filters;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.post.Filter;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.Renderer;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.texture.FrameBuffer;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Nehon
|
||||||
|
*/
|
||||||
|
public final class TranslucentBucketFilter extends Filter {
|
||||||
|
|
||||||
|
private RenderManager renderManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initFilter(AssetManager manager, RenderManager rm, ViewPort vp, int w, int h) {
|
||||||
|
this.renderManager = rm;
|
||||||
|
material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md");
|
||||||
|
material.setColor("Color", ColorRGBA.White);
|
||||||
|
Texture2D tex = processor.getFilterTexture();
|
||||||
|
material.setTexture("Texture", tex);
|
||||||
|
if (tex.getImage().getMultiSamples() > 1) {
|
||||||
|
material.setInt("NumSamples", tex.getImage().getMultiSamples());
|
||||||
|
} else {
|
||||||
|
material.clearParam("NumSamples");
|
||||||
|
}
|
||||||
|
renderManager.setHandleTranslucentBucket(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method and return false if your Filter does not need the scene texture
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isRequiresSceneTexture() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
|
||||||
|
renderManager.setCamera(viewPort.getCamera(), false);
|
||||||
|
renderManager.getRenderer().copyFrameBuffer(prevFilterBuffer, sceneBuffer, false);
|
||||||
|
renderManager.getRenderer().setFrameBuffer(sceneBuffer);
|
||||||
|
viewPort.getQueue().renderQueue(RenderQueue.Bucket.Translucent, renderManager, viewPort.getCamera());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanUpFilter(Renderer r) {
|
||||||
|
if (renderManager != null) {
|
||||||
|
renderManager.setHandleTranslucentBucket(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
if (renderManager != null) {
|
||||||
|
renderManager.setHandleTranslucentBucket(!enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -70,7 +70,7 @@ public class SSAOFilter extends Filter {
|
|||||||
private Pass ssaoPass;
|
private Pass ssaoPass;
|
||||||
private Material downSampleMat;
|
private Material downSampleMat;
|
||||||
private Pass downSamplePass;
|
private Pass downSamplePass;
|
||||||
private int downSampleFactor = 1;
|
private float downSampleFactor = 1f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Screen Space Ambiant Occlusion Filter
|
* Create a Screen Space Ambiant Occlusion Filter
|
||||||
@ -101,7 +101,7 @@ public class SSAOFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
Renderer r = renderManager.getRenderer();
|
Renderer r = renderManager.getRenderer();
|
||||||
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
r.setFrameBuffer(normalPass.getRenderFrameBuffer());
|
||||||
renderManager.getRenderer().clearBuffers(true, true, true);
|
renderManager.getRenderer().clearBuffers(true, true, true);
|
||||||
@ -123,7 +123,7 @@ public class SSAOFilter extends Filter {
|
|||||||
postRenderPasses = new ArrayList<Pass>();
|
postRenderPasses = new ArrayList<Pass>();
|
||||||
|
|
||||||
normalPass = new Pass();
|
normalPass = new Pass();
|
||||||
normalPass.init(renderManager.getRenderer(), screenWidth / downSampleFactor, screenHeight / downSampleFactor, Format.RGBA8, Format.Depth);
|
normalPass.init(renderManager.getRenderer(), (int)(screenWidth / downSampleFactor), (int)(screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);
|
||||||
|
|
||||||
|
|
||||||
frustumNearFar = new Vector2f();
|
frustumNearFar = new Vector2f();
|
||||||
@ -149,11 +149,11 @@ public class SSAOFilter extends Filter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean requiresDepthAsTexture() {
|
public boolean requiresDepthAsTexture() {
|
||||||
return downSampleFactor == 1;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ssaoPass.init(renderManager.getRenderer(), screenWidth / downSampleFactor, screenHeight / downSampleFactor, Format.RGBA8, Format.Depth, 1, ssaoMat);
|
ssaoPass.init(renderManager.getRenderer(), (int)(screenWidth / downSampleFactor), (int)(screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
|
||||||
ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
|
ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
|
||||||
ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
|
ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
|
||||||
postRenderPasses.add(ssaoPass);
|
postRenderPasses.add(ssaoPass);
|
||||||
@ -174,7 +174,7 @@ public class SSAOFilter extends Filter {
|
|||||||
float xScale = 1.0f / w;
|
float xScale = 1.0f / w;
|
||||||
float yScale = 1.0f / h;
|
float yScale = 1.0f / h;
|
||||||
|
|
||||||
float blurScale = 2.0f;
|
float blurScale = 2f;
|
||||||
material.setFloat("XScale", blurScale * xScale);
|
material.setFloat("XScale", blurScale * xScale);
|
||||||
material.setFloat("YScale", blurScale * yScale);
|
material.setFloat("YScale", blurScale * yScale);
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ public class WaterFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRender(RenderManager renderManager, ViewPort viewPort) {
|
public void postQueue(RenderManager renderManager, ViewPort viewPort) {
|
||||||
Camera sceneCam = viewPort.getCamera();
|
Camera sceneCam = viewPort.getCamera();
|
||||||
biasMatrix.mult(sceneCam.getViewProjectionMatrix(), textureProjMatrix);
|
biasMatrix.mult(sceneCam.getViewProjectionMatrix(), textureProjMatrix);
|
||||||
material.setMatrix4("TextureProjMatrix", textureProjMatrix);
|
material.setMatrix4("TextureProjMatrix", textureProjMatrix);
|
||||||
@ -171,7 +171,15 @@ public class WaterFilter extends Filter {
|
|||||||
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean rtb = true;
|
||||||
|
if (!renderManager.isHandleTranslucentBucket()) {
|
||||||
|
renderManager.setHandleTranslucentBucket(true);
|
||||||
|
rtb = false;
|
||||||
|
}
|
||||||
renderManager.renderViewPort(reflectionView, savedTpf);
|
renderManager.renderViewPort(reflectionView, savedTpf);
|
||||||
|
if (!rtb) {
|
||||||
|
renderManager.setHandleTranslucentBucket(false);
|
||||||
|
}
|
||||||
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
|
||||||
renderManager.setCamera(sceneCam, false);
|
renderManager.setCamera(sceneCam, false);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ import static org.lwjgl.opengl.GL11.*;
|
|||||||
public class LwjglGL1Renderer implements GL1Renderer {
|
public class LwjglGL1Renderer implements GL1Renderer {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(LwjglRenderer.class.getName());
|
private static final Logger logger = Logger.getLogger(LwjglRenderer.class.getName());
|
||||||
|
|
||||||
private final ByteBuffer nameBuf = BufferUtils.createByteBuffer(250);
|
private final ByteBuffer nameBuf = BufferUtils.createByteBuffer(250);
|
||||||
private final StringBuilder stringBuf = new StringBuilder(250);
|
private final StringBuilder stringBuf = new StringBuilder(250);
|
||||||
private final IntBuffer ib1 = BufferUtils.createIntBuffer(1);
|
private final IntBuffer ib1 = BufferUtils.createIntBuffer(1);
|
||||||
@ -51,20 +50,16 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
private final RenderContext context = new RenderContext();
|
private final RenderContext context = new RenderContext();
|
||||||
private final GLObjectManager objManager = new GLObjectManager();
|
private final GLObjectManager objManager = new GLObjectManager();
|
||||||
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
||||||
|
|
||||||
private int maxTexSize;
|
private int maxTexSize;
|
||||||
private int maxCubeTexSize;
|
private int maxCubeTexSize;
|
||||||
private int maxVertCount;
|
private int maxVertCount;
|
||||||
private int maxTriCount;
|
private int maxTriCount;
|
||||||
|
|
||||||
private final Statistics statistics = new Statistics();
|
private final Statistics statistics = new Statistics();
|
||||||
private int vpX, vpY, vpW, vpH;
|
private int vpX, vpY, vpW, vpH;
|
||||||
private int clipX, clipY, clipW, clipH;
|
private int clipX, clipY, clipW, clipH;
|
||||||
|
|
||||||
// private Matrix4f worldMatrix = new Matrix4f();
|
// private Matrix4f worldMatrix = new Matrix4f();
|
||||||
private Matrix4f viewMatrix = new Matrix4f();
|
private Matrix4f viewMatrix = new Matrix4f();
|
||||||
// private Matrix4f projMatrix = new Matrix4f();
|
// private Matrix4f projMatrix = new Matrix4f();
|
||||||
|
|
||||||
private boolean colorSet = false;
|
private boolean colorSet = false;
|
||||||
private boolean materialSet = false;
|
private boolean materialSet = false;
|
||||||
|
|
||||||
@ -93,16 +88,16 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||||
|
|
||||||
if (GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
if (GLContext.getCapabilities().GL_ARB_texture_non_power_of_two) {
|
||||||
caps.add(Caps.NonPowerOfTwoTextures);
|
caps.add(Caps.NonPowerOfTwoTextures);
|
||||||
}else{
|
} else {
|
||||||
logger.log(Level.WARNING, "Your graphics card does not "
|
logger.log(Level.WARNING, "Your graphics card does not "
|
||||||
+ "support non-power-of-2 textures. "
|
+ "support non-power-of-2 textures. "
|
||||||
+ "Some features might not work.");
|
+ "Some features might not work.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateState(){
|
public void invalidateState() {
|
||||||
context.reset();
|
context.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +138,8 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
glClearColor(color.r, color.g, color.b, color.a);
|
glClearColor(color.r, color.g, color.b, color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMaterialColor(int type, ColorRGBA color){
|
private void setMaterialColor(int type, ColorRGBA color) {
|
||||||
if (!materialSet){
|
if (!materialSet) {
|
||||||
materialSet = true;
|
materialSet = true;
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
}
|
}
|
||||||
@ -155,8 +150,8 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
glMaterial(GL_FRONT_AND_BACK, type, fb16);
|
glMaterial(GL_FRONT_AND_BACK, type, fb16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFixedFuncBinding(FixedFuncBinding ffBinding, Object val){
|
public void setFixedFuncBinding(FixedFuncBinding ffBinding, Object val) {
|
||||||
switch (ffBinding){
|
switch (ffBinding) {
|
||||||
case Color:
|
case Color:
|
||||||
ColorRGBA color = (ColorRGBA) val;
|
ColorRGBA color = (ColorRGBA) val;
|
||||||
glColor4f(color.r, color.g, color.b, color.a);
|
glColor4f(color.r, color.g, color.b, color.a);
|
||||||
@ -177,12 +172,12 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearSetFixedFuncBindings(){
|
public void clearSetFixedFuncBindings() {
|
||||||
if (colorSet){
|
if (colorSet) {
|
||||||
glColor4f(1,1,1,1);
|
glColor4f(1, 1, 1, 1);
|
||||||
colorSet = false;
|
colorSet = false;
|
||||||
}
|
}
|
||||||
if (materialSet){
|
if (materialSet) {
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
materialSet = false; // TODO: not efficient
|
materialSet = false; // TODO: not efficient
|
||||||
}
|
}
|
||||||
@ -231,7 +226,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
context.colorWriteEnabled = false;
|
context.colorWriteEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.isPointSprite()){
|
if (state.isPointSprite()) {
|
||||||
logger.log(Level.WARNING, "Point Sprite unsupported!");
|
logger.log(Level.WARNING, "Point Sprite unsupported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,8 +320,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
context.blendMode = state.getBlendMode();
|
context.blendMode = state.getBlendMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.isStencilTest())
|
if (state.isStencilTest()) {
|
||||||
throw new UnsupportedOperationException("OpenGL 1.1 doesn't support two sided stencil operations.");
|
throw new UnsupportedOperationException("OpenGL 1.1 doesn't support two sided stencil operations.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,11 +515,11 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check sizes if graphics card doesn't support NPOT
|
// Check sizes if graphics card doesn't support NPOT
|
||||||
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two) {
|
||||||
if (img.getWidth() != 0 && img.getHeight() != 0){
|
if (img.getWidth() != 0 && img.getHeight() != 0) {
|
||||||
if (!FastMath.isPowerOfTwo(img.getWidth())
|
if (!FastMath.isPowerOfTwo(img.getWidth())
|
||||||
|| !FastMath.isPowerOfTwo(img.getHeight())
|
|| !FastMath.isPowerOfTwo(img.getHeight())
|
||||||
|| img.getWidth() != img.getHeight()){
|
|| img.getWidth() != img.getHeight()) {
|
||||||
|
|
||||||
// Resize texture to Power-of-2 size
|
// Resize texture to Power-of-2 size
|
||||||
MipMapGenerator.resizeToPowerOf2(img);
|
MipMapGenerator.resizeToPowerOf2(img);
|
||||||
@ -537,9 +533,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
// generate from base level if required
|
// generate from base level if required
|
||||||
|
|
||||||
// Check if hardware mips are supported
|
// Check if hardware mips are supported
|
||||||
if (GLContext.getCapabilities().OpenGL14){
|
if (GLContext.getCapabilities().OpenGL14) {
|
||||||
glTexParameteri(target, GL14.GL_GENERATE_MIPMAP, GL_TRUE);
|
glTexParameteri(target, GL14.GL_GENERATE_MIPMAP, GL_TRUE);
|
||||||
}else{
|
} else {
|
||||||
MipMapGenerator.generateMipMaps(img);
|
MipMapGenerator.generateMipMaps(img);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -573,7 +569,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTexture(int unit, Texture tex) {
|
public void setTexture(int unit, Texture tex) {
|
||||||
if (unit != 0 || tex.getType() != Texture.Type.TwoDimensional){
|
if (unit != 0 || tex.getType() != Texture.Type.TwoDimensional) {
|
||||||
//throw new UnsupportedOperationException();
|
//throw new UnsupportedOperationException();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -617,7 +613,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
|
|
||||||
private void checkTexturingUsed() {
|
private void checkTexturingUsed() {
|
||||||
Image[] textures = context.boundTextures;
|
Image[] textures = context.boundTextures;
|
||||||
if (textures[0] != null){
|
if (textures[0] != null) {
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
textures[0] = null;
|
textures[0] = null;
|
||||||
}
|
}
|
||||||
@ -691,8 +687,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) {
|
public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) {
|
||||||
if (count > 1)
|
if (count > 1) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
glDrawArrays(convertElementMode(mode), 0, vertCount);
|
glDrawArrays(convertElementMode(mode), 0, vertCount);
|
||||||
}
|
}
|
||||||
@ -725,31 +722,34 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
|
|
||||||
switch (vb.getBufferType()) {
|
switch (vb.getBufferType()) {
|
||||||
case Position:
|
case Position:
|
||||||
if (!(data instanceof FloatBuffer))
|
if (!(data instanceof FloatBuffer)) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
glVertexPointer(comps, vb.getStride(), (FloatBuffer) data);
|
glVertexPointer(comps, vb.getStride(), (FloatBuffer) data);
|
||||||
break;
|
break;
|
||||||
case Normal:
|
case Normal:
|
||||||
if (!(data instanceof FloatBuffer))
|
if (!(data instanceof FloatBuffer)) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
glNormalPointer(vb.getStride(), (FloatBuffer)data);
|
glNormalPointer(vb.getStride(), (FloatBuffer) data);
|
||||||
break;
|
break;
|
||||||
case Color:
|
case Color:
|
||||||
if (data instanceof FloatBuffer){
|
if (data instanceof FloatBuffer) {
|
||||||
glColorPointer(comps, vb.getStride(), (FloatBuffer)data);
|
glColorPointer(comps, vb.getStride(), (FloatBuffer) data);
|
||||||
}else if (data instanceof ByteBuffer){
|
} else if (data instanceof ByteBuffer) {
|
||||||
glColorPointer(comps, true, vb.getStride(), (ByteBuffer)data);
|
glColorPointer(comps, true, vb.getStride(), (ByteBuffer) data);
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TexCoord:
|
case TexCoord:
|
||||||
if (!(data instanceof FloatBuffer))
|
if (!(data instanceof FloatBuffer)) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
glTexCoordPointer(comps, vb.getStride(), (FloatBuffer)data);
|
glTexCoordPointer(comps, vb.getStride(), (FloatBuffer) data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Ignore, this is an unsupported attribute for OpenGL1.
|
// Ignore, this is an unsupported attribute for OpenGL1.
|
||||||
@ -761,16 +761,16 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
setVertexAttrib(vb, null);
|
setVertexAttrib(vb, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawElements(int mode, int format, Buffer data){
|
private void drawElements(int mode, int format, Buffer data) {
|
||||||
switch (format){
|
switch (format) {
|
||||||
case GL_UNSIGNED_BYTE:
|
case GL_UNSIGNED_BYTE:
|
||||||
glDrawElements(mode, (ByteBuffer)data);
|
glDrawElements(mode, (ByteBuffer) data);
|
||||||
break;
|
break;
|
||||||
case GL_UNSIGNED_SHORT:
|
case GL_UNSIGNED_SHORT:
|
||||||
glDrawElements(mode, (ShortBuffer)data);
|
glDrawElements(mode, (ShortBuffer) data);
|
||||||
break;
|
break;
|
||||||
case GL_UNSIGNED_INT:
|
case GL_UNSIGNED_INT:
|
||||||
glDrawElements(mode, (IntBuffer)data);
|
glDrawElements(mode, (IntBuffer) data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -791,8 +791,8 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
|
|
||||||
int elMode = convertElementMode(Mode.Triangles);
|
int elMode = convertElementMode(Mode.Triangles);
|
||||||
int fmt = convertVertexFormat(indexBuf.getFormat());
|
int fmt = convertVertexFormat(indexBuf.getFormat());
|
||||||
// int elSize = indexBuf.getFormat().getComponentSize();
|
// int elSize = indexBuf.getFormat().getComponentSize();
|
||||||
// int listStart = modeStart[0];
|
// int listStart = modeStart[0];
|
||||||
int stripStart = modeStart[1];
|
int stripStart = modeStart[1];
|
||||||
int fanStart = modeStart[2];
|
int fanStart = modeStart[2];
|
||||||
int curOffset = 0;
|
int curOffset = 0;
|
||||||
@ -818,8 +818,6 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void clearVertexAttribs() {
|
public void clearVertexAttribs() {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
VertexBuffer vb = context.boundAttribs[i];
|
VertexBuffer vb = context.boundAttribs[i];
|
||||||
@ -874,8 +872,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void renderMesh(Mesh mesh, int lod, int count) {
|
public void renderMesh(Mesh mesh, int lod, int count) {
|
||||||
if (mesh.getVertexCount() == 0)
|
if (mesh.getVertexCount() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (context.pointSize != mesh.getPointSize()) {
|
if (context.pointSize != mesh.getPointSize()) {
|
||||||
glPointSize(mesh.getPointSize());
|
glPointSize(mesh.getPointSize());
|
||||||
@ -887,8 +886,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean dynamic = false;
|
boolean dynamic = false;
|
||||||
if (mesh.getBuffer(Type.InterleavedData) != null)
|
if (mesh.getBuffer(Type.InterleavedData) != null) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
if (mesh.getNumLodLevels() == 0) {
|
if (mesh.getNumLodLevels() == 0) {
|
||||||
IntMap<VertexBuffer> bufs = mesh.getBuffers();
|
IntMap<VertexBuffer> bufs = mesh.getBuffers();
|
||||||
@ -929,6 +929,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||||
|
}
|
||||||
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,5 +946,4 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
|
|
||||||
public void deleteBuffer(VertexBuffer vb) {
|
public void deleteBuffer(VertexBuffer vb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -326,9 +326,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
caps.add(Caps.VertexBufferArray);
|
caps.add(Caps.VertexBufferArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_non_power_of_two){
|
if (ctxCaps.GL_ARB_texture_non_power_of_two) {
|
||||||
caps.add(Caps.NonPowerOfTwoTextures);
|
caps.add(Caps.NonPowerOfTwoTextures);
|
||||||
}else{
|
} else {
|
||||||
logger.log(Level.WARNING, "Your graphics card does not "
|
logger.log(Level.WARNING, "Your graphics card does not "
|
||||||
+ "support non-power-of-2 textures. "
|
+ "support non-power-of-2 textures. "
|
||||||
+ "Some features might not work.");
|
+ "Some features might not work.");
|
||||||
@ -414,7 +414,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
logger.log(Level.INFO, "Caps: {0}", caps);
|
logger.log(Level.INFO, "Caps: {0}", caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateState(){
|
public void invalidateState() {
|
||||||
context.reset();
|
context.reset();
|
||||||
boundShader = null;
|
boundShader = null;
|
||||||
lastFb = null;
|
lastFb = null;
|
||||||
@ -610,55 +610,50 @@ public class LwjglRenderer implements Renderer {
|
|||||||
context.blendMode = state.getBlendMode();
|
context.blendMode = state.getBlendMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context.stencilTest!=state.isStencilTest()
|
if (context.stencilTest != state.isStencilTest()
|
||||||
|| context.frontStencilStencilFailOperation!=state.getFrontStencilStencilFailOperation()
|
|| context.frontStencilStencilFailOperation != state.getFrontStencilStencilFailOperation()
|
||||||
|| context.frontStencilDepthFailOperation!=state.getFrontStencilDepthFailOperation()
|
|| context.frontStencilDepthFailOperation != state.getFrontStencilDepthFailOperation()
|
||||||
|| context.frontStencilDepthPassOperation!=state.getFrontStencilDepthPassOperation()
|
|| context.frontStencilDepthPassOperation != state.getFrontStencilDepthPassOperation()
|
||||||
|| context.backStencilStencilFailOperation!=state.getBackStencilStencilFailOperation()
|
|| context.backStencilStencilFailOperation != state.getBackStencilStencilFailOperation()
|
||||||
|| context.backStencilDepthFailOperation!=state.getBackStencilDepthFailOperation()
|
|| context.backStencilDepthFailOperation != state.getBackStencilDepthFailOperation()
|
||||||
|| context.backStencilDepthPassOperation!=state.getBackStencilDepthPassOperation()
|
|| context.backStencilDepthPassOperation != state.getBackStencilDepthPassOperation()
|
||||||
|| context.frontStencilFunction!=state.getFrontStencilFunction()
|
|| context.frontStencilFunction != state.getFrontStencilFunction()
|
||||||
|| context.backStencilFunction!=state.getBackStencilFunction()
|
|| context.backStencilFunction != state.getBackStencilFunction()) {
|
||||||
){
|
|
||||||
|
|
||||||
context.frontStencilStencilFailOperation=state.getFrontStencilStencilFailOperation(); //terrible looking, I know
|
context.frontStencilStencilFailOperation = state.getFrontStencilStencilFailOperation(); //terrible looking, I know
|
||||||
context.frontStencilDepthFailOperation=state.getFrontStencilDepthFailOperation();
|
context.frontStencilDepthFailOperation = state.getFrontStencilDepthFailOperation();
|
||||||
context.frontStencilDepthPassOperation=state.getFrontStencilDepthPassOperation();
|
context.frontStencilDepthPassOperation = state.getFrontStencilDepthPassOperation();
|
||||||
context.backStencilStencilFailOperation=state.getBackStencilStencilFailOperation();
|
context.backStencilStencilFailOperation = state.getBackStencilStencilFailOperation();
|
||||||
context.backStencilDepthFailOperation=state.getBackStencilDepthFailOperation();
|
context.backStencilDepthFailOperation = state.getBackStencilDepthFailOperation();
|
||||||
context.backStencilDepthPassOperation=state.getBackStencilDepthPassOperation();
|
context.backStencilDepthPassOperation = state.getBackStencilDepthPassOperation();
|
||||||
context.frontStencilFunction=state.getFrontStencilFunction();
|
context.frontStencilFunction = state.getFrontStencilFunction();
|
||||||
context.backStencilFunction=state.getBackStencilFunction();
|
context.backStencilFunction = state.getBackStencilFunction();
|
||||||
|
|
||||||
if(state.isStencilTest()){
|
if (state.isStencilTest()) {
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
glStencilOpSeparate(GL_FRONT,
|
glStencilOpSeparate(GL_FRONT,
|
||||||
glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),
|
glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),
|
||||||
glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),
|
glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),
|
||||||
glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation())
|
glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation()));
|
||||||
);
|
|
||||||
glStencilOpSeparate(GL_BACK,
|
glStencilOpSeparate(GL_BACK,
|
||||||
glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),
|
glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),
|
||||||
glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),
|
glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),
|
||||||
glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation())
|
glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation()));
|
||||||
);
|
|
||||||
glStencilFuncSeparate(GL_FRONT,
|
glStencilFuncSeparate(GL_FRONT,
|
||||||
glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),
|
glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),
|
||||||
0,Integer.MAX_VALUE
|
0, Integer.MAX_VALUE);
|
||||||
);
|
|
||||||
glStencilFuncSeparate(GL_BACK,
|
glStencilFuncSeparate(GL_BACK,
|
||||||
glStencilFuncFromStencilFunc(state.getBackStencilFunction()),
|
glStencilFuncFromStencilFunc(state.getBackStencilFunction()),
|
||||||
0,Integer.MAX_VALUE
|
0, Integer.MAX_VALUE);
|
||||||
);
|
} else {
|
||||||
}else{
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int glStencilOpFromStencilOp(RenderState.StencilOperation s){
|
private int glStencilOpFromStencilOp(RenderState.StencilOperation s) {
|
||||||
switch(s){
|
switch (s) {
|
||||||
case Keep:
|
case Keep:
|
||||||
return GL_KEEP;
|
return GL_KEEP;
|
||||||
case Zero:
|
case Zero:
|
||||||
@ -680,8 +675,8 @@ public class LwjglRenderer implements Renderer {
|
|||||||
} //end switch
|
} //end switch
|
||||||
}
|
}
|
||||||
|
|
||||||
private int glStencilFuncFromStencilFunc(RenderState.StencilFunction s){
|
private int glStencilFuncFromStencilFunc(RenderState.StencilFunction s) {
|
||||||
switch(s){
|
switch (s) {
|
||||||
case Never:
|
case Never:
|
||||||
return GL_NEVER;
|
return GL_NEVER;
|
||||||
case Less:
|
case Less:
|
||||||
@ -826,7 +821,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
if (val instanceof ColorRGBA) {
|
if (val instanceof ColorRGBA) {
|
||||||
ColorRGBA c = (ColorRGBA) val;
|
ColorRGBA c = (ColorRGBA) val;
|
||||||
glUniform4f(loc, c.r, c.g, c.b, c.a);
|
glUniform4f(loc, c.r, c.g, c.b, c.a);
|
||||||
}else if (val instanceof Vector4f) {
|
} else if (val instanceof Vector4f) {
|
||||||
Vector4f c = (Vector4f) val;
|
Vector4f c = (Vector4f) val;
|
||||||
glUniform4f(loc, c.x, c.y, c.z, c.w);
|
glUniform4f(loc, c.x, c.y, c.z, c.w);
|
||||||
} else {
|
} else {
|
||||||
@ -991,9 +986,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
logger.log(Level.WARNING, "Bad compile of:\n{0}{1}",
|
logger.log(Level.WARNING, "Bad compile of:\n{0}{1}",
|
||||||
new Object[]{source.getDefines(), source.getSource()});
|
new Object[]{source.getDefines(), source.getSource()});
|
||||||
if (infoLog != null) {
|
if (infoLog != null) {
|
||||||
throw new RendererException( "compile error in:" + source + " error:" + infoLog );
|
throw new RendererException("compile error in:" + source + " error:" + infoLog);
|
||||||
} else {
|
} else {
|
||||||
throw new RendererException( "compile error in:" + source + " error: <not provided>" );
|
throw new RendererException("compile error in:" + source + " error: <not provided>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,9 +1067,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (infoLog != null) {
|
if (infoLog != null) {
|
||||||
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog );
|
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
||||||
} else {
|
} else {
|
||||||
throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>" );
|
throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1179,6 +1174,10 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|* Framebuffers *|
|
|* Framebuffers *|
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
||||||
|
copyFrameBuffer(src, dst, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||||
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {
|
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {
|
||||||
int srcW = 0;
|
int srcW = 0;
|
||||||
int srcH = 0;
|
int srcH = 0;
|
||||||
@ -1212,11 +1211,15 @@ public class LwjglRenderer implements Renderer {
|
|||||||
dstW = dst.getWidth();
|
dstW = dst.getWidth();
|
||||||
dstH = dst.getHeight();
|
dstH = dst.getHeight();
|
||||||
}
|
}
|
||||||
|
int mask = GL_COLOR_BUFFER_BIT;
|
||||||
|
if (copyDepth) {
|
||||||
|
mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
}
|
||||||
glBlitFramebufferEXT(0, 0, srcW, srcH,
|
glBlitFramebufferEXT(0, 0, srcW, srcH,
|
||||||
0, 0, dstW, dstH,
|
0, 0, dstW, dstH, mask,
|
||||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
|
||||||
GL_NEAREST);
|
GL_NEAREST);
|
||||||
|
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
||||||
try {
|
try {
|
||||||
checkFrameBufferError();
|
checkFrameBufferError();
|
||||||
@ -1643,9 +1646,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.pointSprite)
|
if (context.pointSprite) {
|
||||||
return; // Attempt to fix glTexParameter crash for some ATI GPUs
|
return; // Attempt to fix glTexParameter crash for some ATI GPUs
|
||||||
|
}
|
||||||
// repeat modes
|
// repeat modes
|
||||||
switch (tex.getType()) {
|
switch (tex.getType()) {
|
||||||
case ThreeDimensional:
|
case ThreeDimensional:
|
||||||
@ -1722,14 +1725,15 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
|
// Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
|
||||||
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two){
|
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two) {
|
||||||
if (img.getData(0) == null)
|
if (img.getData(0) == null) {
|
||||||
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
|
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
|
||||||
|
}
|
||||||
|
|
||||||
if (img.getWidth() != 0 && img.getHeight() != 0){
|
if (img.getWidth() != 0 && img.getHeight() != 0) {
|
||||||
if (!FastMath.isPowerOfTwo(img.getWidth())
|
if (!FastMath.isPowerOfTwo(img.getWidth())
|
||||||
|| !FastMath.isPowerOfTwo(img.getHeight())
|
|| !FastMath.isPowerOfTwo(img.getHeight())
|
||||||
|| img.getWidth() != img.getHeight()){
|
|| img.getWidth() != img.getHeight()) {
|
||||||
// logger.log(Level.WARNING, "Encountered NPOT texture {0}, "
|
// logger.log(Level.WARNING, "Encountered NPOT texture {0}, "
|
||||||
// + "it might not display correctly.", img);
|
// + "it might not display correctly.", img);
|
||||||
|
|
||||||
@ -1739,10 +1743,11 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if graphics card doesn't support multisample textures
|
// Check if graphics card doesn't support multisample textures
|
||||||
if (!GLContext.getCapabilities().GL_ARB_texture_multisample){
|
if (!GLContext.getCapabilities().GL_ARB_texture_multisample) {
|
||||||
if (img.getMultiSamples() > 1)
|
if (img.getMultiSamples() > 1) {
|
||||||
throw new RendererException("Multisample textures not supported by graphics hardware");
|
throw new RendererException("Multisample textures not supported by graphics hardware");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (target == GL_TEXTURE_CUBE_MAP) {
|
if (target == GL_TEXTURE_CUBE_MAP) {
|
||||||
List<ByteBuffer> data = img.getData();
|
List<ByteBuffer> data = img.getData();
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
package jme3test.light;
|
package jme3test.light;
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.effect.ParticleEmitter;
|
||||||
|
import com.jme3.effect.ParticleMesh;
|
||||||
import com.jme3.light.AmbientLight;
|
import com.jme3.light.AmbientLight;
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
@ -107,6 +109,29 @@ public class TestTransparentShadow extends SimpleApplication {
|
|||||||
|
|
||||||
rootNode.attachChild(teaGeom);
|
rootNode.attachChild(teaGeom);
|
||||||
|
|
||||||
|
/** Uses Texture from jme3-test-data library! */
|
||||||
|
ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
|
||||||
|
Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
|
||||||
|
//mat_red.getAdditionalRenderState().setDepthTest(true);
|
||||||
|
//mat_red.getAdditionalRenderState().setDepthWrite(true);
|
||||||
|
fire.setMaterial(mat_red);
|
||||||
|
fire.setImagesX(2); fire.setImagesY(2); // 2x2 texture animation
|
||||||
|
fire.setEndColor( new ColorRGBA(1f, 0f, 0f, 1f)); // red
|
||||||
|
fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
|
||||||
|
fire.setInitialVelocity(new Vector3f(0, 2, 0));
|
||||||
|
fire.setStartSize(0.6f);
|
||||||
|
fire.setEndSize(0.1f);
|
||||||
|
fire.setGravity(0);
|
||||||
|
fire.setLowLife(0.5f);
|
||||||
|
fire.setHighLife(1.5f);
|
||||||
|
fire.setVelocityVariation(0.3f);
|
||||||
|
fire.setLocalTranslation(1.0f, 0, 1.0f);
|
||||||
|
fire.setLocalScale(0.3f);
|
||||||
|
fire.setQueueBucket(Bucket.Translucent);
|
||||||
|
rootNode.attachChild(fire);
|
||||||
|
|
||||||
|
|
||||||
PssmShadowRenderer pssmRenderer = new PssmShadowRenderer(assetManager, 1024, 1);
|
PssmShadowRenderer pssmRenderer = new PssmShadowRenderer(assetManager, 1024, 1);
|
||||||
pssmRenderer.setDirection(new Vector3f(0.01f, -1f, 0.01f).normalizeLocal());
|
pssmRenderer.setDirection(new Vector3f(0.01f, -1f, 0.01f).normalizeLocal());
|
||||||
pssmRenderer.setLambda(0.55f);
|
pssmRenderer.setLambda(0.55f);
|
||||||
|
@ -42,6 +42,7 @@ import com.jme3.math.Vector3f;
|
|||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
import com.jme3.post.filters.BloomFilter;
|
import com.jme3.post.filters.BloomFilter;
|
||||||
import com.jme3.post.filters.CartoonEdgeFilter;
|
import com.jme3.post.filters.CartoonEdgeFilter;
|
||||||
|
import com.jme3.post.filters.CrossHatchFilter;
|
||||||
import com.jme3.post.filters.FogFilter;
|
import com.jme3.post.filters.FogFilter;
|
||||||
import com.jme3.post.filters.RadialBlurFilter;
|
import com.jme3.post.filters.RadialBlurFilter;
|
||||||
import com.jme3.post.ssao.SSAOFilter;
|
import com.jme3.post.ssao.SSAOFilter;
|
||||||
@ -62,6 +63,7 @@ public class TestMultiViewsFilters extends SimpleApplication {
|
|||||||
// create the geometry and attach it
|
// create the geometry and attach it
|
||||||
Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");
|
Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");
|
||||||
teaGeom.scale(3);
|
teaGeom.scale(3);
|
||||||
|
teaGeom.getMaterial().setColor("GlowColor", ColorRGBA.Green);
|
||||||
|
|
||||||
DirectionalLight dl = new DirectionalLight();
|
DirectionalLight dl = new DirectionalLight();
|
||||||
dl.setColor(ColorRGBA.White);
|
dl.setColor(ColorRGBA.White);
|
||||||
@ -109,18 +111,38 @@ public class TestMultiViewsFilters extends SimpleApplication {
|
|||||||
view4.setClearFlags(true, true, true);
|
view4.setClearFlags(true, true, true);
|
||||||
view4.attachScene(rootNode);
|
view4.attachScene(rootNode);
|
||||||
|
|
||||||
|
// Camera cam5 = new Camera(200, 200);
|
||||||
|
// cam5.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
|
||||||
|
// cam5.setName("cam5");
|
||||||
|
// cam5.setViewPort(5.23f, 6.33f, 0.56f, 1.66f);
|
||||||
|
// this.setViewPortAreas(5.23f, 6.33f, 0.56f, 1.66f);
|
||||||
|
// this.setViewPortCamSize(200, 200);
|
||||||
|
// 1046,1266,112,332
|
||||||
|
Camera cam5 = cam.clone();
|
||||||
|
cam5.setName("cam5");
|
||||||
|
cam5.setViewPort(1046f/settings.getWidth(), 1266f/settings.getWidth(), 112f/settings.getHeight(), 332f/settings.getHeight());
|
||||||
|
cam5.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f));
|
||||||
|
cam5.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f));
|
||||||
|
|
||||||
|
final ViewPort view5 = renderManager.createMainView("center", cam5);
|
||||||
|
view5.setClearFlags(true, true, true);
|
||||||
|
view5.attachScene(rootNode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
|
rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
|
||||||
|
|
||||||
final FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
final FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager);
|
final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager);
|
||||||
final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager);
|
final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager);
|
||||||
final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager);
|
final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager);
|
||||||
|
final FilterPostProcessor fpp5 = new FilterPostProcessor(assetManager);
|
||||||
|
|
||||||
|
|
||||||
// fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1)));
|
// fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1)));
|
||||||
fpp3.addFilter(new CartoonEdgeFilter());
|
fpp3.addFilter(new CartoonEdgeFilter());
|
||||||
|
|
||||||
fpp2.addFilter(new BloomFilter());
|
fpp2.addFilter(new CrossHatchFilter());
|
||||||
final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2);
|
final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2);
|
||||||
fpp.addFilter(ff);
|
fpp.addFilter(ff);
|
||||||
|
|
||||||
@ -133,10 +155,13 @@ public class TestMultiViewsFilters extends SimpleApplication {
|
|||||||
fpp4.addFilter(f);
|
fpp4.addFilter(f);
|
||||||
SSAOUI ui = new SSAOUI(inputManager, f);
|
SSAOUI ui = new SSAOUI(inputManager, f);
|
||||||
|
|
||||||
|
fpp5.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects));
|
||||||
|
|
||||||
viewPort.addProcessor(fpp);
|
viewPort.addProcessor(fpp);
|
||||||
view2.addProcessor(fpp2);
|
view2.addProcessor(fpp2);
|
||||||
view3.addProcessor(fpp3);
|
view3.addProcessor(fpp3);
|
||||||
view4.addProcessor(fpp4);
|
view4.addProcessor(fpp4);
|
||||||
|
view5.addProcessor(fpp5);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -149,11 +174,13 @@ public class TestMultiViewsFilters extends SimpleApplication {
|
|||||||
view2.removeProcessor(fpp2);
|
view2.removeProcessor(fpp2);
|
||||||
view3.removeProcessor(fpp3);
|
view3.removeProcessor(fpp3);
|
||||||
view4.removeProcessor(fpp4);
|
view4.removeProcessor(fpp4);
|
||||||
|
view5.removeProcessor(fpp5);
|
||||||
} else {
|
} else {
|
||||||
viewPort.addProcessor(fpp);
|
viewPort.addProcessor(fpp);
|
||||||
view2.addProcessor(fpp2);
|
view2.addProcessor(fpp2);
|
||||||
view3.addProcessor(fpp3);
|
view3.addProcessor(fpp3);
|
||||||
view4.addProcessor(fpp4);
|
view4.addProcessor(fpp4);
|
||||||
|
view5.addProcessor(fpp5);
|
||||||
}
|
}
|
||||||
filterEnabled = !filterEnabled;
|
filterEnabled = !filterEnabled;
|
||||||
}
|
}
|
||||||
|
@ -3,20 +3,29 @@ package jme3test.water;
|
|||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.audio.AudioNode;
|
import com.jme3.audio.AudioNode;
|
||||||
import com.jme3.bounding.BoundingBox;
|
import com.jme3.bounding.BoundingBox;
|
||||||
|
import com.jme3.effect.ParticleEmitter;
|
||||||
|
import com.jme3.effect.ParticleMesh;
|
||||||
import com.jme3.input.controls.ActionListener;
|
import com.jme3.input.controls.ActionListener;
|
||||||
import com.jme3.input.controls.KeyTrigger;
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.FastMath;
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
|
||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
|
import com.jme3.post.filters.DepthOfFieldFilter;
|
||||||
|
import com.jme3.post.filters.LightScatteringFilter;
|
||||||
|
import com.jme3.post.filters.TranslucentBucketFilter;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue.Bucket;
|
||||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.shape.Box;
|
||||||
import com.jme3.terrain.geomipmap.TerrainQuad;
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
import com.jme3.terrain.heightmap.AbstractHeightMap;
|
import com.jme3.terrain.heightmap.AbstractHeightMap;
|
||||||
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
|
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
|
||||||
@ -35,7 +44,6 @@ import jme3tools.converters.ImageToAwt;
|
|||||||
*/
|
*/
|
||||||
public class TestPostWater extends SimpleApplication {
|
public class TestPostWater extends SimpleApplication {
|
||||||
|
|
||||||
private FilterPostProcessor fpp;
|
|
||||||
private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
|
private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
|
||||||
private WaterFilter water;
|
private WaterFilter water;
|
||||||
TerrainQuad terrain;
|
TerrainQuad terrain;
|
||||||
@ -65,10 +73,10 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
|
l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
|
||||||
mainScene.addLight(l);
|
mainScene.addLight(l);
|
||||||
|
|
||||||
flyCam.setMoveSpeed(50);
|
flyCam.setMoveSpeed(100);
|
||||||
|
|
||||||
cam.setLocation(new Vector3f(-700, 100, 300));
|
cam.setLocation(new Vector3f(-700, 100, 300));
|
||||||
cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI*0.06f,FastMath.PI*0.65f,0}));
|
cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));
|
||||||
|
|
||||||
|
|
||||||
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
|
||||||
@ -80,11 +88,24 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
waves.setLooping(true);
|
waves.setLooping(true);
|
||||||
audioRenderer.playSource(waves);
|
audioRenderer.playSource(waves);
|
||||||
|
|
||||||
|
//private FilterPostProcessor fpp;
|
||||||
|
|
||||||
fpp = new FilterPostProcessor(assetManager);
|
|
||||||
// fpp.setNumSamples(4);
|
|
||||||
|
|
||||||
water = new WaterFilter(rootNode, lightDir);
|
water = new WaterFilter(rootNode, lightDir);
|
||||||
|
|
||||||
|
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||||
|
fpp.addFilter(water);
|
||||||
|
|
||||||
|
DepthOfFieldFilter dof=new DepthOfFieldFilter();
|
||||||
|
dof.setFocusDistance(0);
|
||||||
|
dof.setFocusRange(100);
|
||||||
|
fpp.addFilter(new TranslucentBucketFilter());
|
||||||
|
fpp.addFilter(dof);
|
||||||
|
|
||||||
|
|
||||||
|
// fpp.setNumSamples(4);
|
||||||
|
|
||||||
|
|
||||||
water.setWaveScale(0.003f);
|
water.setWaveScale(0.003f);
|
||||||
water.setMaxAmplitude(2f);
|
water.setMaxAmplitude(2f);
|
||||||
water.setFoamExistence(new Vector3f(1f, 4, 0.5f));
|
water.setFoamExistence(new Vector3f(1f, 4, 0.5f));
|
||||||
@ -96,28 +117,83 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
//water.setFoamHardness(0.6f);
|
//water.setFoamHardness(0.6f);
|
||||||
|
|
||||||
water.setWaterHeight(initialWaterHeight);
|
water.setWaterHeight(initialWaterHeight);
|
||||||
fpp.addFilter(water);
|
|
||||||
|
|
||||||
|
//
|
||||||
viewPort.addProcessor(fpp);
|
viewPort.addProcessor(fpp);
|
||||||
|
|
||||||
inputManager.addListener(new ActionListener() {
|
inputManager.addListener(new ActionListener() {
|
||||||
|
|
||||||
public void onAction(String name, boolean isPressed, float tpf) {
|
public void onAction(String name, boolean isPressed, float tpf) {
|
||||||
if(isPressed){
|
if (isPressed) {
|
||||||
if(name.equals("foam1")){
|
if (name.equals("foam1")) {
|
||||||
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));
|
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));
|
||||||
}
|
}
|
||||||
if(name.equals("foam2")){
|
if (name.equals("foam2")) {
|
||||||
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
|
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
|
||||||
}
|
}
|
||||||
if(name.equals("foam3")){
|
if (name.equals("foam3")) {
|
||||||
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));
|
water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "foam1","foam2","foam3");
|
}, "foam1", "foam2", "foam3");
|
||||||
inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));
|
inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));
|
||||||
inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));
|
inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));
|
||||||
inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));
|
inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));
|
||||||
|
createBox();
|
||||||
|
createFire();
|
||||||
|
}
|
||||||
|
Geometry box;
|
||||||
|
|
||||||
|
private void createBox() {
|
||||||
|
//creating a transluscent box
|
||||||
|
box = new Geometry("box", new Box(new Vector3f(0, 0, 0), 50, 50, 50));
|
||||||
|
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
|
mat.setColor("Color", new ColorRGBA(1.0f, 0, 0, 0.3f));
|
||||||
|
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||||
|
//mat.getAdditionalRenderState().setDepthWrite(false);
|
||||||
|
//mat.getAdditionalRenderState().setDepthTest(false);
|
||||||
|
box.setMaterial(mat);
|
||||||
|
box.setQueueBucket(Bucket.Translucent);
|
||||||
|
|
||||||
|
|
||||||
|
//creating a post view port
|
||||||
|
// ViewPort post=renderManager.createPostView("transpPost", cam);
|
||||||
|
// post.setClearFlags(false, true, true);
|
||||||
|
|
||||||
|
|
||||||
|
box.setLocalTranslation(-600, 0, 300);
|
||||||
|
|
||||||
|
//attaching the box to the post viewport
|
||||||
|
//Don't forget to updateGeometricState() the box in the simpleUpdate
|
||||||
|
// post.attachScene(box);
|
||||||
|
|
||||||
|
rootNode.attachChild(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFire() {
|
||||||
|
/** Uses Texture from jme3-test-data library! */
|
||||||
|
ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
|
||||||
|
Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
|
||||||
|
|
||||||
|
fire.setMaterial(mat_red);
|
||||||
|
fire.setImagesX(2);
|
||||||
|
fire.setImagesY(2); // 2x2 texture animation
|
||||||
|
fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f)); // red
|
||||||
|
fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
|
||||||
|
fire.setInitialVelocity(new Vector3f(0, 2, 0));
|
||||||
|
fire.setStartSize(10f);
|
||||||
|
fire.setEndSize(1f);
|
||||||
|
fire.setGravity(0);
|
||||||
|
fire.setLowLife(0.5f);
|
||||||
|
fire.setHighLife(1.5f);
|
||||||
|
fire.setVelocityVariation(0.3f);
|
||||||
|
fire.setLocalTranslation(-500, 30, 300);
|
||||||
|
|
||||||
|
fire.setQueueBucket(Bucket.Translucent);
|
||||||
|
rootNode.attachChild(fire);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTerrain(Node rootNode) {
|
private void createTerrain(Node rootNode) {
|
||||||
@ -138,7 +214,7 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
rock.setWrap(WrapMode.Repeat);
|
rock.setWrap(WrapMode.Repeat);
|
||||||
matRock.setTexture("DiffuseMap_2", rock);
|
matRock.setTexture("DiffuseMap_2", rock);
|
||||||
matRock.setFloat("DiffuseMap_2_scale", 128);
|
matRock.setFloat("DiffuseMap_2_scale", 128);
|
||||||
Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.png");
|
Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
|
||||||
normalMap0.setWrap(WrapMode.Repeat);
|
normalMap0.setWrap(WrapMode.Repeat);
|
||||||
Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
|
Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
|
||||||
normalMap1.setWrap(WrapMode.Repeat);
|
normalMap1.setWrap(WrapMode.Repeat);
|
||||||
@ -161,8 +237,8 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
List<Camera> cameras = new ArrayList<Camera>();
|
List<Camera> cameras = new ArrayList<Camera>();
|
||||||
cameras.add(getCamera());
|
cameras.add(getCamera());
|
||||||
terrain.setMaterial(matRock);
|
terrain.setMaterial(matRock);
|
||||||
terrain.setLocalScale(new Vector3f(5,5,5));
|
terrain.setLocalScale(new Vector3f(5, 5, 5));
|
||||||
terrain.setLocalTranslation(new Vector3f(0,-30,0));
|
terrain.setLocalTranslation(new Vector3f(0, -30, 0));
|
||||||
terrain.setModelBound(new BoundingBox());
|
terrain.setModelBound(new BoundingBox());
|
||||||
terrain.updateModelBound();
|
terrain.updateModelBound();
|
||||||
terrain.setLocked(false); // unlock it so we can edit the height
|
terrain.setLocked(false); // unlock it so we can edit the height
|
||||||
@ -171,7 +247,6 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
rootNode.attachChild(terrain);
|
rootNode.attachChild(terrain);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//This part is to emulate tides, slightly varrying the height of the water plane
|
//This part is to emulate tides, slightly varrying the height of the water plane
|
||||||
private float time = 0.0f;
|
private float time = 0.0f;
|
||||||
private float waterHeight = 0.0f;
|
private float waterHeight = 0.0f;
|
||||||
@ -180,6 +255,7 @@ public class TestPostWater extends SimpleApplication {
|
|||||||
@Override
|
@Override
|
||||||
public void simpleUpdate(float tpf) {
|
public void simpleUpdate(float tpf) {
|
||||||
super.simpleUpdate(tpf);
|
super.simpleUpdate(tpf);
|
||||||
|
// box.updateGeometricState();
|
||||||
time += tpf;
|
time += tpf;
|
||||||
waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
|
waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
|
||||||
water.setWaterHeight(initialWaterHeight + waterHeight);
|
water.setWaterHeight(initialWaterHeight + waterHeight);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user