Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

Qt\QtQuick Tutorial

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
No. Not a game, and as I wrote we have drawings up to 100,000 polylines. Also it is supposed to run on Android, or at least tablet PCs. GDI would be completely a dead end.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Hey, Qt fucking rocks!! :salute:

Image quality, simplicity of the functions and stability so far is absolutely top notch.

The fact that my window can also run in the background for hours and not crashing with "DeviceLost" like your usual open source widget greatly adds to my excitement ..

iKKWT7d.jpg


That's in principle all I have to do to render a basic scene with all my required primitives. Rendering transparent backgrounds is also a piece of cake, you can simply choose an alpha value.

Code:
void Helper::paint(QPainter *painter, QPaintEvent *event, int elapsed)
{
    //..
    painter->fillRect(event->rect(), background);

    //..
    painter->setBrush(circleBrush);
    painter->setPen(circlePen);

    //..
    QPolygon polygon;
    polygon.setPoints(4, 50, 50,
                         100, 50,
                         100, 100,
                         50, 100);
    painter->drawPolygon(polygon);

    //..
    QPolygon polyline;
    polyline.setPoints(3, 150, 50,
                          200, 100,
                          250, 100);
    painter->drawPolyline(polyline);

    //..
    painter->drawPoint(75,175);

    //
    painter->drawLine(175,150,175,200);
    painter->drawLine(150,175,200,175);
 
    //..
    QImage image;
    image.load("C:\\joda.jpg");
    painter->drawImage(200,200,image);

    //..

    painter->setPen(textPen);
    painter->setFont(textFont);

    //..
    painter->drawText(50,75,"Polygon");
    painter->drawText(200,100,"Polylinie");
    painter->drawText(75,200,"Punkt");
    painter->drawText(175,175,"Punkt als Symbol");
    painter->drawText(200,357,"joda.jpg");

}
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Guys I can see myself making good progress from now, but I would really love a few recommendations.

Do you think anything speaks against using stl and qt together? I definitely need some robust generics but don't want to overcomplicate things either ...

1. I don't need more books about the language, but I never got as deep into C++ projects as I wanted, so I wonder if there is something that explains more of the "hard" stuff, like makefiles, building, compilers, libs, deployment and all the shebang that usually goes wrong?

2. One comprehensive book about everything Qt, with multiplatform / Android in mind?

3. The last one goes probably too far, but something like "building a scene graph" would be swell! I realized I need stuff like layers, viewport transformations and so on, and it should be fast and reliable. Even a web resource of that kind would be amazing. I can probably work out most of the stuff myself but maybe not in the best way ..
 
Joined
Jan 9, 2011
Messages
2,726
Codex 2012 Codex 2013 Codex 2014 PC RPG Website of the Year, 2015 Codex 2016 - The Age of Grimoire Make the Codex Great Again! Grab the Codex by the pussy Insert Title Here RPG Wokedex Strap Yourselves In Codex Year of the Donut Codex+ Now Streaming! Serpent in the Staglands Dead State Divinity: Original Sin Project: Eternity Torment: Tides of Numenera Wasteland 2 Codex USB, 2014 Shadorwun: Hong Kong Divinity: Original Sin 2 BattleTech Bubbles In Memoria A Beautifully Desolate Campaign Pillars of Eternity 2: Deadfire Pathfinder: Kingmaker Steve gets a Kidney but I don't even get a tag. My team has the sexiest and deadliest waifus you can recruit. Pathfinder: Wrath I'm very into cock and ball torture I helped put crap in Monomyth
No probs using stl and qt together. However, if you are using Qt you might want to use their containers: https://doc.qt.io/archives/qt-5.8/containers.html. There are pretty much same functionality wise to stl containers (http://en.cppreference.com/w/cpp/container if you haven't seen this site already).

For reading about makefiles, read make and cmake docs. Or try to build a small build system yourself ;) For compilers I recommend taking a look at http://www.cppgm.org/ - basically try to write your own. I would start with something simpler though, like C (pre C99) or even Pascal. libs - not sure what you mean, there's bajilion of them. Stuff that goes wrong - "Human vs. Computer" on amazon is both fun and interesting collection of stuff that goes wrong with software.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
I have seen the qt containers, but believed they were less comprehensive than stl. But you are probably right, List and a Dictionary is usually all I need and overuse of containers was a mistake in C#. In the last years I converted the bulk of my code to plain arrays as well as foreach to (for i=..) loops of the old style, and performance has improved greatly. Not that I expect stl to be a performance problem, but I would indeed try to keep everything as simple as possible.

Thanks for your tips, that's a very interesting book but not exactly what I need right now. As to the "managing C++ IDEs" such knowledge is specialized and may be guarded by the people who have it.

