Author Topic: 2015/12/12 - Blockland r1983  (Read 46091 times)


Thanks for the updates. It's good to know that you haven't abandoned BL, not that anybody doubted you I'm assuming.

Any chance you'd be kind enough to fix GuiBitmapCtrl::getPixelColor?

Badspot

  • Administrator
Any chance you'd be kind enough to fix GuiBitmapCtrl::getPixelColor?

You need to actually describe the problem.

You need to actually describe the problem.
Time to resolve this mystery!

getPixelColor(x, y) is written very badly. Allow me to illustrate roughly what it's doing:

Code: [Select]
<wrapper for getPixelColor defined with ConsoleFunction>

...

void GuiBitmapCtrl::getPixelColor(int x, int y, ColorI* pOut)
{
     Canvas->renderFrame(false); //Render canvas children.
     Canvas->renderFrame(false); //It's called twice-- maybe for transparency, since glClear isn't called inbetween.

     //renderFrame renders to the back buffer and then swaps it to front.
     //Supposedly reading from the back buffer is undefined after a swap, but whatever. This is Blockland.
     glReadBuffer(GL_BACK);

     unsigned char pixel[3];
     glReadPixels(x + this->mBounds.point.x, y + this->mBounds.point.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);

     pOut->set(pixel[0], pixel[1], pixel[2]); //Alpha = 255
}

Summary: The code renders all the canvas contents twice (this includes the scene plus any active GUI controls), then reads a pixel from the back buffer using (Ctrl.position.x + arg_x, Ctrl.position.y + arg_y).

This seems somewhat logical for the most part, but recall that by default OpenGL uses the bottom left corner for the (0, 0) position. Controls in Blockland are positioned with the (0, 0) corner at the top left. Calling getPixelColor(5, 5) on a simple bitmap control located at (100, 100) will make this code evaluate glReadPixels(105, 105, ...), which will return incorrect data, since the y coordinate is flipped.

In conclusion, getPixelColor() sucks. It should return pixels based on the bitmap's texture data, not actual pixels rendered on the canvas.

Correct usage is something like this ((0, 0) being top left corner of control):

Code: [Select]
%py = getWord(TestBitmapControl.position, 1);
%yRes = getWord(getRes(), 1);

...

%RealY = 10;
%RealX = 10;

TestBitmapControl.getPixelColor(%RealX, -2 * %py + %yRes - %RealY);

Make sure your control is in view, I guess. Obviously I don't recommend this because you will be re-rendering the entire canvas twice for every call, which would badly hurt performance when scanning an entire image, even if it were 64x64.
Because of this it also takes around 21 minutes to scan a 640x640.

thanks for updating the steam news badspot

Because of this it also takes around 21 minutes to scan a 640x640.
what the hell

"Quote from: Val on December 31, 1969, 06:00:00 PM"

what

what the hell

"Quote from: Val on December 31, 1969, 06:00:00 PM"

what
quotes use UNIX time in order to determine the time when the post was made
jes probably just copy/pasted the post and put it in a quote and didn't bother to calculate the UNIX timestamp

And for whatever reason, it needs a date in order to be linked.

When you release r2000, please release v22.

release r2016 on january 1st

that'd be entertaining

I made a function that gets the correct pixel color, but it's still really slow.

Code: [Select]
function guiBitmapCtrl::getRealPixelColor(%obj, %x, %y)
{
%realY = -2 * getWord(%obj.getScreenPosition(), 1);
%realY += getWord(getRes(), 1) - %y;
%realY -= 1;

return %obj.getPixelColor(%x, %realY);
}

Because the getPixelColor function is junk, you need to be able to see the guiBitmapCtrl and it needs to be unobstructed by other GUI elements(don't think that the mouse can obstruct it).
« Last Edit: December 21, 2015, 01:39:06 PM by jes00 »

I made a function that gets the correct pixel color, but it's still really slow.

Code: [Select]
function guiBitmapCtrl::getRealPixelColor(%obj, %x, %y)
{
%realY = -2 * getWord(%obj.getScreenPosition(), 1);
%realY += getWord(getRes(), 1) - %y;
%realY -= 1;

return %obj.getPixelColor(%x, %realY);
}

Because the getPixelColor function is junk, you need to be able to see the guiBitmapCtrl and it needs to be unobstructed by other GUI elements(don't think that the mouse can obstruct it).
You can't fix this with torkscript, you'd just make it even slower. Badspot needs to change getPixelColor to read from the image instead.

I've noticed a pattern, it might help with debugging the load freezing. While frozen, dnetsetlogging(1); always looks like this:



There will always be one or more "not recv" between the large batches of packets. It's frozen until this missing packet finally arrives (or forever)
« Last Edit: December 22, 2015, 08:28:20 AM by Zeblote »

Since it's been a over a month since the runtime errors started occurring and there's been no visible progress (and no one has fixed it for him), does anyone have a link to the previous version? I want to host something for some friends for the holidays, but I don't want to keep resting every 10 minutes. If you don't want to post it here in fear of getting banned or whatever, could you PM me it?