Draw axis text label in OpenGL for a Qt project - qt

I have an x, y, z axis in the lower left-hand corner to give the user an idea of orientation. I want to label these axes with the appropriate x, y, and z labels.
I know that I don't want to use Glut to accomplish this since it's old and outdated, and was wondering if I could leverage QPainter to help label these axes.
NOTE: I've seen this, but found it too much: http://nehe.gamedev.net/tutorial/bitmap_fonts/17002/

You can use QPainter to draw text on any paint device. A QGLWidget is such a paint device; QPainter will then use OpenGL to draw the text (or whatever you want to draw). Guessing you are using a QGLWidget to draw your scene, you can just put the QPainter stuff at the end of your paintEvent:
MyGLWidget::paintEvent(QPaintEvent *event)
{
// draw OpenGL scene
// ...
// draw labels:
QPainter p(this);
p.drawText(..., ..., "X");
p.drawText(..., ..., "Y");
p.drawText(..., ..., "Z");
p.end();
}
Also have a look at the Qt OpenGL Overpainting Example.

Because (you said) you don't have access to QPainter for some reason, you need some kind of font rendering library for OpenGL. You could use FTGL or you can make your own renderer using freetype 2. Starting with Qt version 4.8.1 it should be possible to access individual glyphs using QRawFont (without having to directly deal with freetype), which can make implementing your own font rendering routines even easier.
If your object is QPaintDevice or QGLWidget, then use QPainter. It might be slower than traditional texture font, but it'll save you (from) another coding headache.

Related

Best way to draw QPixmap with 'color mod'

Some rendering libraries allow to set a 'color mod' (for example, in SDL2 you do it with SDL_SetTextureColorMod) when drawing a texture, which would effectively multiply the colours of the pixels by a given value before drawing. What is the best way to achieve this in Qt5, for example, when drawing a QPixmap with QPainter::drawPixmap? So far the only option I see is to use a temporary pixmap, fill it with the colour by which I want to multiply, then draw on it with QPainter::CompositionMode_Multiply and then draw the result to the target device. Is there a more straightforward way that maybe does not include drawing to a temporary pixmap?
You can do without the temporay pixmap by drawing a rect with size of your pixmap in your target:
QPixmap const src(":/images/img.png");
painter->fillRect(QRect(QPoint(0, 0), src.size()), Qt::red);
painter->setCompositionMode(QPainter::CompositionMode_Multiply);
painter->drawPixmap(QPoint(0, 0), src);
If your pixmap has transparent regions, you can add painter->setClipRegion(src.mask()); before calling fillRect.

How can I create QColor objects in Qt for the SRGB color space?

I can't seem to find (official or unofficial) documentation on Qt colors vs color spaces.
I would like to define QColor's for my Qt application. I am coming from an OS X background, where I am accustomed to having [NSColor colorWithDeviceRed:green:blue:alpha:] and also [NSColor colorWithSRGBRed:green:blue:alpha:], and other options as well.
Most of the time, I would like to use SRGB. How can I achieve that? It would be also good to know where using the default QColor(int,int,int,int) constructor leads to, but I suspect it will be device colors.
My target platform is mostly Windows, so if you can only come up with a platform-dependent way of creating QColor objects with components defined in the SRGB color space, go ahead!
QColor is just a container for four ints. Everything depends on what you use it for. You'd need to show example code of how you use the QColor instance.
In most cases, though, QColor will end up being used by the raster paint engine back end. In such case, it has the meaning of the device color. Specifically, if you paint using QColor, it is not ever seen directly by OS X drawing functions. OS X is only passed a texture/image that has been already rendered by the raster paint engine.

How to make qt qgraphicsview scale to not affect stipple pattern?

I draw few rectangles inside the QGraphicsView ; I use custom stipple pattern for these by creating a QBrush with my QPixmap. This gets displayed with the default zoom level as expected.
When I call view->scale(), the rectangles show up bigger or smaller as I expected. However Qt has scaled the individual bits of the stipple pattern which is not expected; I expected it to draw the larger or smaller rectangle again with the brush.
Eg.
If I had used a stipple pattern with one pixel dot and pixel space, after zooming in, I want to see a larger rectangle but I want the same stipple pattern with same pixel gaps. Is this achievable somehow? Thanks.
I ran into the same problem while developing an EDA tool companion in Qt.
After some trying, what I did (and seems to work for me) is to create a custom graphics item. On the paint method, I do:
QBrush newBrush = brush_with_pattern;
newBrush.setTransform(QTransform(painter->worldTransform().inverted()));
painter->setBrush(newBrush);
That is to apply the inverse transformation of the item to the brush (so it does not scale).
I think that the setDashOffset is only for the border of the shapes (not the fill).
You may use QPen::setDashOffset:
http://harmattan-dev.nokia.com/docs/library/html/qt4/qpen.html#setDashOffset
You'll need to set the offset based on the scenes zoom/scale level. You can grab a pointer to the scene in your item by calling scene(), don't forget to check for NULL though since it will be NULL when not added to the scene (although you shouldn't in theory get a paint() when not in a scene).
The other option is to use:
http://doc.qt.digia.com/qt/qpainter.html#scale
To undo the views scaling on your painter.
In case anyone is still looking on this, a related question here regarding scaling of standard fill patterns instead of pixmap fill patterns may help. Basically, it may not be possible to modify scaling of standard fill patterns (a few workaround ideas are listed), but, working with alpha values instead gives the desired effect if you are looking for varying colors, especially gray levels - and is much less convoluted.

QBrush texture without tiling

Is there an easy way to get rid of tiling when using a QBrush with texture?
QImage* texture = CreateQImage(); // create texture
QBrush* brush = new QBrush(*texture); // create texture brush
QPainter* painter = CreateQPainter(); // create painter
painter->fillRectangle(0, 0, 500, 500, *brush);
Suppose we have a QImage texture with size of 20x20 pixels. The code above will tile this texture all across the rectangle being filled. Is there an easy way to draw only a single instance of this texture? The QBrush usage is crucial.
Theoretically, I could reload every fill and draw method of the QPainter that takes a QBrush as input and use a QPainter.drawImage() method, but I think there must be a simplier way.
Thanks, Tony.
I don't think there is (see Qt::BrushStyle - the only style with a texture tiles it), and it wouldn't really make sens IMO. If you just want one image, use the drawImage functions as you've stated.
(One of the problems with not tiling is: what do you fill the rest of the rectangle with? Nothing? Some default background color? Some other QBrush attribute?)

How do I erase a portion of a bitmap in Qt?

Any idea on how to erase a portion of a bitmap just like Android's PorterDuff Mode?
I am creating an application like Paint, and I don't know how to erase the drawings I have written using the pen.
Any idea regarding this one?
Thank you!
I suggest you use the QPainter class which can perform various drawing operations on a QBitmap (more precisely: it draws on a QPaintDevice, from which QBitmap derives).
Among the various operations of the painter, there is QPainter::eraseRect() which can erase a portion of a QBitmap.
This is the way you use it:
QBitmap b;
QPainter p( &b );
p.eraseRect( x, y, w, h ); // With x, y, w and h defining the portion
// of your bitmap you want to erase

Resources