I am a mostly self-taught OpenGL programmer teaching Computer Graphics at a small college - so I'm definitely not an expert OpenGL programmer by any means.
I am trying to develop an implementation of the board game "Monopoly", and am trying to write code that can render an individual property. If you're not familiar with Monopoly, here's an image of the board A "property" is one of the individual rectangles with a colored border at the top, such as "Connecticut Avenue" at the bottom left corner of the image. Rendering the property itself is no problem, obviously. Adding in the text using JOGL's TextRenderer is proving difficult, however. The TextRenderer class seems to want to use pixels as the units for world coordinate system, as the documentation mentions that calling beginRendering will set up an orthographic projection based on the width/height passed to beginRenderering. The documentation suggests passing the width and height of the GLAutoDrawable being drawn into as the parameters for beginRenderering. If I pass drawable.getWidth() and drawable.getHeight(), and then draw text at (getWidth()/2, getHeight()/2), it draws text whose lower left corner is in the center of the drawable as expected. I have learned to model domain objects, like the Monopoly properties, in their own coordinate space, usually placing their origin in the center of the object. Then modeling transformations can be applied to transform the object appropriate based on the coordinate system representing the world being rendered. For the property, I've modeled it using (0, 0) as the center, with the 4 vertices representing the property's coordinates being the appropriate combinations of (± WIDTH/2, ± HEIGHT/2). I'm not sure how to model these domain objects independently like this and still use JOGL's TextRenderer code to render the property name and price. What I have thought to do is to invert both the modelview and projection matrices to obtain a matrix that will allow me to know where in the viewport the property's vertices are being rendered, and using that to help me determine an appropriate (x, y) location to use within the coordinate system set up by TextRenderer.beginRendering. I haven't yet tried this - is this an appropriate approach, or am I making the problem too difficult? Thanks in advance for any ideas, Ryan |
Sorry, after I thought about it some more, I realized this was easier than I thought.
I obtained the modelview matrix using glGetFloatv, multiplied the desired location within my Property's idea of its coordinate system, then retrieved the viewport and applied the world-to-viewport computations to help me know where I should draw the text. It's all working now! |
Administrator
|
Hello
Feel free to release your source code, it could be valuable for others :)
Julien Gouesse | Personal blog | Website
|
Sure, I'm happy to post the code that I used in case someone stumbles across this question in the future! First, some building block methods: This one retrieves the current ModelView matrix - since there may have been calls to glTranslate, glRotate, etc. that position the property somewhere on the board, I need this matrix to help me compute where the property is in screen coordinates. private static Matrix4d getModelViewMatrix (GL gl) { float[] modelViewMatrix = new float[16]; gl.glGetFloatv(GLMatrixFunc.GL_MODELVIEW_MATRIX, modelViewMatrix, 0); Matrix4d mvMatrix = new Matrix4d(); mvMatrix.set(modelViewMatrix); return mvMatrix; } Next is getScreenCoordinatesForPoint. It uses the model view matrix from above to transform the (x,y) coordinates in the property's coordinate system (with (0,0) in the center of the property) to the world coordinates where the property is being drawn. Then, it uses a utility method to map those world coordinates into screen coordinates. private static Vector2i getScreenCoordinatesForPoint(GL gl, Matrix4d mvMatrix, double x, double y) { Vector4d point = new Vector4d(x, y, 1.0, 1.0).mul(mvMatrix); return GLUtilities.worldToViewport(gl, MonopolyWindow.world, point.x, point.y); } Finally, the method to render the text now that I know where it should go in the viewport: private static void renderPropertyName(Property property, GLCanvas canvas, TextRenderer renderer, Matrix4d mvMatrix) { LinkedList Hope that's helpful! |
Administrator
|
I advise you to create a single direct NIO buffer once instead of using an array here, JOGL has to perform the conversion for you under the hood.
Julien Gouesse | Personal blog | Website
|
Thanks, I will take a look at doing that.
I have a follow-up question regarding the use of Nothing I'm reading suggests that changes to the Modelview matrix shouldn't affect the way that text is drawn. However, I have this code:
and it draws the string "Bottom left (0, 0)" at the bottom left corner of my drawable, seemingly ignoring my modelview matrix.
However, if I move the code that manipulates the modelview matrix after the call to
But the docs don't say anything about
Am I correct about this? If so, I think it would be good if the docs for |
Administrator
|
Have you tried begin3DRendering() and end3DRendering()?
Julien Gouesse | Personal blog | Website
|
I just tried it with
draws the string appropriately translated up and to the right. |
One reason I struggle with begin3DRendering is that I am unsure of what vertices the draw method uses for the quads that it renders. Therefore I often end up with something that looks more like ink blots than text, because whatever projection matrix I'm using is making the rendered quads too large, effectively "zooming in" on the font.
I now recall the draw3D method, which is maybe what I should be using. This method includes a scaleFactor parameter which I am guessing is designed to address the "ink blot" problem described above. The above image uses a scaleFactor of 1, with a 2D world coordinate system set up with gluOrtho2D. Both X and Y values range from -1 to 1. If I change the scale factor to 0.01 through trial and error, I get this image The documentation doesn't really say how to use scaleFactor. How do I calculate an appropriate value for scaleFactor, instead of guessing? |
Free forum by Nabble | Edit this page |