Anyway, I think I could now go and automatically generate the C++ code to initialize a drawing (though the coordinate lists could become entire pages), copy that into QtCreator and then think about simple coordinate system transformations (basically just zoom and scroll). Viewport clipping would be by simple bounding rectangle around the objects, and the paint() method only renders the viewport, avoiding costly transformations at render time.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
stern01.jpg


Did a little more, mostly just because I wanted to see what it will look like. That's not pretty but it should demonstrate what I am trying to do. Let's say a very basic CAD viewer with acceptable performance.

Ah and I can see now where I will spend the actual work, tons of work. Transformation of coordinate systems and this kind of stuff. I thought it would be easy to get a drawing to render by simple autogenerating the C++ code, and in some way it was, but my objects are inverted and not scaled. Fixing that in a robust way will be a ton of work, and I must also think about floating number precision, because these CAD drawings can have insane scaling issues.

But the apart from a few objects that are not filled (could be because the underlying polygons are not correct) this actually looks quite good. Fill in a robust data import and rendering and with real data it all comes to life.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Apparently basic world coordinate transformation is already built in.

That's something I really, really like about qt. Whenever I need something, it seems they already thought of it and have implemented the functionality.

That seems theoretically everything I need for scaling, and panning is equivalently simple by using painter->translate(someshit)

Code:
class SomeClass:public QWidget
{
  protected:
    void paintEvent ( QPaintEvent * event );
    void wheelEvent ( QWheelEvent * event );
  private:
    qreal scale;
    qreal step;
};

void SomeClass::paintEvent ( QPaintEvent * event )
{
   QPainter p;
   p.scale(scale,scale);
}
void YourClass::wheelEvent ( QWheelEvent * event )
{
   scale+=(event->delta()/step);
}
Hey, with a little bit of luck a basic viewer demo is actually feasible without a huge mayhem of code :bounce:

Of course the floating point precision issue is not so certain, I don't think I can use every kind of input without tricks.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Yaar Podshipnik thanks, this seems exactly what I need!

This Chips demo is pretty impressive I must say :salute:
not only does it implement seemless zooming and scaling but 40,000 objects is also realistic from my experience. I just hope they dont use instanced rendering for unrealistic performance gains. This is important because I dont use rectangles but multi shaped polygons, often with insane amount of points.

I still need painting, mouse picking, and rubberbanding, otherwise I think I have most of what I need.

practical usefulness of Qt so far: :5/5::5/5:
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Well, turns out there are even easier ways to do this.

The Chips demo uses QGraphicsView and in fact this has already implemented most of what I was talking about.

Viewport transformations is basically free, everything you need to do is basically graphicsView.setMatrix(matrix) and tie that to some input of your choice.

In the example they use sliders. I simplified it as much as possible to show the basic idea:

Code:
void View::setupMatrix()
{

    QMatrix matrix;
    matrix.scale(zoomSlider->value(),zoomSlider->value());
    matrix.rotate(rotateSlider->value());
    matrix.translate(translateSliderX->value(), translateSliderY->value());

    graphicsView->setMatrix(matrix);
}

Well. Does not look like much, but that's almost a full fledged application that you just need to populate with data.
 

vlzvl

Arcane
Developer
Joined
Aug 7, 2017
Messages
190
Location
Athens
No. Not a game, and as I wrote we have drawings up to 100,000 polylines.

Ah i see. In this case, try to render your graphics in batches.
I do not know how Qt manages the rendering, but code like that:

Code:
   ...
   QPolygon polygon;
   polygon.setPoints(4, 50, 50,
                        100, 50,
                        100, 100,
                        50, 100);
   painter->drawPolygon(polygon);
   ...

might give you ridiculous frame rate when you call that 100k times, especially on low-end machines.
OpenGL will definitely get hurt from this since the number OpenGL commands must be few but loaded with big enough data.

..I just hope they dont use instanced rendering for unrealistic performance gains..

It is true that instanced rendering can give you a way better performance, but first try to batch up rendering, if that is possible with Qt.
Better to batch 100,000 polylines into 1000 draw calls, each one holding 100 line points, rather 100,000 draw calls to OpenGL driver.
A good rule of thumb is to batch ~100 points per primitive type i.e. line, triangle before try to render it.
Instanced rendering also requires some tweaking in shaders and for some polylines i would never touch it.
Rendering a million textured planets, i would consider using it.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
hmm. that paint() method was my very first attempt at someshit with the GLWidget and derived from the examples. And it seems the way to do it.

I can try to find out about batching, but this sounds more like something someone would say who is more into OpenGL/DirectX and more low level stuff. Of course, if performance suffers I must optimize but I am not going to develop a low level graphics engine here.

