I'm trying to render a mathematical equation from an AST tree in SFML.
My current approach is to have a function that create base sf::Texture from characters, such as:
sf::Texture ASTHelper::GetTextureFromDefaultChar(char c) {
sf::Text tmp;
tmp.setFillColor(sf::Color::Black);
tmp.setString(std::string(1, c));
tmp.setFont(this->textFont);
tmp.setCharacterSize(this->fontSize);
int x = tmp.getLocalBounds().width;
int y = tmp.getLocalBounds().height;
sf::RenderTexture tex;
tex.create(x, y);
tex.clear();
tex.draw(tmp);
tex.display();
sf::Texture returnTex = tex.getTexture();
return returnTex;
}
then merge/move/copy those textures into more convoluted equations while traversing the AST tree.
For example, given an expression like (x+1), I can use GetTextureFromDefaultChar() for each character, then merge the textures together horizontally.
Problem is, seems like merging and copying sf::Texture/sf::RenderTexture is strongly discouraged. And certainly not every frame.
https://en.sfml-dev.org/forums/index.php?topic=17566.0
https://en.sfml-dev.org/forums/index.php?topic=18020.0
https://en.sfml-dev.org/forums/index.php?topic=10512.0
I've also look into other API/libraries to see if anything could be use in C++ (since I don't want to reinvent the wheel), and MathJax seems to be used a lot (Mathjax in C++ console), but in browsers.
So,
Is there a better way than merging/copying sf::Texture and sf::RenderTexture (or some completely different arrangements that I may have overlook)?
and
If not, are there any different C++ libraries that support this?
Let say you have every math symbol as sf::Int/FloatRect which would be their position in sf::Texture that would contain every single one of them.
Then you could just calculate their position in one line i.e. how would they be positioned if you would like to draw them.
Then draw these as sf::Sprite or sf:RectangleShape to one sf::RenderTexture, display it and now you have a texture which is made out of your symbols.
This way you don't draw all textures nor create that sf::RenderTexture every frame from scratch. Also, making another math equation into a texture would just require to call sf::RenderTexture::clear(sf::Color::Transparent) and repeating the same steps as before.
This way there is no merging, copying of textures, just one texture sheet of symbols which are drawn into one renderTexture.
Related
This probably has been asked before, but I can't find something on it other than the general private/public/const solutions. Basically, I need to load fonts into an array when an instance of my class text is created. The text class is in my text.h file, and defined in text.cpp. In both of these files, they also include a Fonts class, and so I want my fonts class to have my selection of fonts preloaded in an array ready to be accessed by my text class AFTER the first instance is created. I want these fonts to be able to be accessed by my text class, but not able to be changed. I can't create a TTF_Font *Get_Font() method in the fonts class as each time a font is created, it loads memory that needs to be manually closed, so I couldn't exactly close it after it runs out of the method's scope, so rather, I would want to do something like, when creating a character for example, call TTF_RenderText_Blended(Fonts::arialFonts[10], "123", black); which would select the font type of arial in size 11 for example.
I'm not sure what type of application you are using your fonts in, but I've done some 3D graphics programming using OpenGL and Vulkan. This may or may not help you, but should give you some kind of context on the structure of the framework that is commonly used in Game Engine development.
Typically we will have a Texture class or struct that has a vector of color triplets or quads that represent the color data for each pixel in the image. Other classes will contain UV coordinates that the texture will be applied to... We also usually have functions to load in textures or graphics files such as PNG, JPG, TGA, etc. You can write your own fairly trivially or you can use many of the opensource loader libraries that are out there if you're doing graphics type programming. The texture class will contain other properties such as mipmap, if it is repeated or mirrored, its quality, etc... So we will typically load a texture and assign it an ID value and will store it into a hash table. If this texture is trying to be loaded again from a file, the code will recognize that it exists and exits that function call, otherwise it will store this new texture into the hash table.
Since most rendered texts are 2D, instead of creating a 3D model and sending it to the render to be processed by the model-view-projection matrix... We create what is commonly called a Sprite. This is another class. It has vertices to make up its polygonal edges. Typically a sprite will have 4 vertices since it is a QUAD. It will also have texture coordinates that will be associated with it. We don't apply the textures directly to the sprite because we want to instance a single sprite having only a single copy in memory. What we will typically do here, is we will send a reference of it to the renderer along with a reference to the texture by id, and transformation matrix to changes its shape, size, and world position. When this is being processed by the GPU through the shaders, since it is a 2D object, we use an orthographic projection. So this saves a matrix multiplication within the vertex shader for every vertex. Basically, it will be processed by the view-projection matrix. Here our Sprites will be stored similarly to our textures, in a hash table with an associated ID.
Now we have a sprite that is basically a Graphics Image that is drawn to the screen, a simple quad that can be resized and placed anywhere easily. We only need a single quad in memory but can draw hundreds even thousands because they are instanced via a reference count.
How does this help with Text or Fonts? You want your Text class to be separate from your Font class. The text class will contain where you want to draw it, which font to use, the size of the font, the color to be applied, and the text itself... The Font class would typically inherit from the basic Sprite Class.
We will normally create a separate tool or mini- console program that will allow you to take any of the known true type fonts or windows fonts by name that will generate 2 files for you. You will pass flags into the program's command-line arguments along with other commands such as -all for all characters or -"abc123" for just the specific characters you want, and -12, for the font size, and by doing so it will generate your needed files. The first will be a single textured image that we call a Font Atlas which is basically a specific form of a Sprite Sheet and the other file will be a CSV text file with generated values for texture positioning of each character's quad.
Back in the main project, the font class will load in these two files the first is simple as it's just a Texture image which we've already done before, and the later is the CSV file for the information that is needed to generate all of the appropriate quads, however, the "Font" class does have quite a bit of complex calculations that need to be performed. Again, when a Font is loaded into memory, we do the same as we did before. We check to see if it is already loaded into memory by either filename or by id and if it isn't we then store it into a hash table with a generated associated ID.
Now when we go to use the Text class to render our text, the code might look something like this:
void Engine::loadAssets() {
// Textures
assetManager_.loadTexture( "assets\textures\shells.png" );
assetManager_.loadTexture( "assets\textures\blue_sky.jpg" );
// Sprites
assetManager_.loadSprite( "assets\sprites\jumping_jim.spr" );
assetManager_.loadSprite( "assets\sprites\exploading_bomb.spr" );
assetManager_.loadFont( "assets\fonts\"arial.png", 12 );
// Same font as above, but the code structure requires a different font id for each different size that is used.
assetManager_.loadFont( "assets\fonts\"arial.png", 16 );
assetManager_.loadFont( "assets\fonts\"helvetica.png" );
}
Now, these are all stored as a single instance in our AssetManager class, this class containers several hashtables for each of the different types of assets. Its role is to manage their memory and lifetime. There is only ever a single instance of each, but we can reference them 1,000 times... Now somewhere else in the code, we may have a file with a bunch of standalone enumerations...
enum class FontType {
ARIAL,
HELVETICA,
};
Then in our render call or loadScene function....
void Engine::loadScene() {
fontManager_.drawText( ARIAL, 18, glm::vec3(-0.5, 1.0, 0.5), glm::vec4(245, 169, 108, 128), "Hello World!");
fontManager_.drawText( ARIAL, 12, glm::vec3(128, 128, 0), glm::vec4(128, 255, 244, 80), "Good Bye!");
}
The drawText function would be the one that takes the ARIAL id and gets the reference into the hashtable for that stored font. The renderer uses the positioning, and color values, the font size, and the string message... The ID and Size are used to retrieve the appropriate Font Atlas or Sprite Sheet. Then each character in the message string will be matched and the appropriate texture coordinates will be used to apply that to a quad with the appropriate size based on the font's size you specified.
All of the file handling, opening, reading from, and closing of was already previously done in the loadAssets function. All of the required information is already stored in a set of hashtables that we reference in to via instancing. There is no need or concern to have to worry about memory management or heap access at this time, this is all done through utilizing the cache. When we draw the text to the screen, we are only manipulating the pixels through the shaders by matrix transformations.
There is another major component to the engine that hasn't been mentioned yet, but we typically use a Batch Process and a Batch Manager class which handles all of the processing for sending the Vertices, UV Coordinates, Color, or Texture Data, etc... to the video card. CPU to GPU transfer across the buss and or the PCI-Express lanes are considered slow, we don't want to be sending 10,000, 100,000, or even 1 million individual render calls every single frame! So we will typically create a set of batches that has a priority queue functionality and when all buckets are full, either the bucket with the highest priority value or the fullest bucket will be sent to the GPU and then emptied. A single bucket can hold 10,000 - 100,000 primitives... where single a primitive could be a point, a line, a triangle list, a triangle fan, etc... This makes the code much more efficient. The heap is seldom used. The BatchManager, AssetManager, TextureManager, AudioManager, FontManager classes, etc. are the ones that live on the heap, but all of their stored assets are used by reference and due to that we can instance a single object a million times! I hope this explanation helps.
I want to draw a ring (circle with big border) with the shaperenderer.
I tried two different solutions:
Solution: draw n-circles, each with 1 pixel width and 1 pixel bigger than the one before. Problem with that: it produces a graphic glitch. (also with different Multisample Anti-Aliasing values)
Solution: draw one big filled circle and then draw a smaller one with the backgroundcolor. Problem: I can't realize overlapping ring shapes. Everything else works fine.
I can't use a ring texture, because I have to increase/decrease the ring radius dynamic. The border-width should always have the same value.
How can I draw smooth rings with the shaperenderer?
EDIT:
Increasing the line-width doesn't help:
MeshBuilder has the option to create a ring using the ellipse method. It allows you to specify the inner and outer size of the ring. Normally this would result in a Mesh, which you would need to render yourself. But because of a recent change it is also possible to use in conjunction with PolygonSpriteBatch (an implementation of Batch that allows more flexible shapes, while SpriteBatch only allows quads). You can use PolygonSpriteBatch instead of where you normally would use a SpriteBatch (e.g. for your Stage or Sprite class).
Here is an example how to use it: https://gist.github.com/xoppa/2978633678fa1c19cc47, but keep in mind that you do need the latest nightly (or at least release 1.6.4) for this.
Maybe you can try making a ring some other way, such as using triangles. I'm not familiar with LibGDX, so here's some
pseudocode.
// number of sectors in the ring, you may need
// to adapt this value based on the desired size of
// the ring
int sectors=32;
float outer=0.8; // distance to outer edge
float inner=1.2; // distance to inner edge
glBegin(GL_TRIANGLES)
glNormal3f(0,0,1)
for(int i=0;i<sectors;i++){
// define each section of the ring
float angle=(i/sectors)*Math.PI*2
float nextangle=((i+1)/sectors)*Math.PI*2
float s=Math.sin(angle)
float c=Math.cos(angle)
float sn=Math.sin(nextangle)
float cn=Math.cos(nextangle)
glVertex3f(inner*c,inner*s,0)
glVertex3f(outer*cn,outer*sn,0)
glVertex3f(outer*c,outer*s,0)
glVertex3f(inner*c,inner*s,0)
glVertex3f(inner*cn,inner*sn,0)
glVertex3f(outer*cn,outer*sn,0)
}
glEnd()
Alternatively, divide the ring into four polygons, each of which consists of one quarter of the whole ring. Then use ShapeRenderer to fill each of these polygons.
Here's an illustration of how you would divide the ring:
if I understand your question,
maybe, using glLineWidth(); help you.
example pseudo code:
size = 5;
Gdx.gl.glLineWidth(size);
mShapeRenderer.begin(....);
..//
mShapeRenderer.end();
I want to load a mesh file using TetGen library in C++ but I don't know the right procedure or what switches to activate in my code in order to show the Constrained Delaunay mesh.
I tried something basic loading of a dinosaur mesh (from rocq.inria.fr) with default behavior:
tetgenio in, out;
in.firstnumber = 0;
in.load_medit("TetGen\\parasaur1_cut.mesh",0);
tetgenbehavior *b = new tetgenbehavior();
tetrahedralize(b, &in, &out);
The shape is supposed to be like this:
When using TetView it works perfectly. But with my code I got the following result:
I tried to activate the Piecewise Linear Complex (plc) property for Delaunay Constraint:
b->plc = 1;
and I got just a few parts from the mesh:
Maybe there are more parts but I don't know how to get them.
That looks a lot like you might be loading a quad mesh as a triangle mesh or vice versa. One thing is clear, you are getting the floats from the file, since the boundaries of the object look roughly correct. Make certain you are loading a strictly triangle or quad-based mesh. If it is a format that you can load into Blender, I'd recommend loading it, triangulating it, and re-exporting it, just in case a poly snuck into there.
Another possibility is an indexing off by one error. Are you sure you are getting each triangle/quad in the correct order? Which is to say -- make sure you are loading triangles 123 123 123 and NOT 1 231 231 231.
One other possibility, if this format indexes all of the vertices, and then lists the indexes of the vertices, you might be loading all of the vertices correctly, and then getting the indexes of the triangles/quads messed up, as described in the previous two paragraphs. I'm thinking this is the case, since it looks like all of your points are correct, but the lines connecting them are way wrong.
When my programm start, it must display a circle on a background. Also i must controll all displaying circles. I use class VertexController and class Vertex for that purpose. In Vertex i have constructor:
Vertex::Vertex(const ci::Vec2f & CurrentLoc){
vColor = Color(Rand::randFloat(123.0f),Rand::randFloat(123.0f),Rand::randFloat(123.0f));
vRadius = Rand::randFloat(23.0f);
vLoc = CurrentLoc;
}
and in VertexController i have
VertexController::VertexController()
{
Vertex CenterVertex = Vertex(getWindowCenter());
CenterVertex.draw(); // function-member draw solid circle with random color
}
and in setup{} method i wrote
void TutorialApp::setup(){
gl::clear(Color(255,204,0));
mVertexController=VertexController();
}
Unfrtunatelly, my way didnt work.I see only background.
So the main question - in CINDER_APP_BASIC drawing possible only in draw{},update{},setup{} directly? If yes, advise a solution, else say where is my fail.
this line of code does not make any sense to me:
mVertexController=VertexController();
Anyways, you should use draw() function just for drawing circles to window. This it why by default there is gl::clear(Color(0,0,0)); to clear background and start drawing new frame from scratch (this is the way drawing in OpenGL, used by default in Cinder, works).
I suggest to use Vector container for storing all circles (this way you can add and remove circles on the fly with some effort), add the first one in VertexController constructor, and make separate function VertexController::draw() to draw all circles using for loop.
I have a 2D list of vectors (say 20x20 / 400 points) and I am drawing these points on a screen like so:
for row in grid:
for point in row:
pygame.draw.circle(window, white, (particle.x, particle.y), 2, 0)
pygame.display.flip() #redraw the screen
This works perfectly, however it's much slower then I expected.
I want to rewrite this in C++ and hopefully learn some stuff (I am doing a unit on C++ atm, so it'll help) on the way. What's the easiest way to approach this? I have looked at Direct X, and have so far followed a bunch of tutorials and have drawn some rudimentary triangles. However I can't find a simple (draw point).
DirectX doesn't have functions for drawing just one point. It operates on vertex and index buffers only. If you want simpler way to make just one point, you'll need to write a wrapper.
For drawing lists of points you'll need to use DrawPrimitive(D3DPT_POINTLIST, ...). however, there will be no easy way to just plot a point. You'll have to prepare buffer, lock it, fill with data, then draw the buffer. Or you could use dynamic vertex buffers - to optimize performance. There is a DrawPrimitiveUP call that is supposed to be able to render primitives stored in system memory (instead of using buffers), but as far as I know, it doesn't work (may silently discard primitives) with pure devices, so you'll have to use software vertex processing.
In OpenGL you have glVertex2f and glVertex3f. Your call would look like this (there might be a typo or syntax error - I didn't compiler/run it) :
glBegin(GL_POINTS);
glColor3f(1.0, 1.0, 1.0);//white
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
glVertex2f(points[y][x].x, points[y][x].y);//plot point
glEnd();
OpenGL is MUCH easier for playing around and experimenting than DirectX. I'd recommend to take a look at SDL, and use it in conjuction with OpenGL. Or you could use GLUT instead of SDL.
Or you could try using Qt 4. It has a very good 2D rendering routines.
When I first dabbled with game/graphics programming I became fond of Allegro. It's got a huge range of features and a pretty easy learning curve.