I’m trying to develop simple OpenGL app using NVPathRendering extenstion with LWJGL Java library.
I wrote some code, but it doesn’t render correctly.
I think that path isn’t correctly stenciled in the stencil buffer.
SVG path looks correct:
String star = "M 300 300 C 100 400,100 200,300 100,500 200,500 400,300 300Z"; //heart
The below screen presents how it should look like.
Red points in the right window represents path coordinates.
Any idea what’s wrong?
External Media
public class Main {
private boolean closeRequested = false;
private int pathObj = 41;
public Main() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeRequested = true;
}
});
Canvas canvas = new Canvas();
canvas.setSize(500, 400);
canvas.setFocusable(true);
canvas.setIgnoreRepaint(true);
frame.setLayout(new BorderLayout());
frame.add(canvas, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
try {
Display.setResizable(true);
Display.setParent(canvas);
Display.sync(60);
Display.create();
} catch (LWJGLException ex) {
ex.printStackTrace();
}
System.out.println("OpenGL version: " + glGetString(GL_VERSION));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 500, 0, 400, 1, -1);
glMatrixMode(GL_MODELVIEW);
// SVG format
String star =
"M 300 300 C 100 400,100 200,300 100,500 200,500 400,300 300Z"; //heart
ByteBuffer starBuf =
ByteBuffer.allocateDirect(star.getBytes().length);
starBuf.put(star.getBytes());
starBuf.flip();
glPathStringNV(pathObj, GL_PATH_FORMAT_SVG_NV, starBuf);
glPathParameteriNV(pathObj, GL_PATH_JOIN_STYLE_NV, GL_ROUND_NV);
glPathParameterfNV(pathObj, GL_PATH_STROKE_WIDTH_NV, (float) 6.5);
while (!Display.isCloseRequested() && !closeRequested) {
pathRender();
render();
Display.update();
}
Display.destroy();
frame.dispose();
//System.exit(0);
}
private void pathRender() {
glClearStencil(0);
glClearColor(0, 0, 0, 0);
glStencilMask(~0);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixLoadIdentityEXT(GL_PROJECTION);
glMatrixLoadIdentityEXT(GL_MODELVIEW);
glMatrixOrthoEXT(GL_MODELVIEW, 0, 500, 0, 400, -1, 1);
// glStencilFillPathNV(pathObj, GL_COUNT_UP_NV, 0x1F);
// glEnable(GL_STENCIL_TEST);
// boolean even_odd = false;
// if (even_odd) {
// glStencilFunc(GL_NOTEQUAL, 0, 0x1);
// } else {
// glStencilFunc(GL_NOTEQUAL, 0, 0x1F);
// }
// glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
// glColor3f(1, 1, 0); // yellow
// glCoverFillPathNV(pathObj, GL_BOUNDING_BOX_NV);
glStencilStrokePathNV(pathObj, 0x1, ~0);
glColor3f(1, 1, 1); //white
glCoverStrokePathNV(pathObj, GL_CONVEX_HULL_NV);
}
public void render() {
glColor3f(1, 0, 0);
GL11.glPointSize(5);
glBegin(GL11.GL_POINTS); // point at 5 above mouse location
GL11.glVertex3f(300,300, 0);
GL11.glVertex3f(100,400, 0);
GL11.glVertex3f(100,200, 0);
GL11.glVertex3f(300,100, 0);
GL11.glVertex3f(500,200, 0);
GL11.glVertex3f(500,400, 0);
glEnd();
}
public static void main(String args[]) {
try {
// Set System L&F
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
new Main();
}
}