This is more of a quick test in the Qt framework that I already tried 6 years ago and liked very much, before we evaluate a long term future with it.

And besides, as I wrote in my last post I now discovered QGraphicsView that is a scene graph. That means you only create an instance and add objects once, and no more paint() stuff.

Here is a bit of code from the sample that populates the scene:

Code:
QGraphicsScene *scene;
..
for (int i = -11000; i < 11000; i += 110) {
        ++xx;
        int yy = 0;
        for (int j = -7000; j < 7000; j += 70) {
            ++yy;
            qreal x = (i + 11000) / 22000.0;
            qreal y = (j + 7000) / 14000.0;

            QColor color(image.pixel(int(image.width() * x), int(image.height() * y)));
            QGraphicsItem *item = new Chip(color, xx, yy);
            item->setPos(QPointF(i, j));
            scene->addItem(item);

            ++nitems;
        }
    }
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Code:
   ...
   QPolygon polygon;
   polygon.setPoints(4, 50, 50,
                        100, 50,
                        100, 100,
                        50, 100);
   painter->drawPolygon(polygon);
   ...

Ok, I didn't notice at first, but of course QPolygon and setPoints(..) does not belong in the paint method. That is indeed very wasteful, as only a pointer needs to be passed anyhow.

Subtle difference, but you are right that is very important [.. independent of batching and the difference to the QGraphicsScene that handles paint() by itself]

You can compile and run the 40,000 chips demo and it runs marvellously, so I'm not concerned about performance right now.
Painting new objects with the mouse, screen coordinate translation and rubberbanding are much higher on my agenda at this point.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
I still need some tips on one feature.

Although this is not yet a requirement, I already know that sooner or later the users will realize they need to click on the screen and draw a polygon/point whatever.

I don't think that it is overly difficult to do that by transforming between screen coordinates and model coordinates and adding some objects to the scene graph, but I have done such things in the past and they can get incredibly glitchy. Keep in mind that the average user simply refuses software if basic interaction is not right to his taste.

A simple example of screen coordinate transformation and object creation would help me immensely, preferrable with the QGraphicsScene class.

Yaar Podshipnik? You seem to be the man who knows qt examples in and out, and already helped me a great deal bro :salute:
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Well, I cannot have everything problem worked out beforehand. Once I have a basic application running I can work on the mouse coordinate problem, which will probably be a bit more complex.

I also found that they use LODs in the Chips sample. That's one of the reasons the performance is so good, even without OpenGL
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
I started working on this again and making good progress. Just wanted to say thank you especially Yaar Podshipnik tiagocc0 keep posting so I can give you more brofists.

As I wrote, I switched from the opensource installation to the (horribly time limited) commercial version and now back to the opensource. And I can see no real difference for the stuff I am making. The programs run the same. There is also debugger support and all. Of course you need to know the (legal) limitations like dynamic linking but since static linking needs to be explicitly enabled in the pro file, there is no real advantage to me anyhow. At least right now.

I had some problems at the beginning but only because I tried to use UI editor and dragged QML and QWidgets into the same form. I am now skipping QML and all that stuff completely (what would I need it for except convenience?) and everything works as I would expect to.

However, I have some problems understanding the performance implications because OpenGL and native both work the same - ie native runs without performance penalty - so I must be missing something important here. This is relevant to my decision making because native runs more reliable, OpenGL crashed on some computers, probably because then I have driver support on top of my normal problems (deployment isn't always easy and I needed a bit of googling for platform dlls and such).

Anyhow, a graphic scene with 10,000s of rectangles is running even on a weak laptops without problems. I don't even need to optimize anything right away, so I can begin with my actual application now. Thank you qt :salute:

i061.jpg


So what I have next is

>interactive painting with mouse and touchscreen
>the usual shebang like layers, signatures and such - I probably skip this for now
>loading/saving of data
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Ok, Qt is really making my life easy.

I now worked on one of the remaining stumbling blocks of converting between between window coordinates and scene coordinates. When you work on such stuff, most controls provide a mouseclick event but that only tells you screen coordinates. You then must find a way to convert that into where this actually translates to in your scene graph (by reversing all previous transformations of a scene, which can be a royal pain in the ass and often never really works).

In Qt that turned out actually pretty easy.

All I had to understand was that I should not use the QGraphicsView::mousePressEvent(QMouseEvent *event) but the QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)

The GraphicsSceneMouseEvent tells me the needed scenePosition, which is extremely convenient and will be the basis for a lot of required functionality.

So basically, once I had subclassed QGraphicsScene and overridden its mousePressEvent, I can go directly doing stuff at the exact position in the scene. No ugly maths, just one call of event->scenePos()

