How can I achieve noSmooth() with the P3D renderer?

I'd like to render basic 3D shapes without any aliasing/smoothing with a PGraphics instance using the P3D renderer, but noSmooth() doesn't seem to work.

In OF I remember calling setTextureMinMagFilter(GL_NEAREST,GL_NEAREST); on a texture.

What would be the equivalent in Processing ?

I tried to use PGL:

PGL.TEXTURE_MIN_FILTER = PGL.NEAREST;
PGL.TEXTURE_MAG_FILTER = PGL.NEAREST;

but I get a black image as the result. If I comment PGL.TEXTURE_MIN_FILTER = PGL.NEAREST; I can see the render, but it's interpolated, not sharp.

Here'a basic test sketch with a few things I've tried:

PGraphics buffer;
PGraphicsOpenGL pgl;

void setup() {
  size(320, 240, P3D);
  noSmooth();
  //hint(DISABLE_TEXTURE_MIPMAPS);

  //((PGraphicsOpenGL)g).textureSampling(0);

  //PGL pgl = beginPGL();
  //PGL.TEXTURE_MIN_FILTER = PGL.NEAREST;
  //PGL.TEXTURE_MAG_FILTER = PGL.NEAREST;
  //endPGL();

  buffer=createGraphics(width/8, height/8, P3D);
  buffer.noSmooth();
  buffer.beginDraw();
  //buffer.hint(DISABLE_TEXTURE_MIPMAPS);
  //((PGraphicsOpenGL)buffer).textureSampling(0);
  PGL bpgl = buffer.beginPGL();
  //PGL.TEXTURE_MIN_FILTER = PGL.NEAREST;//commenting this back in results in a blank buffer
  PGL.TEXTURE_MAG_FILTER = PGL.NEAREST;
  buffer.endPGL();
  buffer.background(0);
  buffer.stroke(255);
  buffer.line(0, 0, buffer.width, buffer.height);
  buffer.endDraw();
}
void draw() {

  image(buffer, 0, 0, width, height);
}

(I've also posted on the Processing Forum, but no luck so far)


You were actually on the right track. You were just passing the wrong value to textureSampling().

Since the documentation on PGraphicsOpenGL::textureSampling() is a bit scarce to say the least. I decided to peak into it using a decompiler, which lead me to Texture::usingMipmaps(). There I was able to see the values and what they reflected (in the decompiled code).

2 = POINT
3 = LINEAR
4 = BILINEAR
5 = TRILINEAR

Where PGraphicsOpenGL's default textureSampling is 5 (TRILINEAR).

I also later found this old comment on an issue equally confirming it.

So to get point/nearest filtering you only need to call noSmooth() on the application itself, and call textureSampling() on your PGraphics.

size(320, 240, P3D);
noSmooth();

buffer = createGraphics(width/8, height/8, P3D);
((PGraphicsOpenGL) buffer).textureSampling(2);

So considering the above, and only including the code you used to draw the line and drawing buffer to the application. Then that gives the following desired result.


I needed to combine both GL_LINEAR and GL_NEAREST with one shader so the ((PGraphicsOpenGL) buffer).textureSampling(2); was no option.

It was some digging, but this works for me:

PGL pgl = beginPGL();
Texture ascii_map_tex = ((PGraphicsOpenGL)g).getTexture(ascii_map);
pgl.bindTexture(PGL.TEXTURE_2D, ascii_map_tex.glName);
pgl.texParameteri(PGL.TEXTURE_2D, PGL.TEXTURE_MIN_FILTER, PGL.NEAREST);
pgl.texParameteri(PGL.TEXTURE_2D, PGL.TEXTURE_MAG_FILTER, PGL.NEAREST);
pgl.bindTexture(PGL.TEXTURE_2D, 0);
endPGL();