Is there an easy way to use QMatrix4x4 with OpenGL functions, specifically glMultMatrixf?
If I understand this right, I'd have to transpose the matrix, and be sure to convert qreal (which can be either float or double depending on the underlying system) to GLfloat.
Isn't there a function which does this for me?
I also have the same problem with QVector3D, which again I need as GLfloat array in the function glVertex3fv.
First I want to mention that QMatrix4x4 has built-in operators for matrix multiplication (with a second matrix, a vector or a scalar). However, your question still needs an answer, as you want to pass a matrix to OpenGL sooner or later.
QMatrix4x4 uses qreals for internal representation. While the class is intended to be used with OpenGL directly (using constData() as suggested by Bart in his answer), you can make sure you pass it to the corresponding OpenGL function depending on the type, if you want to keep platform compatibility (on embedded devices, qreal is float!):
// these are defined in the OpenGL headers:
void glMultMatrixf(const GLfloat *m);
void glMultMatrixd(const GLdouble *m);
// add overloaded functions which call the underlying OpenGL function
inline void glMultMatrix(const GLfloat *m) { glMultMatrixf(m); }
inline void glMultMatrix(const GLdouble *m) { glMultMatrixd(m); }
// add an overload for QMatrix4x4 for convenience
inline void glMultMatrix(const QMatrix4x4 &m) { glMultMatrix(m.constData()); }
You can also use this mechanism for vectors, here the glVertex* family, where it makes even more sense because of the number of components the "raw pointer" overloads need to consider, but the object oriented overloads can do automatically for you:
inline void glVertex2v(const GLfloat *v) { glVertex2fv(v); }
inline void glVertex2v(const GLdouble *v) { glVertex2dv(v); }
inline void glVertex3v(const GLfloat *v) { glVertex3fv(v); }
inline void glVertex3v(const GLdouble *v) { glVertex3dv(v); }
inline void glVertex4v(const GLfloat *v) { glVertex4fv(v); }
inline void glVertex4v(const GLdouble *v) { glVertex4dv(v); }
// Note that QVectorND use floats, but we check this during compile time...
Q_STATIC_ASSERT(sizeof(QVector2D) == 2*sizeof(float));
Q_STATIC_ASSERT(sizeof(QVector3D) == 3*sizeof(float));
Q_STATIC_ASSERT(sizeof(QVector4D) == 4*sizeof(float));
inline void glVertex(const QVector2D &v) { glVertex2v(reinterpret_cast<const float*>(&v)); }
inline void glVertex(const QVector3D &v) { glVertex3v(reinterpret_cast<const float*>(&v)); }
inline void glVertex(const QVector4D &v) { glVertex4v(reinterpret_cast<const float*>(&v)); }
// Even for QPointF we can do it!
Q_STATIC_ASSERT(sizeof(QPointF) == 2*sizeof(qreal));
inline void glVertex(const QPointF &v) { glVertex4v(reinterpret_cast<const qreal*>(&v)); }
So your code keeps valid if the following changes are made:
Qt changes the representation of QVector* / QMatrix to use floats / doubles respectively,
Your code changes the number of components of vectors
... while especially the second isn't the case when using raw OpenGL commands like glVertex3f.
The Q_STATIC_ASSERTions in the code above are only defined since Qt 5.0. If you are using Qt4 (or code with Qt4 compatibility), add this in some global header file / before your definitions: http://ideone.com/VDPUSg [source: Qt5 / qglobal.h]
qreal is defined to be a double on all platforms, except for ARM architectures. So most likely for you they are doubles.
That said, yes, you can use your QMatrix4x4 perfectly fine with OpenGL, using the constData() method. Of course with a double type you would either have to use glMultMatrixd, or create a float matrix out of it. Which might not be what you want to do. There are various examples by Qt which use the matrix type in their OpenGL demos.
I personally never use Qt's matrix and vector types for my OpenGL code though (even though I extensively use Qt), but rather go for a library like Eigen, GLM, or something else suitable.
Related
Is it possible for QTextLayout to render several characters, but to process/handle it as one character. For example rendering a code point like: [U+202e], and when moving the caret/calculating positions, it is treated as one character.
Edited:
Please check this following issue, were I explain what I'm trying to do. It for the edbee Qt component. It's using QTextLayout for line rendering.
https://github.com/edbee/edbee-lib/issues/127
Possibly it isn't possible with QTextLayout, the documentation is quite limited.
According to Qt docs:
"The class has a rather low level API and unless you intend to implement your own text rendering for some specialized widget, you probably won't need to use it directly." - https://doc.qt.io/qt-5/qtextlayout.html#details
You should probably use a QLineEdit or a QTextEdit (each has a method called setReadOnly(bool)).
Before answering the question, I will point out that the CursorMode enum (https://doc.qt.io/qt-5/qtextlayout.html#CursorMode-enum) seems very promising for this problem, but to me, the documentation isn't clear on how to use it or set it.
Now to answer your question in regards to QLineEdit or QTextEdit, it's a bit complicated, but it's the same for QLineEdit and QTextEdit, so lets look at QTextEdit.
Firstly, mouse clicks: QTextEdit has a signal called cursorPositionChanged(), which will be helpful here. You'll want to connect that to a custom slot, which can make use of the function moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor) (https://doc.qt.io/qt-5/qtextedit.html#moveCursor). Notice that there are very helpful enumeration values for you here in QTextCursor::MoveOperation regarding word hopping (https://doc.qt.io/qt-5/qtextcursor.html#MoveOperation-enum). How do we put all of this together? Well, probably the right way to do it is to determine the width of the chars to the left of the cursor's position and the width of the chars to the right of the cursor's position when the cursorPositionChanged() signal is emitted and go to the side of the word that has less width. However, I'm not sure how to do that. At this point I'd settle with checking the number of chars to the left and right and going to the side with less.
Secondly, keyboard presses: This goes a bit out of my knowledge, but almost everything drawable and iteractable inherits from QWidget. Take a look at https://doc.qt.io/qt-5/qwidget.html#keyPressEvent and it's possible that overriding that in your own implementation of QTextEdit is necessary to get the left arrow and right arrow keypresses to jump words (once you get that part it's pretty easy, just use the same function as last section for moving the cursor, or in the case of QLineEdit, cursorWordForward()/cursorWordBackward()).
All this being said, I've so far been assuming that you're not deleting anything or selecting anything. Selection can be a real pain depending on if you allow multiple selections, but the functions are all there in the documentation to implement those things.
Example of mouse click impl:
myclass.hpp
#include <QTextEdit>
#include <QTextCursor>
#include <QObject>
#include <QString>
int distance_to_word_beginning_or_end(const QString &str, int index, bool beginning);
class MyClass {
MyClass();
~MyClass();
private:
QTextEdit *text_edit;
public slots:
void text_edit_changed_cursor_location();
};
myclass.cpp
#include "myclass.hpp"
int distance_to_word_beginning_or_end(const QString &str, int index, bool beginning)
{
// return the distance from the beginning or end of the word from the index given
int inc_or_dec = (beginning) ? -1 : 1;
int distance = 0;
while (index >= 0 && index < str.length())
{
if (str.at(index) == ' ' || str.at(index) == '\n' || str.at(index) == '\t')
{
return distance;
}
distance++;
index += inc_or_dec;
}
return --distance;
}
MyClass::MyClass()
{
text_edit = new QTextEdit();
QObject::connect(text_edit, &QTextEdit::cursorPositionChanged, this, &MyClass::text_edit_changed_cursor_location);
}
MyClass::~MyClass()
{
delete text_edit;
}
void MyClass::text_edit_changed_cursor_location()
{
QString text_edit_string = text_edit->text();
QTextCursor text_edit_cursor = text_edit->textCursor();
auto current_position = text_edit_cursor.position();
QTextCursor new_text_cursor;
int distance_to_beginning = distance_to_word_beginning_or_end(text_edit_string, current_position, true);
int distance_to_end = distance_to_word_beginning_or_end(text_edit_string, current_position, false);
auto movement_type;
if (distance_to_beginning > distance_to_end)
{
new_text_cursor.setPosition(current_position + distance_to_end);
} else {
new_text_cursor.setPosition(current_position - distance_to_beginning);
}
text_edit->setTextCursor(new_text_cursor);
}
I am writing a function:
void callFunctionAt(uint32_t address){
//There is a void at address, how do I run it?
}
This is in Atmel Studio's C++. If previous questions are to be believed, the simple answer is to write the line "address();". This cannot be correct. Without changing the header of this function, how would one call the function located at the address given?
The answer should be system-agnostic for all micro controllers which support standard c++ compilation.
The common way to do this is to give the argument the correct type. Then you can call it right away:
void callFunctionAt(void (*address)()) {
address();
}
However, since you wrote "Without changing the header of this function [...]", you need to cast the unsigned integer to a function pointer:
void callFunctionAt(uint32_t address) {
void (*f)() = reinterpret_cast<void (*f)()>(address);
f();
}
But this is not safe and not portabel because it assumes that the uint32_t can be casted into a function pointer. And this needs not to be true: "[...] system-agnostic for all micro controllers [...]". Function pointers can have other widths than 32 bits. Pointers in general might consist of more than the pure address, for example include a selector for memory spaces, depending on the system's architecture.
If you got the address from a linker script, you might have declared it like this:
extern const uint32_t ext_func;
And like to use it so:
callFunctionAt(ext_func);
But you can change the declaration into:
extern void ext_func();
And call it directly or indirectly:
ext_func();
callFunctionAt(&ext_func);
The definition in the linker can stay as it is, because the linker knows nothing about types.
There is no generic way. It depends on which compiler you are using. In the following I'll assume avr-g++ because it's common and freely available.
Spoiler: On AVR, it's more complicated than on most other machines.
Suppose you actually have a uint32_t address which would be a byte address. Function pointers in avr-g++ are word addresses actually, where a word has 16 bits. Hence, you'll have to divide the byte address by 2 first to get a word address; then cast it to a function pointer and call it:
#include <stdint.h>
typedef void (*func_t)(void);
void callFunctionAt (uint32_t byte_address)
{
func_t func = (func_t) (byte_address >> 1);
func();
}
If you started with a word address, then you can call it without further ado:
void callFunctionAt (uint32_t address)
{
((func_t) word_address)();
}
This will only work for devices with up to 128KiB of flash memory!
The reason is that addresses in avr-g++ are 16 bits long, cf. the layout of void* as per avr-gcc ABI. This means using scalar addresses on devices with flash > 128KiB will not work in general, for example when you issue callFunctionAt (0x30000) on an ATmega2560.
On such devices, the 16-bit address in Z register used by EICALL instruction is extended by the value held in the EIND special function register, and you must not change EIND after entering main. The avr-g++ documentation is clear about that.
The crucial point here is how you are getting the address. First, in order to call and pass it around properly, use a function pointer:
typedef void (*func_t)(void);
void callFunctionAt (func_t address)
{
address();
}
void func (void);
void call_func()
{
func_t addr = func;
callFunctionAt (addr);
}
I am using void argument in the declaration because this is how you'd do it in C.
Or, if you don't like the typedef:
void callFunctionAt (void (*address)(void))
{
address();
}
void func (void);
void call_func ()
{
void (*addr)(void) = func;
callFunctionAt (addr);
}
If you want to call a function at a specific word address like, for example 0x0 to "reset"1 the µC, you could
void call_0x0()
{
callFunctionAt ((func_t) 0x0);
}
but whether this works depends on where your vector table is located, or more specifically, how EIND was initialized by the startup code. What will always work is using a symbol and define it with -Wl,--defsym,func=0 when linking with the following code:
extern "C" void func();
void call_func ()
{
void (*addr)(void) = func;
callFunctionAt (addr);
}
The big difference compared to using 0x0 directly it that the compiler will wrap symbol func with symbol modifier gs which it will not do when using 0x0 directly:
_Z9call_funcv:
ldi r24,lo8(gs(func))
ldi r25,hi8(gs(func))
jmp _Z14callFunctionAtPFvvE
This is needed if the address is out of the scope of EIJMP to advise the linker to generate a stub.
1 This will not reset the hardware. The best approach to force a reset is by letting the watchdog timer (WDT) issue a reset for you.
Methods
Yet another situation is when you want the address of a non-static method of a class because you also need a this pointer in that case:
class A
{
int a = 1;
public:
int method1 () { return a += 1; }
int method2 () { return a += 2; }
};
void callFunctionAt (A *b, int (A::*f)())
{
A a;
(a.*f)();
(b->*f)();
}
void call_method ()
{
A a;
callFunctionAt (&a, &A::method1);
callFunctionAt (&a, &A::method2);
}
The 2nd argument of callFunctionAt specifies which method (of a given prototype) you want, but you also need an object (or pointer to one) to apply it. avr-g++ will use gs when taking the method's address (provided the following call(s) cannot be inlined), thus it will also work for all AVR devices.
Based on comments I think you are asking about how microcontroller calls function.
Could you compile your program to see assembly files?
I would recommend you to read one of them.
Every function after compiling are translated to instructions that CPU can do (loading to register, adding to register etc.).
So then your void foo(int x) {statements;} compile to simple CPU instructions and whenever you call foo(x) in your program, you are moving to instructions that are related to foo - you are calling a subroutine.
As far as I remeber there is a CALL function in AVR to invoke subroutines and the name of subroutine is the label where executing program jump and invoking next instruction at adress.
I think you can clarify your doubts when you read some AVR assembly tutorials.
It is fun (at least for me) to see what exactly CPU do when it calls function that I wrote, but it required to know what instructions do. You develop in AVR so there is a set of instructions that you can read about in this PDF and compare with your assembly files.
I have a Qt project, there I have an Object, which is going to be copied a lot of time. Therefor I would like to add move semantics.
#ifndef OBJECTTOCOPY_H
#define OBJECTTOCOPY_H
#include <QColor>
#include <QString>
#include <QDataStream>
namespace level_1 {
namespace level_2 {
class ObjectToCopy {
public:
explicit ObjectToCopy(const QString& _name = "", const QColor& colorBody = QColor() );
// MOVE
ObjectToCopy(ObjectToCopy && other);
static quint32 _valueInt32;
static quint16 _valueInt16;
QString _name;
QColor _colorBody;
private:
};
}
}
#endif // OBJECTTOCOPY_H
How do I steal the pointers of the member variables, since they are no pointers?
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( other._name )
, _colorBody( other._colorBody )
{
other._valueInt32 = 0;
other._valueInt16 = 0;
other.name.clear();
other._colorBody = QColor();
}
Does that make sense for non-pointers?
Is it ok to reset QString 's like string.clear(); to mark that for the garbage collector?
How could I reset a QColor object?
You can add move semantics of course, but in your case there is no need in this at all. quint32, quint16 are moved by copying. QColor is wrapper around union and has no move constructor (and doesn't need one) and will also be moved by copying. QString is reference counted type in QT. It has move constructor in recent versions of library, but the difference in speed will be minimal (difference between swapping pointer and incrementing reference counter).
You are looking for std::move:
ObjectToCopy::ObjectToCopy (ObjectToCopy&& other)
: _valueInt32( other._valueInt32 )
, _valueInt16( other._valueInt16 )
, _name( std::move(other._name) )
, _colorBody( std::move(other._colorBody) )
{
other._valueInt32 = 0; //probably not necessary
other._valueInt16 = 0; //probably not necessary
//other.name.clear(); //not necessary
//other._colorBody = nullptr; //not necessary
}
It makes sense to move non-pointers. You are in the process of making such an object. Moving integers doesn't help, but doesn't hurt either, so you may as well do it for consistancy. Moving things that don't have a move constructor also works: If no move constructor is available the copy constructor is used (moving is not always better, but not worse either).
The implementation above says "move by copying the ints and moving the name and the _colorBody".
Make sure you do not read from variables you moved from.
It is ok, but not necessary. other is supposed to be a temporary that will get destroyed anyways. (C++ does not have a garbage collector in your sense)
Also once an object is moved from it tends to be in the cleared state like for QString, but that is not always the case.
You cannot really. You can assign a default constructed one like other._colorBody = QColor(); but that just means it sets the color to black. A QColor cannot be empty, it always has some color.
Also read What are move semantics?
In QT have the following code that starts a thread to send out commands. The thread takes a char * and int as arguments. In the "run" I use the pointer that is given by the constuctor. The code is:
MyThread::MyThread(char * payld, int payld_size)
{
payload_size = payld_size;
payload_p = payld;
}
void MyThread::run()
{
while(...)
{
sendCommand(payload_p, payload_size);
}
}
Unfortunately this doesn´t work and my application crashes when I try to use thread.start(). But when I change it to:
MyThread::MyThread(char * payld, int payld_size)
{
payload_size = payld_size;
payload_p = payld;
for(int i=0; i<payload_size; i++)
{
payload[i] = payld[i];
}
}
void MyThread::run()
{
while(...)
{
sendCommand(payload, payload_size);
}
}
The code does run and only crashes sometimes (looks pretty random to me). Can anybody Explain me why version one doesnt work and version two does? And any ideas on why the second code sometimes crashes? Could it be because the size of payload is not predefined (in the header file I defined it as
char payload[];
When I define it as:
char payload[10];
it seems to work better, but it is annoying to test since the crashes are pretty random.
instead of fiddling with char*, I would switch to QString (since you're using Qt). It takes a bit of learning, but it's almost mandatory to get code working smoothly in this framework. Then declare
QString payload;
and depending on sendCommand implementation, use one of the member functions QString to get the char*, like payload.toLatin1()
Writing some signal processing in CUDA I recently made huge progress in optimizing it. By using 1D textures and adjusting my access patterns I managed to get a 10× performance boost. (I previously tried transaction aligned prefetching from global into shared memory, but the nonuniform access patterns happening later messed up the warp→shared cache bank association (I think)).
So now I'm facing the problem, how CUDA textures and bindings interact with asynchronous memcpy.
Consider the following kernel
texture<...> mytexture;
__global__ void mykernel(float *pOut)
{
pOut[threadIdx.x] = tex1Dfetch(texture, threadIdx.x);
}
The kernel is launched in multiple streams
extern void *sourcedata;
#define N_CUDA_STREAMS ...
cudaStream stream[N_CUDA_STREAMS];
void *d_pOut[N_CUDA_STREAMS];
void *d_texData[N_CUDA_STREAMS];
for(int k_stream = 0; k_stream < N_CUDA_STREAMS; k_stream++) {
cudaStreamCreate(stream[k_stream]);
cudaMalloc(&d_pOut[k_stream], ...);
cudaMalloc(&d_texData[k_stream], ...);
}
/* ... */
for(int i_datablock; i_datablock < n_datablocks; i_datablock++) {
int const k_stream = i_datablock % N_CUDA_STREAMS;
cudaMemcpyAsync(d_texData[k_stream], (char*)sourcedata + i_datablock * blocksize, ..., stream[k_stream]);
cudaBindTexture(0, &mytexture, d_texData[k_stream], ...);
mykernel<<<..., stream[k_stream]>>>(d_pOut);
}
Now what I wonder about is, since there is only one texture reference, what happens when I bind a buffer to a texture while other streams' kernels access that texture? cudaBindStream doesn't take a stream parameter, so I'm worried that by binding the texture to another device pointer while running kernels are asynchronously accessing said texture I'll divert their accesses to the other data.
The CUDA documentation doesn't tell anything about this. If have to to disentangle this to allow concurrent access, it seems I'd have to create a number of texture references and use a switch statementto chose between them, based on the stream number passed as a kernel launch parameter.
Unfortunately CUDA doesn't allow to put arrays of textures on the device side, i.e. the following does not work:
texture<...> texarray[N_CUDA_STREAMS];
Layered textures are not an option, because the amount of data I have only fits within a plain 1D texture not bound to a CUDA array (see table F-2 in the CUDA 4.2 C Programming Guide).
Indeed you cannot unbind the texture while still using it in a different stream.
Since the number of streams doesn't need to be large to hide the asynchronous memcpys (2 would already do), you could use C++ templates to give each stream its own texture:
texture<float, 1, cudaReadModeElementType> mytexture1;
texture<float, 1, cudaReadModeElementType> mytexture2;
template<int TexSel> __device__ float myTex1Dfetch(int x);
template<> __device__ float myTex1Dfetch<1>(int x) { return tex1Dfetch(mytexture1, x); }
template<> __device__ float myTex1Dfetch<2>(int x) { return tex1Dfetch(mytexture2, x); }
template<int TexSel> __global__ void mykernel(float *pOut)
{
pOut[threadIdx.x] = myTex1Dfetch<TexSel>(threadIdx.x);
}
int main(void)
{
float *out_d[2];
// ...
mykernel<1><<<blocks, threads, stream[0]>>>(out_d[0]);
mykernel<2><<<blocks, threads, stream[1]>>>(out_d[1]);
// ...
}