Code:
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF point;
    if (event->button() == Qt::LeftButton){
       point = event->scenePos();
       ..

Very Nice!
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
I got some of those even when I had the files in the right place. Sometimes I have to delete the build files (temporary on the build folder it creates) so it starts anew with a new makefile.
Sometimes the version is not right one when I had multiple qt versions installed. You probably know this but you have to copy some folders from the plugin folder in the qt installation directory.

Platforms is one folder that you find in the plugin one. So you copy it to where the exe is, along with the necessary dlls and also some folders from the qml dir.

So you have to get files and folders from these guys here from you qt install dir.

9Kf8tn7.png

This was quite important but I only understood it now while doing my first deployment. If you get "platform windows plugin missing" errors when running your application you need to copy the (windows) dll from your plugins/platforms folder.

The problem is that the exe expects the dll to be in a /platforms subfolder in your release version. I have no idea where this is defined, but since I deploy that dll in the proper subfolder folder it works and I can run my programs now from USB sticks on different computers. OpenGL still crashes on some but that must be driver related, in fact all kinds of shit happens with OpenGL (eg images not showing correctly)
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
My confusion has cleared up a little bit more. It's true that Native and OpenGL perform roughly the same, even with relatively large numbers of objects.

I did not do exact measurements, but if I can render 50,000 entities in Native I do not really need OpenGL, my users will be very happy with that already.

However, the point is something else entirely and I should have thought of it. OpenGL is of course greatly reducing the CPU usage, since Native must do polygon filling and everything on the CPU. In that sense OpenGL becomes a "nice to have" but I can keep Native as Default path. Sorry if that should have been clear from the start but I had seen OpenGL as the only hope because my previous toolkits like GDI+ were slow as shit.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Yes, I have studied the chips example you provided me and found much more than I hoped. I am now in data handling and stuff, that I probably could do on my own, but that QGraphicsScene(graph) is really more than I expected :salute:

The thing is a lot of toolkits look ok but break down in practical tasks but this runs stable, I can run different instances etc. I could still use some more experience with QT macros and such, but this is a toolkit by people who use it themselves and it makes my life easy in so many ways, excellent!
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
I discovered my first problem. Can't really say it's the library's fault or that it comes unexpected but here my requirement deviates very much from what they had in mind for their widget, I guess.

QPixmaps do not really play well with being scaled to values smaller than 1.0
Normally if you want to show an image, you load a Pixmap and use the size in pixels (width, height) and it looks ok. Of course Qt is not a CAD system where it is absolutely normal to use scale factors like "0.0043" (since maps are often scaled in meters it would only be a few "pixel units" i.e. 10x10 meters translates to a scene scaled to 10x10 pixels - and this is where Qt and OpenGL dont play well with my data, and the reason OpenGL crashed when I used a really large scale factor like 5,000 - at least that is solved now)

Ok, pretty sure I must develop my own transformations before I can use real data. It shouldn't be a biggy but transformation of source data coordinates was something I wanted to avoid, because I have to reverse the same transformation when the data goes back into CAD.

Anyway this is more complex stuff and not unexpected.
 

Burning Bridges

Enviado de meu SM-G3502T usando Tapatalk
Joined
Apr 21, 2006
Messages
27,561
Location
Tampon Bay
Those problems were mostly solved but I wonder how CAD systems do it. I guess they have some heavy machinery underneath to make sure images get scaled for graphics cards, which I cannot replicate immediately.

As it was established, I cannot just use the original scale of my documents because then I end up with for example one of my rasterimages 0.02*0.03 units in size, or another 200,000*300,000 units, which does not work because in QtGraphicsScene 1 unit = 1 pixel. I can display drawings of a normalized scale where pixel images are within a reasonable size (of some hundred or very few thousand pixels). Everything else either reduces the to a garbled mush (too small) or crashes the system (too big, for example 5000x5000 pixels crashed on my computer). Makes me wonder, is this connected to 32 bit vs 64 bit versions?

That is mostly solved by scaling to "reasonable" units. Actually I can just take the scale of one image and use that as scale for coordinates in the entire drawing. The other images are scaled in the resulting ratio to the first image. Of course this does not work if images are of vastly different scale, or I do need some things like resizing images before import. So, 90% a success.

The mirroring effect due to different coordinate systems was simply adjusted by flipping the y coordinates (basically *-1), plus a convenient translation so that coordinates are distributed around the 0,0 point of the scene. Another good thing is that the shape of the QGraphicsItems can be easily manipulated at run time, I can just change the coordinates in the fly and the paint() method renders the current shape. That means simple drawing and reshaping operations are a breeze.
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom