Skip to content
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

DrawNode graphical artifacts #2140

Closed
rh101 opened this issue Sep 13, 2024 · 17 comments · Fixed by #2158
Closed

DrawNode graphical artifacts #2140

rh101 opened this issue Sep 13, 2024 · 17 comments · Fixed by #2158
Milestone

Comments

@rh101
Copy link
Contributor

rh101 commented Sep 13, 2024

  1. Build cpp-tests and run on device
  2. Go to test 29:Node: Draw
  3. Navigate to test 6: Morphing. This test is random, so if you do not see any glitches, then go back to test 5, and then go to test 6 again until the issue is visible.

The following are video recordings (MP4 format) of the issues:

https://github.com/user-attachments/assets/e6e67862-50c7-4bbc-9f2a-f2b26ed0a23f
https://github.com/user-attachments/assets/a1ce5e9d-f737-4de5-8327-be35d852ed6c

Aside from these, I'm now seeing random problems in my own app related to the new DrawNode implementation, and it seems to only be happening on Android. It is random though, so it may be happening on other platforms too.

The correct output is this:
image

What I'm actually seeing is random output like this:
image
and
image

The methods used to create the above circles are:

void DrawNode::drawSolidCircle(const Vec2& center,
                               float radius,
                               float angle,
                               unsigned int segments,
                               float scaleX,
                               float scaleY,
                               const Color4B& color)

and for the black circle outline:

void DrawNode::drawCircle(const Vec2& center,
                          float radius,
                          float angle,
                          unsigned int segments,
                          bool drawLineToCenter,
                          float scaleX,
                          float scaleY,
                          const Color4B& color,
                          float thickness)
@rh101
Copy link
Contributor Author

rh101 commented Sep 13, 2024

@aismann Any thoughts on this issue?

@aismann
Copy link
Contributor

aismann commented Sep 13, 2024

