processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.1k stars 3.22k forks source link

textFont() doesn't work for WebGL outside of preload() for loading fonts unlike P2D which isn't specified #7028

Closed RandomGamingDev closed 1 month ago

RandomGamingDev commented 1 month ago

Most appropriate sub-area of p5.js?

p5.js version

1.9.3

Web browser and version

115.6.0esr

Operating system

Debian 12

Steps to reproduce this

Steps:

  1. Create a WebGL canvas
  2. Set a font using textFont as requested by the error, but not in the preload() function: WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.
  3. Try to draw text and get the error: WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.

Snippet:

function setup() {
  createCanvas(100, 100, WEBGL);

  background(200);
  textFont('Courier New');
  textSize(24);
  text('hi', 35, 55);

  describe('The text "hi" written in a black, monospace font on a gray background.');
}
RandomGamingDev commented 1 month ago

This should be better clarified in the error message since using textFont() outside of preload() is valid in P2D/Canvas mode or work outside of the preload() function (I doubt that's the path we should go down though). The fact that textFont() only works in preload() mode isn't even present on its documentation page

davepagurek commented 1 month ago

I think this error is misleading but for a different reason: it's allowed in setup, but in WebGL, you must use a loadFont font instead of a font name string.

RandomGamingDev commented 1 month ago

I think this error is misleading but for a different reason: it's allowed in setup, but in WebGL, you must use a loadFont font instead of a font name string.

Yeah, I didn't differentiate between loading an already loaded font and loading a new font so I changed the updated more specific error msg of the PR to be:

WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` (both of which have to be executed in preload() for WebGL mode when loading a new font) for more details.
davepagurek commented 1 month ago

both of which have to be executed in preload() for WebGL mode when loading a new font

Is this true? I think textFont works outside of preload, e.g. in https://openprocessing.org/sketch/2241717

RandomGamingDev commented 1 month ago

both of which have to be executed in preload() for WebGL mode when loading a new font

Is this true? I think textFont works outside of preload, e.g. in https://openprocessing.org/sketch/2241717

That example is of textFont() loading an already loaded font. When loading a new font like 'Courier New' in WEBGL mode textFont() has to be used in preload().

davepagurek commented 1 month ago

I'm not sure I'm following the distinction between an already loaded font and a new font. I don't think we support string font names at all in WebGL, which is what the current error message is trying to say. If you set the font to a string font in preload, I don't think it will have direct behavior even though it doesn't give an error -- it just doesn't know yet that you're trying to create a WebGL sketch.

RandomGamingDev commented 1 month ago

I'm not sure I'm following the distinction between an already loaded font and a new font. I don't think we support string font names at all in WebGL, which is what the current error message is trying to say. If you set the font to a string font in preload, I don't think it will have direct behavior even though it doesn't give an error -- it just doesn't know yet that you're trying to create a WebGL sketch.

Ah, I see. It looks like what's actually going on here is it's creating a WebGL canvas in the preload function before ignoring it and creating a P2D canvas automatically without a createCanvas() statement which is how the font's actually getting loaded with no errors reporting what happened.

Example Code:

// WEBGL Example
function preload() {
  createCanvas(100, 100, WEBGL); // In WebGL textFont has to be executed in preload
  textFont('Courier New');
}

function setup() {
  background(200);
  textSize(24);
  text('hi', 35, 55);

  describe('The text "hi" written in a black, monospace font on a gray background.');
}

Sketch: https://editor.p5js.org/PotatoBoy/sketches/fSU62FlS3

RandomGamingDev commented 1 month ago

Sorry about that, I didn't know that it would automatically create a P2D canvas alongside the WebGL canvas explicitly created and then use that instead if I tried to use textFont(). I've closed the PR and I'm closing the issue now.

davepagurek commented 1 month ago

Ah ok, yeah it's pretty confusing that that example still renders a canvas! Just the wrong one. Definitely open to suggestions on how to make that clearer (maybe catching instances of canvases created in preload, since I think the library assumes it will only be made in setup?)

RandomGamingDev commented 1 month ago

Ah ok, yeah it's pretty confusing that that example still renders a canvas! Just the wrong one. Definitely open to suggestions on how to make that clearer (maybe catching instances of canvases created in preload, since I think the library assumes it will only be made in setup?)

Yeah, adding a check for whether or not a canvas has been created in preload() and adding a note to the preload() page's documentation sounds great, but I'm not sure if the library only assumes that it'll be made in setup since there isn't any documentation against it and it does work.