Important: Please read the Qt Code of Conduct -

How to use an image file as texture?

  • So I am currently developing a game called QuickCurver, which is a clone of game "Achtung die Kurve", lately also known as Curve Fever. I am doing the drawing stuff with QSGNodes (It is a Qt Quick Project with QML and this seemed to be the best way to draw from C++). Everything is working fine so far, and I must really say that Qt/C++ is really quick, btw my project is open sourced here, though this is not the latest build (I only commit stable ones to github).

    So what I am trying now, is applying a texture to the items. I got a png file in qrc:/images/flash.png and I want to convert it to a QSGTexture. I am aware of the QQuickView::createTextureFromImage method so I tried this, as you can see in the code below. The QQuickView view is the same view as in main.cpp (it got passed via constructor to this class). When running the code, it terminates with following error:
    ASSERT: "m_attributes.count == 1" in file /usr/include/qt/QtQuick/qsggeometry.h, line 214
    Does anyone know how to help me? I don't know what I did wrong. When I go over it with the debugger, the program does not terminate immediately, it executes even the last line of the constructor without error. So I guess the error happens in the next paint event.
    Note that the only necessary code is the constructor from the line where it says that the code now is necessary, for the sake of completion I included the rest. If you need more rest, the complete source code is on github, but the error definetely is something in the constructor, because before trying to implement textures everything worked.


    #ifndef CURVEITEM_H
    #define CURVEITEM_H
    #include <QPointF>
    #include <QtQuick/qsgnode.h>
    #include <QtQuick/qsgtexturematerial.h>
    #include <QObject>
    #include "segment.h"
    #include <QQuickWindow>
    #include <QOpenGLTexture>
    #include <QQuickWindow>
    #include <QtMath>
    #include "qcurver.h"
    #include "segment.h"
    #include <QTimer>
    #include <QImage>
    #include <QQuickView>
    #define SIZE 10
    class CurveItem : public QObject
    	explicit CurveItem(QSGNode* node, QQuickView *view);
    	int getSize();
    	QPointF getPos();
    	bool testCollision(QPointF p);
    	QColor getColor();
    	void useItem(int playerCount, QCurver** curver, QCurver* collector);
    	void setRound(int round);
    public slots:
    //	void renderUseless();
    protected slots:
    	void deuseMyself();
    	void deuseAll();
    	void deuseOthers();
    	virtual void use(QCurver* curver);
    	virtual void deuse(QCurver* curver);
    	int deUseTime = 0; //millisecs, 0 if no deUse at all
    	void deuseIn(int msecs);
    	void useMyself();
    	void useAll();
    	void useOthers();
    	int playerCount;
    	QCurver **curver;
    	QCurver *collector;
    	QPointF pos;
    	QSGNode* node;
    	QSGTextureMaterial* material = material;
    	QSGGeometry* geometry;
    	QSGGeometryNode* gnode;
    	QSGGeometry::Point2D *vertices;
    	QSGTexture* texture;
    	QColor color;
    	QTimer* timer;
    	bool invisible = false;
    	int round = -1;
    	QQuickView *view;
    #endif // CURVEITEM_H


    CurveItem::CurveItem(QSGNode *node, QQuickView *view) {
    	this->node = node;
    	this->view = view;
    	pos = QPointF(segment::randInt(10, 990), segment::randInt(10,990));
    	int r = segment::randInt(0,2);
    	switch (r) {
    	case 0:
    		color = Qt::green;
    	case 1:
    		color = Qt::red;
    		color = Qt::blue;
            //here begins the necessary code!
    	gnode = new QSGGeometryNode;
    	geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0);
    	geometry->setDrawingMode(GL_TRIANGLES); //we essentially create a rectangle later with 6 vertices (2 triangles)
    	QImage *img = new QImage(":/images/flash.png"); //we load the file, the file does exist
    	this->material = new QSGTextureMaterial;
    	texture = view->createTextureFromImage(*img); //we create the texture
    	texture->setMipmapFiltering(QSGTexture::Linear); //some random modifications
    	this->material->setTexture(texture); //set the texture
    	vertices = geometry->vertexDataAsPoint2D();
    	vertices[2].set(pos.x()+10, pos.y()-10);
    	vertices[3].set(pos.x()+10, pos.y()+10);
    	vertices[4].set(pos.x()-10, pos.y()+10);
    	vertices[5].set(pos.x()+10, pos.y()-10);

Log in to reply