Search code examples
openglprocessingjogl

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)


Solution

  • 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.