New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webgl text #3110
Webgl text #3110
Conversation
} | ||
}; | ||
|
||
p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this code came from p5.Renderer2D.prototype.text
var textures = this.textures; | ||
for (var it = 0; it < textures.length; ++it) { | ||
var texture = textures[it]; | ||
if (texture.src === img) return texture; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using a for loop instead of Array.find()
which is really slow..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe indexOf would be faster? http://www.andygup.net/fastest-way-to-find-an-item-in-a-javascript-array/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think indexOf would work in this case since we're looking for the element that has a particular (src
) property. this is what find()
is intended for - apply a predicate to each element and return the first that matches. but the function call is really slow.
|
||
var gl = this._renderer.GL; | ||
// pull texture from data, make sure width & height are appropriate | ||
if (textureData.width !== this.width || textureData.height !== this.height) { | ||
updated = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using this flag to de-duplicate the texImage2D
code
@@ -0,0 +1,189 @@ | |||
#extension GL_OES_standard_derivatives : enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll comment this when we have glsl minification in the build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this file needs comments. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i added issue #3114
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and PR #3116
src/core/p5.Renderer.js
Outdated
@@ -44,6 +44,8 @@ p5.Renderer = function(elt, pInst, isMainCanvas) { | |||
this._textStyle = constants.NORMAL; | |||
this._textAscent = null; | |||
this._textDescent = null; | |||
this._textAlign = constants.LEFT; | |||
this._textBaseline = constants.BOTTOM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are stored here now, instead of as native 2d canvas properties.
Oh boy, this is my first time reviewing a PR....please bear with me 😬 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting this output on https://p5js.org/reference/#/p5/textLeading example in 2D on your build :
textAscent() also seems to give unexpected results in 2D mode :
Original | Now |
---|---|
* | ||
* the ImageInfos class holds a list of ImageDatas of a given size. | ||
*/ | ||
function ImageInfos(width, height) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering this is private, wouldn't it be better to make it _ImageInfos? Just like other private functions in p5.js? Also there are other functions like this one in this file (setPixel, FontInfo...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uh-oh, good catch on the 2d bugs, that definitely needs to be fixed.
as for the '_'s, i don't think this is necessary. those functions are all private to the 'text' module whose only export is the p5
object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, 1543600 should fix the alignment/metrics issues.
@kjhollen can you take a final look at this as well? 😀 |
i thought about adding a i added an example for as for adding a default font: it's a good idea, but i'm not sure how easy this would be to implement. do we always preload it before setup()? or do we add some async on-demand loading the first time it's required? do we load it from a fixed location on the internet (what if the machine is disconnected?), do we require it to be located in a specific location relative to the sketch? do we embed it as a base64-encoded binary (~35K for latin script) in the p5.js javascript? |
This seems a bit tricky. How is 2D mode handling this? I think it seems to be using a default web safe font? |
2d mode is using p5.js/src/core/p5.Renderer2D.js Line 31 in 0956fc9
|
@kjhollen @mlarghydracept Overall the implementation is working great! There is a problem of adding a default font. What do you suggest? |
if you need more checks for alignment, leading etc, some of the sketches in 'manual-test-examples' might be of use in verifying that 2d, 3d, and original processing are all producing the same results (test/manual-test-examples/p5.Font/custom/index.html for example)... |
thank you for the initial review, @AdilRabbani! I'm happy to take a deeper look at this—I'll do it next week once I settle in from moving a little more, if that works for you @Spongman? |
thanks everyone, no rush ;-) |
or @mlarghydracept can look sooner :) |
sorry about that - didn't mean to spam - travis got stuck for some reason on the last commit and i don't know any other way to re-trigger it. |
Okay I have been taking some more time with this and realize there are huge number of changes to look over. I will try to do a line-by-line this weekend but for now I have just managed to give it a broad-strokes once over. So far everything works really well but I have concerns that this structure in text.js may make future contributions difficult. Text rendering is a difficult task but I wonder if there are ways that this can be changed slightly to make it less intimidating to future contributors. Namely there is a high density of class declarations and utility functions. This may be unavoidable but it feels different than the rest of the library. Also, why the additions to the p5.Vector class? Maybe I am missing something but couldn't the static methods be used to accomplish this same task without adding to that class? |
the main reason i added the private fluent methods to p5.Vector was to make the vector math in the cubic approximation code easier to read. i originally had it with the static methods, but after the linter made a mess of things, i switched it to fluent. for example, there's a statement in var c = p5.Vector.sub(
p5.Vector.sub(p5.Vector.sub(this.p1, this.c1), a),
p5.Vector.mul(b, 2)
); and here's the same statement with the fluent interface: var c = this.p1
.minus(this.c1)
.minus(a)
.minus(b.times(2)); maybe it's just me, but I find it significantly easier to work out what's actually happening when reading the 2nd version mostly because it reads in my head identically to the math expression it's calculating. also, having private/undocumented methods in one part of the library that are used by another is not without precedent. |
Hm I see how that probably looks pretty convoluted with the static methods. I still don't really know if it is okay to add these fluent methods to p5.Vector just for this single use. So I have been trying to think about solutions to the default font issue. This feels like a pretty confusing roadbump for users. I haven't had any epiphanies but I want to keep up a conversation about it because it feels significant. It may be an inescapable aspect of the implementation, in which case we'd need to make sure that the reference clearly explains the need for a loaded font when using WebGL. |
@@ -1,11 +1,25 @@ | |||
var _webgl = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it looks like some browsers limit the number of concurrent webgl contexts. try edge, it doesn't do this.
ok, i don't mind changing it back to the static methods. the math is actually a little simpler than it used to be. |
travis stalled again, ugh. i rebased on to master (post webgl-gsoc-2018). |
I agree that there it feels that there should be somewhere for more elaborate documentation. Reference docs focus on clarity and simplicity. Not sure about the solution there, but for now I feel that this PR is ready to merge. @kjhollen have any interest in giving this a final glance before I merge? It is a pretty large addition. Thanks for your patience @Spongman! |
WebGL docs would need an update regarding WebGL text in p5.js. |
Good call @AdilRabbani! |
@Spongman just to clarify - I think that we can move forward with a merge. I have spoken with @kjhollen. The only thing that needs to happen before that is that we need to update the [developer_docs] (https://github.com/processing/p5.js/blob/master/developer_docs/webgl_mode_architecture.md) as per @AdilRabbani's suggestion. |
Okay! @Spongman Merging now. Thanks for the final touches, especially the additional comments. It helps demystify quite a lot. This is a large and well-considered contribution! Can you make an issue that addresses the default font when you get a chance? It seems that you have already done quite a bit of work to consider possible solutions and it would be good to document these for future contributors. |
fantastic, thanks for reviewing this! |
closes #2183
implements
text()
for the webgl renderer. most of the code is in src/webgl/text.js, however some other changes were required:p5.Renderer2D.prototype.text()
andtextAlign()
code into shared methods inp5.Renderer
, this necessitated:textAlign
andtextBaseline
properties so they are backed directly by variables in the renderer instead of being calculated based on canvas properties. this also simplifies the logic for those properties.push
/pop
,_applyTextProperties
methods to accommodate the above.p5.Font
methods to make them renderer-independent.p5.RendererGL.prototype.getTexture
which gets called a ton.p5.Texture
from anImageData
object.p5.Shader.prototype.updateTextures()
method that ensures all dirty textures are sent to the GPU.