I will have a look.
Any other drawing Methode?
E.g. the white boxes (one white box and lot of lines? Or lot of small boxes?
How is the blue background drawing?
All draws on one drawnode?

@rh101
Copy link
Contributor Author

rh101 commented Sep 14, 2024

I will have a look. Any other drawing Methode? E.g. the white boxes (one white box and lot of lines? Or lot of small boxes? How is the blue background drawing? All draws on one drawnode?

The blue background is just a Sprite created from an image file.

A single DrawNode is used for all items:

  • The solid white rectangles are drawn via DrawNode::drawSolidRect
  • The circles are drawn via DrawNode::drawSolidCircle with a black border created using DrawNode::drawCircle
  • The black lines for the grid are drawn via DrawNode::drawLine

This is how it is all used:

const auto renderer = Director::getInstance()->getRenderer();

auto* renderTexture = RenderTexture::create(static_cast<int>(panelSize.width), static_cast<int>(panelSize.height), true);
renderTexture->beginWithClear(0, 0, 0, 0);

const auto layerColor = LayerColor::create(Color4B::WHITE, someWidth, someHeight);
layerColor->setIgnoreAnchorPointForPosition(false);
const auto drawNode = DrawNode::create();
layerColor->addChild(drawNode);

// drawnode calls here

layerColor->visit();
renderTexture->end();
renderer->render();

auto gridSprite = Sprite::createWithTexture(renderTexture->getSprite()->getTexture());
gridSprite->setFlippedY(true);
addChild(gridSprite);

@aismann
Copy link
Contributor

aismann commented Sep 14, 2024

Thickness is always 1.0f (the default)?
Draworder is the default too?

@rh101
Copy link
Contributor Author

rh101 commented Sep 14, 2024

Thickness is always 1.0f (the default)? Draworder is the default too?

The line thickness is never changed.

I'm not sure what you mean by draw order.

I'll expand on the code some more. What you see below is almost the exact code used:

const auto renderer = Director::getInstance()->getRenderer();

auto* renderTexture = RenderTexture::create(static_cast<int>(panelSize.width), static_cast<int>(panelSize.height), true);
renderTexture->beginWithClear(0, 0, 0, 0);

const auto layerColor = LayerColor::create(Color4B::WHITE, someWidth, someHeight);
layerColor->setIgnoreAnchorPointForPosition(false);
const auto drawNode = DrawNode::create();
layerColor->addChild(drawNode);

for (.... loop through rows here...)
{
    for (... loop through columns here ...)
    {
        drawNode->drawSolidRect(..., Color4F::WHITE);
        if (someCondition == true)
        {
            drawNode->drawSolidCircle(..., columnWidth / 2, 0, 36, 0.8f, 0.8f, Color4F::GREEN);
            drawNode->drawCircle(..., columnWidth / 2, 0, 36, false, 0.8f, 0.8f, Color4F::BLACK);
        }
    }
}

auto currentX = 0.f;
auto currentY = 0.f;

for (size_t i = 0; i < columns + 1; i++)
{
    drawNode->drawLine(Vec2(currentX, 0), Vec2(currentX, size.height), Color4F::BLACK);
    currentX += columnWidth;
}

for (size_t i = 0; i < rows + 1; i++)
{
    drawNode->drawLine(Vec2(0, currentY), Vec2(size.width, currentY), Color4F::BLACK);
    currentY += rowHeight;
}

layerColor->visit();
renderTexture->end();
renderer->render();

auto gridSprite = Sprite::createWithTexture(renderTexture->getSprite()->getTexture());
gridSprite->setFlippedY(true);
addChild(gridSprite);

There is nothing else besides the above code to generate the problem. Sometimes there is no problem, and everything renders correctly, but other times there are artifacts, exactly the ones as can be seen in the screenshots above.

Note that I just noticed 29:Node: Draw, test 5 in cpp-tests also has problems. You just need to keep going back and forth from test 4 to test 5 until you see the issue. Random lines appearing on the screen.

@aismann
Copy link
Contributor

aismann commented Sep 14, 2024

drawNode->drawSolidCircle(..., columnWidth / 2, 0, 36, 0.8f, 0.8f, Color4F::GREEN);
drawNode->drawCircle(..., columnWidth / 2, 0, 36, false, 0.8f, 0.8f, Color4F::BLACK);

For a better performance you should use:

  1. Color4B::xxx
  2. Solid circle with border like:
    drawNode->drawSolidCircle(center, 30, 0, 361, 0.8f, 0.8f, Color4B::GREEN, 1.0f, Color4B::BLACK);

image

About:

Note that I just noticed 29:Node: Draw, test 5 in cpp-tests also has problems. You just need to keep going back and forth from > test 4 to test 5 until you see the issue. Random lines appearing on the screen.

Its enough you reset the test (green solid circle in the middle below) for getting this sporadic artefacts>
=> The reason is the vertices are overlapping (I will write better test data)

Anyhow there is another bug: fixed with PR: #2145
drawNode->drawSolidCircle(center, 30, 0, 36, 0.8f, 0.8f, Color4B::GREEN, 1.0f, Color4B::BLACK);

image

@rh101
Copy link
Contributor Author

rh101 commented Sep 14, 2024

For a better performance you should use:

1. `Color4B::xxx`
2. `Solid circle with border` like:
   `drawNode->drawSolidCircle(center, 30, 0, 361, 0.8f, 0.8f, Color4B::GREEN, 1.0f, Color4B::BLACK);`

The option to use Color4B and pass the border color to the drawSolidCircle method did not exist in the original DrawNode API when this code was written years ago, and this code hasn't been touched since. I gather that the new handy methods were added recently in this new DrawNode implementation? Thanks for the tips.

@aismann
Copy link
Contributor

aismann commented Sep 14, 2024

Color4B::xxx

See CHANGELOG.md: axmol-1.0.0 Aug.9 2023
[REFINE] Change DrawNode api color parameters from Color4F to low Color4B

Solid circle with border like:
drawNode->drawSolidCircle(center, 30, 0, 361, 0.8f, 0.8f, Color4B::GREEN, 1.0f, Color4B::BLACK);

Yes its new with DrawNode V2.
There will come some more I belive

@halx99 halx99 linked a pull request Sep 14, 2024 that will close this issue
6 tasks
@halx99 halx99 added this to the 2.2.0 milestone Sep 14, 2024
@aismann
Copy link
Contributor

aismann commented Sep 15, 2024

@rh101
I modified your example a little bit:
Can you test it plz?
Goal is to get the "fragments" again.
image

...
    const auto drawNode = DrawNode::create();
    addChild(drawNode);

    drawNode->properties.setPosition(center / 2);

    int columnWidth = 20;
    float stoneSize = columnWidth / 2;
    int columns     = 10;
    int rows        = 10;

    drawNode->drawSolidRect(Vec2(0, 0), Vec2(columnWidth * columns, columnWidth * columns), Color4F::WHITE);
    for (size_t x = 0; x < columns; x++)
    {
        for (size_t y = 0; y < rows; y++)
        {
            //  if (someCondition == true)
            {
                Vec2 pos = Vec2(columnWidth * x, columnWidth * y) + Vec2(stoneSize, stoneSize); 
                drawNode->drawSolidCircle(pos, stoneSize, 0, 36, 0.8f, 0.8f, Color4F::GREEN, 1.0f, Color4F::BLACK);
              //  drawNode->drawCircle(pos, stoneSize, 0, 36, false, 0.8f, 0.8f, Color4F::BLACK);
            }
        }
    }
    for (size_t i = 0; i < columns + 1; i++)
    {
        drawNode->drawLine(Vec2(i * columnWidth, 0), Vec2(i * columnWidth, columnWidth * columns), Color4F::BLACK);
    }

    for (size_t i = 0; i < rows + 1; i++)
    {
        drawNode->drawLine(Vec2(0, i * columnWidth), Vec2(columnWidth * rows, i * columnWidth), Color4F::BLACK);
    }
...

@aismann
Copy link
Contributor

aismann commented Sep 15, 2024

@rh101
Another idea is to make this project private and let me accsess to it for debuging.
I need only the artifact...not the game (You can remove all what is not needed if you want)

@rh101
Copy link
Contributor Author

rh101 commented Sep 15, 2024

Another idea is to make this project private and let me accsess to it for debuging.
I need only the artifact...not the game (You can remove all what is not needed if you want)

That is not possible, but I should be able to create a test project, which I'll post up soon.

@rh101
Copy link
Contributor Author

rh101 commented Sep 15, 2024

@aismann The code you posted changed the initial sample a bit too much, so it's not as obvious when the issue occurs.

A project is now up here. Simply compile and run on an Android device, and hopefully it will reproduce the issue.

Press the "RESET" button to reset it constantly until you see the problem, which I could easily reproduce to get the following output:
Screenshot_20240915_190145
Screenshot_20240915_190205
Screenshot_20240915_190218

Note that the test does not contain the changes made in #2145

@aismann
Copy link
Contributor

aismann commented Sep 15, 2024

Note that the test does not contain the changes made in #2145

I see ;)
Thanks I getting the artefakts.

@rh101
Copy link
Contributor Author

rh101 commented Sep 16, 2024

@aismann Sample project updated. Reduced the amount of DrawNode calls, so it only takes 2 calls to cause the problem, being drawSolidCircle and drawSolidRect. If drawSolidCircle is used on its own, then no issue appears, but when drawSolidRect is introduced, then the problem appears.

@aismann
Copy link
Contributor

aismann commented Sep 16, 2024

@rh101
Can you try this fix:
Update DrawNode.cpp #2158

@halx99
PR can merge if works on @rh101 device successfull.

@rh101
Copy link
Contributor Author

rh101 commented Sep 16, 2024

@rh101 Can you try this fix: Update DrawNode.cpp #2158

I'll test it soon.

@rh101
Copy link
Contributor Author

rh101 commented Sep 16, 2024

@aismann @halx99 Everything seems to be working fine with the changes in #2158

@halx99 halx99 closed this as completed in 46332b5 Sep 16, 2024
@halx99 halx99 linked a pull request Sep 16, 2024 that will close this issue
6 tasks
xfbird pushed a commit to xfbird/axmol that referenced this issue Sep 18, 2024
xfbird pushed a commit to xfbird/axmol that referenced this issue Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants