Stretch JmeCanvasContext? or OpenGL shader to a jMonkey shader?

I am trying to create a application with a resolution 640 x 480 but displayed in a JFrame or Applet that is 800 x 600. I want each pixcle in the application doubled so instead of 1 x1 they are 2 x 2 does this make since? the idea is to create a pixcilized 3D environment giving the effect of an old low resolution game in a window that is of a reasonable size.

Heres an example of the effect I am looking for…

Secret of Mana I think was originally 320 x 240 but this image is 640 x 480

What I attempted was to set the AppSettings resolution to 640 x 480 and the JmeCanvasContext preferred size to 800 x 600. [FAIL]


Ok I found something that would work but I don’t know how to convert a OpenGL shader to a jMonkey shader a point in the right direction would be helpful.

Link to shader I found →

you don’t really need a shader here.

What i would do is to resize the cam to 640x480 and render the scene to a frame buffer. set the mag filter of the texture to nearest

then render a full sreen quad at full resolution and map the texture on it.

You can use the ColorOverlayFilter Material.

I made a quick test here


package mygame;


import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;


import com.jme3.renderer.Camera;

import com.jme3.renderer.RenderManager;

import com.jme3.renderer.Renderer;

import com.jme3.renderer.ViewPort;

import com.jme3.renderer.queue.RenderQueue;

import com.jme3.scene.Spatial;

import com.jme3.scene.control.AbstractControl;

import com.jme3.scene.control.Control;

import com.jme3.texture.FrameBuffer;

import com.jme3.texture.Image.Format;

import com.jme3.texture.Texture.MagFilter;

import com.jme3.texture.Texture2D;

import com.jme3.ui.Picture;

public class PixelationTest extends SimpleApplication {

public static void main(String[] args) {

PixelationTest app = new PixelationTest ();




public void simpleInitApp() {

Spatial s = assetManager.loadModel(“Models/Teapot/Teapot.obj”);


/** A white, directional light source */

DirectionalLight sun = new DirectionalLight();

sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());



cam.resize(320, 240, true);

s.addControl(new AbstractControl() {


protected void controlUpdate(float tpf) {

getSpatial().rotate(0, tpf, 0);



protected void controlRender(RenderManager rm, ViewPort vp) {


public Control cloneForSpatial(Spatial spatial) {

return null;





MyProcessor proc = new MyProcessor(1024, 768);




public void simpleUpdate(float tpf) {



public void simpleRender(RenderManager rm) {

//TODO: add render code


class MyProcessor implements SceneProcessor {

ViewPort vp;

int renderWidth;

int renderHeight;

Picture fsQuad = new Picture(“fullscreenquad”);

FrameBuffer buffer;

Texture2D sceneTexture;

Camera filterCam = new Camera(1, 1);

public MyProcessor(int renderWidth, int renderHeight) {

this.renderWidth = renderWidth;

this.renderHeight = renderHeight;


public void initialize(RenderManager rm, ViewPort vp) {

this.vp = vp;

int width = vp.getCamera().getWidth();

int height = vp.getCamera().getHeight();

//creating the frame buffer

buffer = new FrameBuffer(width, height, 1);


//creating the texture

sceneTexture = new Texture2D(width, height, Format.RGBA8);

//setting the mag filter to nearest (that’s where we get the pixelisation effect)



fsQuad.setMaterial(new Material(assetManager, “Common/MatDefs/Post/Overlay.j3md”));

fsQuad.getMaterial().setTexture(“Texture”, sceneTexture);

fsQuad.getMaterial().setColor(“Color”, ColorRGBA.White);

//set the viewport to render to this framebuffer



public void reshape(ViewPort vp, int w, int h) {


public boolean isInitialized() {

return vp != null;


public void preFrame(float tpf) {


public void postQueue(RenderQueue rq) {


public void postFrame(FrameBuffer out) {




filterCam.resize(renderWidth, renderHeight, true);

fsQuad.setPosition(0, 0);


renderManager.setCamera(filterCam, true);

//render to screen setting framebuffer to null


renderManager.getRenderer().clearBuffers(true, true, true);



renderManager.setCamera(vp.getCamera(), false);


private void displayShadowMap(Renderer r) {

Camera cam = viewPort.getCamera();

renderManager.setCamera(cam, true);


int h = cam.getHeight();

fsQuad.setPosition(64 + 128, h / 20f);





renderManager.setCamera(cam, false);



public void cleanup() {





I render the scene at 320x240 and display it at 1024x768.

1 Like