sbook said:
Weird, if you trace it you end up here at LWJGLTextureRenderer:117
supportsMultiSample = GLContext.getCapabilities().GL_EXT_framebuffer_multisample;
I thought that you had got the shader working already in the other thread so its clearly not that your GPU doesn't support multisampling.. Have you tried injecting the pass gamestate creation in the OpenGL thread?
my card has the required support this code below works perfectly, its when I try to incorporate it as a gamestate in my Standard game app I get these issues :?
test
package test;
import java.awt.Color;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.FloatBuffer;
import java.util.logging.Logger;
import javax.print.attribute.standard.Finishings;
import pass.SketchOverRenderPass;
import jmetest.flagrushtut.Lesson2;
import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.Input;
import com.jme.input.InputHandler;
import com.jme.input.InputSystem;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.DirectionalLight;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.renderer.pass.OutlinePass;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.shape.RoundedBox;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
public class Main extends BaseGame {
private Logger log = Logger.getLogger(this.getClass().getName());
private int width = 800,
height = 500;
private Timer timer = Timer.getTimer();
private Renderer rend;
private Camera cam;
private Node scene;
private FirstPersonHandler fpHandler;
private KeyBindingManager kbm = KeyBindingManager.getKeyBindingManager();
private BasicPassManager pm = new BasicPassManager();
private SketchOverRenderPass srp;
private TerrainBlock tb;
@Override
protected void cleanup() {
// end game
}
@Override
protected void initSystem() {
// init window, camera, input system, etc.
display = DisplaySystem.getDisplaySystem();
display.createWindow(width, height, 32, 60, false);
rend = display.getRenderer();
cam = rend.createCamera(width, height);
cam.setFrustumPerspective(45.0f, (float)width / (float)height, 1, 3000);
Vector3f loc = new Vector3f(200.0f, 200.0f, 200.0f);
Vector3f left = new Vector3f(-0.5f, 0.0f, 0.5f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(-0.5f, 0.0f, -0.5f);
// Move our camera to a correct place and orientation.
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
scene = new Node("scene");
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
scene.setRenderState(buf);
rend.setCamera(cam);
rend.setBackgroundColor(ColorRGBA.yellow);
BlendState as = rend.createBlendState();
srp = new SketchOverRenderPass(cam, 2);
srp.setEnabled(true);
srp.add(scene);
RenderPass rp = new RenderPass();
rp.setEnabled(true);
rp.add(scene);
//pm.add(olp);
pm.add(rp);
pm.add(srp);
//pm.updatePasses(0);
fpHandler = new FirstPersonHandler(cam, 400, 1);
fpHandler.getKeyboardLookHandler().setEnabled(true);
fpHandler.getMouseLookHandler().setEnabled(true);
kbm.set("exit", KeyInput.KEY_ESCAPE);
kbm.set("o", KeyInput.KEY_O);
}
@Override
protected void initGame() {
// all game or scene data is set up
buildLighting();
buildTerrain();
scene.attachChild(tb);
scene.updateGeometricState(0f, true);
scene.updateRenderState();
Sphere s = new Sphere("sphere", 30, 30, 20);
s.setLocalTranslation(new Vector3f(100, 200, 100));
s.setModelBound(new BoundingBox());
MaterialState color = rend.createMaterialState();
color.setColorMaterial(MaterialState.ColorMaterial.None);
color.setAmbient(ColorRGBA.red);
color.setMaterialFace(MaterialState.MaterialFace.Front);
color.setEnabled(true);
s.setRenderState(color);
s.updateRenderState();
s.updateModelBound();
s.updateGeometricState(0, true);
scene.attachChild(s);
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
}
@Override
protected void reinit() {
// system setting are changed (e.g. change in resolution)
}
@Override
protected void render(float interpolation) {
// render the sali-boy
interpolation = timer.getTimePerFrame();
rend.clearBuffers();
pm.renderPasses(rend);
}
@Override
protected void update(float interpolation) {
// main frame to frame update method
timer.update();
interpolation = timer.getTimePerFrame();
pm.updatePasses(interpolation);
fpHandler.update(interpolation);
if(kbm.isValidCommand("exit"))
finished = true;
if(kbm.isValidCommand("o")) {
rend.takeScreenShot("screenshot1`");
}
}
public static void main(String [] args) {
BaseGame game = new Main();
game.start();
}
private void buildTerrain() {
MidPointHeightMap heightMap = new MidPointHeightMap(64, 0.5f);
Vector3f terrainScale = new Vector3f(20, 1, 20);
tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale, heightMap.getHeightMap(), new Vector3f(0, 0, 0));
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
TextureState ts = rend.createTextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.loadTexture("/data/textures/scene/highest.jpg",
Texture.MinificationFilter.Trilinear,
Texture.MagnificationFilter.Bilinear));
tb.setRenderState(ts);
tb.updateRenderState();
}
private void buildLighting() {
PointLight light = new PointLight();
light.setLocation(new Vector3f(0, 10000, 0));
light.setAmbient(ColorRGBA.white);
light.setDiffuse(ColorRGBA.white);
light.setEnabled(true);
/** Attach the light to a lightState and the lightState to rootNode. */
LightState lightState = display.getRenderer().createLightState();
lightState.attach(light);
lightState.setGlobalAmbient(ColorRGBA.white);
lightState.setEnabled(true);
scene.setRenderState(lightState);
}
}
pass
package pass;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.pass.Pass;
import com.jme.scene.Spatial;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jmex.effects.glsl.SketchRenderPass;
/**
* GLSL sketch effect pass.
* - Render supplied source to a texture
* - Render normals and depth to texture
* - Apply sobel filter to find changes is normal and depth
* - (Blur if wanted, slow)
* - Overwrite or blend with first pass
*
* @author Rikard Herlitz (MrCoder)
*/
public class SketchOverRenderPass extends Pass {
private static final long serialVersionUID = 1L;
private TextureRenderer tRendererDepth;
private Texture2D textureDepth;
private Quad fullScreenQuad;
private GLSLShaderObjectsState sobelShader;
private GLSLShaderObjectsState normShader;
private float normalMult = 10.5f;
private float depthMult = 1250.0f;
private float off = 0.0001f;
private boolean supported = true;
protected RenderState[] preStates = new RenderState[RenderState.StateType.values().length];
/**
* Reset sketch parameters to default
*/
public void resetParameters() {
normalMult = 22.5f;
depthMult = 1850.0f;
off = 0.0009f;
}
/**
* Release pbuffers in TextureRenderer's. Preferably called from user cleanup method.
*/
public void cleanup() {
tRendererDepth.cleanup();
}
public boolean isSupported() {
return supported;
}
public SketchOverRenderPass(Camera cam, int renderScale) {
//Test for glsl support
if(!GLSLShaderObjectsState.isSupported()) {
supported = false;
return;
}
DisplaySystem display = DisplaySystem.getDisplaySystem();
resetParameters();
//Create texture renderers and rendertextures for depth (only needed for some nvidia cards, like mine)
tRendererDepth = display.createTextureRenderer(
display.getWidth() / renderScale,
display.getHeight() / renderScale,
TextureRenderer.Target.Texture2D);
tRendererDepth.setBackgroundColor(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f));
tRendererDepth.setCamera(cam);
textureDepth = new Texture2D();
textureDepth.setWrap(Texture.WrapMode.Clamp);
textureDepth.setMagnificationFilter(Texture.MagnificationFilter.Bilinear);
tRendererDepth.setupTexture(textureDepth);
//Create extract normals and depth shader
normShader = display.getRenderer().createGLSLShaderObjectsState();
normShader.load(SketchRenderPass.class.getClassLoader().getResource("data/shader/pass/sketch_norm.vert"),
SketchRenderPass.class.getClassLoader().getResource("data/shader/pass/sketch_norm.frag"));
normShader.setEnabled(true);
normShader.setUniform("nearClip", cam.getFrustumNear());
normShader.setUniform("diffClip", cam.getFrustumFar() - cam.getFrustumNear());
//Create sobel shader
sobelShader = display.getRenderer().createGLSLShaderObjectsState();
sobelShader.load(SketchRenderPass.class.getClassLoader().getResource("data/shader/pass/sketchover_sobel.vert"),
SketchRenderPass.class.getClassLoader().getResource("data/shader/pass/sketchover_sobel.frag"));
sobelShader.setEnabled(true);
//Create fullscreen quad
fullScreenQuad = new Quad("FullScreenQuad", display.getWidth(), display.getHeight());
fullScreenQuad.getLocalRotation().set(0, 0, 0, 1);
fullScreenQuad.getLocalTranslation().set(display.getWidth() / 2, display.getHeight() / 2, 0);
fullScreenQuad.getLocalScale().set(1, 1, 1);
fullScreenQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
fullScreenQuad.setCullHint(Spatial.CullHint.Never);
fullScreenQuad.setTextureCombineMode(TextureCombineMode.Replace);
fullScreenQuad.setLightCombineMode(Spatial.LightCombineMode.Off);
TextureState ts = display.getRenderer().createTextureState();
ts.setEnabled(true);
fullScreenQuad.setRenderState(ts);
BlendState as = display.getRenderer().createBlendState();
as.setBlendEnabled(true);
as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
as.setEnabled(true);
fullScreenQuad.setRenderState(as);
fullScreenQuad.updateRenderState();
fullScreenQuad.updateGeometricState(0.0f, true);
//setup shader for extracting normals and depth
noTexture = display.getRenderer().createTextureState();
noTexture.setEnabled(false);
noLights = display.getRenderer().createLightState();
noLights.setEnabled(false);
noMaterials = display.getRenderer().createMaterialState();
noMaterials.setEnabled(false);
}
protected static TextureState noTexture;
protected static LightState noLights;
protected static MaterialState noMaterials;
public void doRender(Renderer r) {
if(spatials.size() != 1) return;
//Render scene to normals and depth
saveEnforcedStates();
context.enforceState(noTexture);
context.enforceState(noLights);
context.enforceState(noMaterials);
context.enforceState(normShader);
tRendererDepth.render(spatials.get(0), textureDepth);
replaceEnforcedStates();
TextureState ts = (TextureState) fullScreenQuad.getRenderState(RenderState.StateType.Texture);
//Apply sobel as final render
sobelShader.clearUniforms();
sobelShader.setUniform("depth", 0);
sobelShader.setUniform("normalMult", getNormalMult());
sobelShader.setUniform("depthMult", getDepthMult());
sobelShader.setUniform("off", getOff());
ts.setTexture(textureDepth, 0);
fullScreenQuad.setRenderState(sobelShader);
fullScreenQuad.updateRenderState();
r.draw(fullScreenQuad);
}
/**
* saves any states enforced by the user for replacement at the end of the
* pass.
*/
protected void saveEnforcedStates() {
for(int x = RenderState.StateType.values().length; --x >= 0;) {
preStates[x] = context.enforcedStateList[x];
}
}
/**
* replaces any states enforced by the user at the end of the pass.
*/
protected void replaceEnforcedStates() {
for(int x = RenderState.StateType.values().length; --x >= 0;) {
context.enforcedStateList[x] = preStates[x];
}
}
public float getNormalMult() {
return normalMult;
}
public void setNormalMult(float normalMult) {
this.normalMult = normalMult;
}
public float getDepthMult() {
return depthMult;
}
public void setDepthMult(float depthMult) {
this.depthMult = depthMult;
}
public float getOff() {
return off;
}
public void setOff(float off) {
this.off = off;
}
}