memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.13k stars 768 forks source link

Weird vertex buffers when trying to render in OGRE #194

Open iboshkov opened 9 years ago

iboshkov commented 9 years ago

I'm trying to make OGRE and nanovg play together nicely, but one of them keeps refusing. Current issues I'm having:

  1. Triangle strips seem to be continuous once, and discontinued another time, not sure why that is.
  2. Fill doesn't fill my shapes, but is instead given like a bad stroke, and gets quite buggy due to (1).
  3. Stroke sometimes works properly, sometimes doesn't.

Stroke: jntdr5u Fill: xgewjdl

What I'm doing in my code is just filling the vertex buffers in OGRE and rendering the result.

Here's the actual code:

// ngVertex just converts a NGVertex to my own struct
struct Vertex
{
    Ogre::Vector3 position;
    Ogre::RGBA colour;
};

void NVORenderer::renderFill(NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths)
{
    for (int i = 0; i < npaths; i++)
    {
        NVGpath path = paths[i];
        for (int j = 0; j < path.nfill; j++)
            mVertices.push_back(ngVertex(path.fill[j], paint));
    }
    mRenderOp.vertexData->vertexCount = mVertices.size();
}

void NVORenderer::renderStroke(NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths)
{
    for (int i = 0; i < npaths; i++)
    {
        NVGpath path = paths[i];

        for (int j = 0; j < path.nstroke; j++)
            mVertices.push_back(ngVertex(path.stroke[j], paint));
    }
    mRenderOp.vertexData->vertexCount = mVertices.size();
}

void NVORenderer::renderTriangles(NVGpaint* paint, NVGscissor* scissor, const NVGvertex* verts, int nverts)
{
    for (int j = 0; j < nverts; j++)
        mVertices.push_back(ngVertex(verts[j], paint));
}

And the relevant nanovg draw calls:

        nvgBeginFrame(vg, vp->getActualWidth(), vp->getActualHeight(), 0.1);
        nvgFillColor(vg, nvgRGB(80, 120, 225));
        nvgStrokeColor(vg, nvgRGB(63, 242, 188));
        //nvgLineJoin(vg, NVG_ROUND);
        nvgBeginPath(vg);
        nvgRect(vg, 150, 300, 100, 100);
        nvgRoundedRect(vg, 600, 300, 100, 100, 20);
        nvgCircle(vg, 400, 200, 50);
        nvgArc(vg, 500, 500, 50, 0, Math::PI, NVG_CW);
        nvgText(vg, 50, 50, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 0);
        nvgFill(vg);
        //nvgStroke(vg);

        Ogre::WindowEventUtilities::messagePump();
        root.renderOneFrame();
        nvgEndFrame(vg);

Then I'm just copying that data into the vertex buffer of OGRE and rendering, so it's probably the way I'm reading the data from nanovg that I'm screwing up, I'm just not sure which part.

memononen commented 9 years ago

Each path should become a separate draw call. Fills are rendered as fans. The ogl backend creates one big vertex buffer, and uses offsets for draw calls.

--mikko

Sent from my iPhone

On 5.1.2015, at 2.04, MindCalamity notifications@github.com wrote:

I'm trying to make OGRE and nanovg play together nicely, but one of them keeps refusing. Current issues I'm having:

Triangle strips seem to be continuous once, and discontinued another time, not sure why that is. Fill doesn't fill my shapes, but is instead given like a bad stroke, and gets quite buggy due to (1). Stroke sometimes works properly, sometimes doesn't. Stroke:

Fill:

What I'm doing in my code is just filling the vertex buffers in OGRE and rendering the result.

Here's the actual code:

// ngVertex just converts a NGVertex to my own struct struct Vertex { Ogre::Vector3 position; Ogre::RGBA colour; };

void NVORenderer::renderFill(NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths) { for (int i = 0; i < npaths; i++) { NVGpath path = paths[i]; for (int j = 0; j < path.nfill; j++) mVertices.push_back(ngVertex(path.fill[j], paint)); } mRenderOp.vertexData->vertexCount = mVertices.size(); }

void NVORenderer::renderStroke(NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths) { for (int i = 0; i < npaths; i++) { NVGpath path = paths[i];

    for (int j = 0; j < path.nstroke; j++)
        mVertices.push_back(ngVertex(path.stroke[j], paint));
}
mRenderOp.vertexData->vertexCount = mVertices.size();

}

void NVORenderer::renderTriangles(NVGpaint* paint, NVGscissor* scissor, const NVGvertex* verts, int nverts) { for (int j = 0; j < nverts; j++) mVertices.push_back(ngVertex(verts[j], paint)); } Then I'm just copying that data into the vertex buffer of OGRE and rendering, so it's probably the way I'm reading the data from nanovg that I'm screwing up, I'm just not sure which part.

— Reply to this email directly or view it on GitHub.

iboshkov commented 9 years ago

That was a great tip, after refactoring my whole code I got the vertex building to work, now I'm not sure how gradients, shadows and such are rendered, are they entirely shader-based or do I need to do something special (other than passing the values from the renderXXX functions to the shader).

I also have this issue with the fill still: screenshot_7

Not sure why it's happening, I'm using a triangle fan vertex and filling it with the raw data from nanoVG.

memononen commented 9 years ago

Hi,

Are you using the stencil buffer to mask the shapes? If not, then that is the problem with the fill. Take a look at the OpenGL back-end on how to setup the stencil. If you're not familiar with the method, google for polygon filling stencil.

A good chunk of the work is done in the shader, so you'll need to implement that to render things properly.

--mikko

On Mon, Jan 5, 2015 at 8:14 PM, MindCalamity notifications@github.com wrote:

That was a great tip, after refactoring my whole code I got the vertex building to work, now I'm not sure how gradients, shadows and such are rendered, are they entirely shader-based or do I need to do something special (other than passing the values from the renderXXX functions to the shader).

I also have this issue with the fill still: [image: screenshot_7] https://cloud.githubusercontent.com/assets/2392895/5617409/d01b9586-950e-11e4-99f2-f88f7510b5be.png

Not sure why it's happening, I'm using a triangle fan vertex and filling it with the raw data from nanoVG.

— Reply to this email directly or view it on GitHub https://github.com/memononen/nanovg/issues/194#issuecomment-68749923.