Image pixels y problem

Preface

I’m a professional game programmer, I’m using JUCE in my personal time, specifically for #devember. I’ve never used it. I choose it because of the audio management code.

The problem

Here you can see the problem https://cdn.discordapp.com/attachments/176695674262257665/784880086599860234/unknown.png .
I’m testing the software way of manipulation of an image and clearly the y is drunk. I’ve also tested drawing with different functions, positions and scales: https://cdn.discordapp.com/attachments/176695674262257665/784891050925228062/unknown.png

What am I doing wrong?

I’m on linux, latest build of JUCE, 1 dec 2020.

Here’s the repo https://bitbucket.org/theGiallo/spectral_painter .

I’m really lost and I could turn back to my happy crappy opengl code with fast compilation times and hot reload. Please help me. Thank you.

I don’t know how it’s supposed to look, but just in case -in Juce, 0,0 is top-left, x goes left to right, y goes top to bottom.

Well, we can’t see the code that is actually being executed here, because tick_tock is always 1, which is always less than 240/2. So the else block will execute, and we can’t see that code here.

If the code shown were executed, though, it would always give greyscale values (x01 * 255 for r, g and b), because, again, tick_tock is always 1, which is always less than 240 / 2 + 240 / 4.

What are you trying to do?

So, here tick_tock, is used to generate a temporal partitioning to have many different images, looping in time. That variable is incremented each update and it’s looped back once it reaches the end value. I’m used to write this kind of stuff on shadertoy.com. Here I’m choosing the color of each pixel based on it’s coordinates. I’m doing this to test that the pixels are where I think they to be. Using only the x as grayscale works correctly. Using only the y should generate the same image but rotated, instead it’s the image you can see linked above.

But that is not what the code your screen shot showed is doing. We can’t guess what might be wrong without the actual code that replicates the problem.

Oh, I’ve linked the whole code. Let me link the actual line https://bitbucket.org/theGiallo/spectral_painter/src/master/spectral_painter/Source/MainComponent.cpp#lines-120

One thing I would suggest would be to generate the image separately from your paint() function, and simply draw the image into the graphic context in paint(). You never know when or how often a paint() function will be called. Many things can trigger a call to paint(). I haven’t analyzed the code any further than that yet, but generating the image in a loop or via a timer (and then calling repaint() immediately after generating its content) is much more likely to give you consistent results.

I’m calling repaint() in the timer callback set to 60Hz. I’ve looked into using an AsyncUpdater for that, but I had problems. I’m used to a game loop, so this timer feels strange to me, but searching online told me that it’s the way to go in JUCE.

You’re missing my point, and the purpose of repaint(). The repaint() function only sets a “dirty” flag for the component, so that at some point in the (near) future, the OS knows that that portion of the screen needs painting. It does not directly call paint(). The paint() function gets called in a number of different conditions, not under your control, and OS dependent.

As I said, you probably should be regenerating your image in a member function called from your timer callback, and then calling repaint(), not regenerating the image within paint() itself.

(I would also make tick_tock a member as well, instead of a static variable. Statics can cause problems, especially in audio plugins, which share static memory between instances.)

2 Likes

Oh, yes. I noticed that repaint does nothing more than setting a dirty flag. Yes, tick_tock in paint has not the expected behaviour of 60Hz increment. tick_tock was a temporary way of debugging, meant to die soon, but I’ll move it in.
I’ve done the restructuring and pushed it. No differences in the graphic result.

I see that you have two variables named h defined in the same scope, one on line 136, and one (uninitialized) on line 141. Then you do that again later, with one defined on line 181, and one (uninitialized) on line 206.

I exported to Xcode (because I don’t have Linux), and it warned about those variables being used while uninitialized (on line 143 and again on line 208). I don’t know if you get warnings in your make builds, but always pay attention to warnings like that.

Fixing those should resolve your issue. (It did for me.)

1 Like

I’ve just read the code from the browser and… omg you’re right, I use h as in height after I’ve declared the other h as in hue. Just coding beeing sleepy has these effects :sweat_smile:

I love you man.

Btw, no, I’ve not touched the warning flags. Usually I have all the warnings up.

1 Like

I’ve set up the flags but strangely the warning doesn’t come up, even without the -flto, that seems to disable it. Compiling just a function with the error manually or in goldbolt, makes the error show up. Strange. https://thegiallo-en.tumblr.com/post/636894524319383552/devember-2020-day-6-spectral-painter-eureka

I glanced at your page there, and saw you noticed that setPixelAt() is gosh-awful slow. That is quite true. Much faster to access the data directly than through that call. I’m surprised the JUCE SDK doesn’t mention that. If doing it with any frequency, better to never use that call if you don’t have to.

Yes. I thought that the function would do the same work and that it would have been optimized by the compiler, but probably it has bound checks that inhibit that, so no vectorization happens.