nanovg
nanovg copied to clipboard
NanoVG (GL2) and OpenGL cannot drawing together, but NanoVG(GL3) could
For some reason, I tried to render using mixed NanoVG and raw OpenGL.
glClearColor( 0.7f, 0.8f, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT );
// PART1: nanovg
nvgBeginFrame( nvg, w, h, 1.0f );
nvgCircle( nvg, 50, 50, 50 );
nvgStrokeWidth( nvg, 3.0f );
nvgStrokeColor( nvg, nvgRGB( 255, 127, 64 ) );
nvgStroke( nvg );
nvgEndFrame( nvg );
// PART2: raw OpenGL
glUseProgram( prog );
glBindVertexArray( vao );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
glFinish();
SDL_GL_SwapWindow( win );
If I compile nanovg_gl.h with NANOVG_GL2_IMPLEMENTATION, the OpenGL drawing part would always output nothing; and if compile with NANOVG_GL3_IMPLEMENTATION, it renders correctly.
The OpenGL drawing part as simple as drawing an rectangle with vertex color.
What make it so different between GL2 and GL3?
In addition:
- I've turned on stencil buffer this time.
- the result won't change even if I put PART2 before PART1.
- The reason I'm using mixed drawing is that I'm making a screen-space image effect that needs drawing back hijacked framebuffer using OpenGL draws.
- The reason I use
NANOVG_GL2_IMPLEMENTATIONis that my Linux laptop's Intel HD3000 graphic driver don't support#version 150shader, which is required by NanoVG's GL3 implementation.
I run both GL2 and GL3 programs with CodeXL and recorded all OpenGL calls in rendering loop.
Records from NanoVG compiled with NANOVG_GL2_IMPLEMENTATION:
glClearColor(0.69999999, 0.80000001, 1, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glUseProgram(1) [Context 3 - program 1: shader 2, shader 3]
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CCW)
glEnable(GL_BLEND)
glDisable(GL_DEPTH_TEST)
glDisable(GL_SCISSOR_TEST)
glColorMask(TRUE, TRUE, TRUE, TRUE)
glStencilMask(4294967295)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
glStencilFunc(GL_ALWAYS, 0, 4294967295)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, 0)
glBindBuffer(GL_ARRAY_BUFFER, 1)
glBufferData(GL_ARRAY_BUFFER, 2080, 0x00000208FB7AB5E0, GL_STREAM_DRAW)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, 16, 0x0000000000000000)
glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, 16, 0x0000000000000008)
glUniform1i(12, 0) [Context 3 - program 1: shader 2, shader 3]
glUniform2fv(11, 1, {600, 400}) [Context 3 - program 1: shader 2, shader 3]
glBlendFuncSeparate(1, GL_ONE_MINUS_SRC_ALPHA, 1, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_STENCIL_TEST)
glStencilMask(255)
glStencilFunc(GL_EQUAL, 0, 255)
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR)
glUniform4fv(0, 11, {0, 0, 0, 0}) [Context 3 - program 1: shader 2, shader 3]
glGetError()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glUniform4fv(0, 11, {0, 0, 0, 0}) [Context 3 - program 1: shader 2, shader 3]
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glColorMask(FALSE, FALSE, FALSE, FALSE)
glStencilFunc(GL_ALWAYS, 0, 255)
glStencilOp(0, 0, 0)
glGetError()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glColorMask(TRUE, TRUE, TRUE, TRUE)
glDisable(GL_STENCIL_TEST)
glDisableVertexAttribArray(0)
glDisableVertexAttribArray(1)
glDisable(GL_CULL_FACE)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glUseProgram(0) [Context 3 - program 0]
glUseProgram(4) [Context 3 - program 4: shader 5, shader 6]
glBindVertexArray(1)
glBindBuffer(GL_ARRAY_BUFFER, 2)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4)
glFinish()
wglSwapBuffers(0x000000001A01224C)
And from NANOVG_GL3_IMPLEMENTATION:
glClearColor(0.69999999, 0.80000001, 1, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glUseProgram(1) [Context 3 - program 1: shader 2, shader 3]
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CCW)
glEnable(GL_BLEND)
glDisable(GL_DEPTH_TEST)
glDisable(GL_SCISSOR_TEST)
glColorMask(TRUE, TRUE, TRUE, TRUE)
glStencilMask(4294967295)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
glStencilFunc(GL_ALWAYS, 0, 4294967295)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, 0)
glBindBuffer(GL_UNIFORM_BUFFER, 2)
glBufferData(GL_UNIFORM_BUFFER, 512, 0x000001D670FF28B0, GL_STREAM_DRAW)
glBindVertexArray(1)
glBindBuffer(GL_ARRAY_BUFFER, 1)
glBufferData(GL_ARRAY_BUFFER, 2080, 0x000001D670FE2870, GL_STREAM_DRAW)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glVertexAttribPointer(0, 2, GL_FLOAT, FALSE, 16, 0x0000000000000000)
glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, 16, 0x0000000000000008)
glUniform1i(14, 0) [Context 3 - program 1: shader 2, shader 3]
glUniform2fv(13, 1, {600, 400}) [Context 3 - program 1: shader 2, shader 3]
glBindBuffer(GL_UNIFORM_BUFFER, 2)
glBlendFuncSeparate(1, GL_ONE_MINUS_SRC_ALPHA, 1, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_STENCIL_TEST)
glStencilMask(255)
glStencilFunc(GL_EQUAL, 0, 255)
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR)
glBindBufferRange(GL_UNIFORM_BUFFER, 0, 2, 256, 176)
glGetError()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glBindBufferRange(GL_UNIFORM_BUFFER, 0, 2, 0, 176)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glColorMask(FALSE, FALSE, FALSE, FALSE)
glStencilFunc(GL_ALWAYS, 0, 255)
glStencilOp(0, 0, 0)
glGetError()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 130)
glColorMask(TRUE, TRUE, TRUE, TRUE)
glDisable(GL_STENCIL_TEST)
glDisableVertexAttribArray(0)
glDisableVertexAttribArray(1)
glBindVertexArray(0)
glDisable(GL_CULL_FACE)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glUseProgram(0) [Context 3 - program 0]
glUseProgram(4) [Context 3 - program 4: shader 5, shader 6]
glBindVertexArray(2)
glBindBuffer(GL_ARRAY_BUFFER, 3)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4)
glFinish()
wglSwapBuffers(0x000000004B0123A6)
The last six lines start from glUseProgram(4) is my custom raw GL drawing.
I compared the two records. It seems in GL3 version, nanovg is using its own VAO (an extra pair of glBindVertexArray(1) and glBindVertexArray(0)), while GL2 version not. So would GL2 version disturb some currently binding VAO? As VAO feature is not GL3-only, why nanovg don't have this pair of call in GL2 version?
Did you find a solution to this ? I want to try mixing OpenGL calls with nanovg also, so I guess this will concern me too soon.
NanoVG will change some OpenGL state, which you will need to manually reset. See https://github.com/memononen/nanovg#opengl-state-touched-by-the-backend
I was trying to leach off some working demo code here. :) I know that page. (But thanks anyway)