Current Error: vec4 has a user-defined constructor or non-trivial default constructor.
Hello,
I looked up a few things on this bug, by going into what a non-trivial default constructor is and got no where. The code is currently this
union
{
float elements[4 * 4];
vec4 columns[4];
};
To my current knowledge as long as i was to flag the constructor as default i would be fine which i did here.
vec4() = default;
vec4(const float& x, const float& y, const float& z, const float& w);
If anyone has any knowledge on what is going on here, or can help can help me reach a conclusion that would be great!
Thanks
Related
Ignoring coding patterns and code clarity/quality:
This is a question I just don't know if it's inherently bad or inconsequential. I can't find enough on the inner workings of assigning to say: gl_FragColor in WebGL 1.0 or to an out variable in WebGL 2 (layout(location = 0) out vec4 color).
Is there some inherent additional performance cost for doing something like:
void main() {
gl_FragColor = vec4(0., 0., 0., 1.);
vec4 val = gl_FragColor * something;
...
gl_FragColor = val;
}
Or is it better to work entirely with interim declared variables and then assign to the out value a single time?
void main() {
vec4 thing = vec4(0., 0., 0., 1.);
vec4 val = thing * something;
...
gl_FragColor = val;
}
I'm only guessing the answer is "no", there is no consequence. The driver can do whatever it wants/needs to get the correct answer. If gl_FragColor is special the driver can make its own temp. GPU Vendors compete for perf. Shaders are translated to the assembly language of the GPU itself so it's unlikely gl_FragColor is special except as a way to tell the compiler which value to actually output when it's all done computing.
I do it all the time. So does three.js as an example
I'm working on an game, using OpenGL ES 2.0
I would like to eliminate branches in the fragment shader, if possible. But there is a function, which I cannot improve:
float HS(in float p, in float c) {
float ap = abs(p);
if( ap > (c*1.5) ) {
return ap - c ;
} else {
return mod(ap+0.5*c,c)-0.5*c;
}
}
The c is a constant in most of the cases, if it helps in this situation. I use this function like this:
vec3 op = sign(p1)*vec3(
HS(p1.x, cc),
HS(p1.y, cc),
HS(p1.z, cc)
);
Here's a trick that "eliminates" the branch. But the more important thing it does is vectorize your code. After all, the compiler probably eliminated the branch for you; it's far less likely that it realized it could do this:
vec3 HSvec(in vec3 p, in const float c)
{
vec3 ap = abs(p);
vec3 side1 = ap - c;
const float val = 0.5 * c;
vec3 side2 = mod(ap + val, vec3(c)) - val;
bvec3 tests = greaterThan(ap, vec3(c*1.5));
return mix(side2, side1, vec3(tests));
}
This eliminates lots of redundant computations, as well as doing lots of computations simultaneously.
The key here is the mix function. mix performs linear interpolation between the two arguments based on the third. But since a bool converted to a float will be exactly 1.0 or 0.0, it's really just selecting either side1 or side2. And this selection is defined by the results of the component-wise greaterThan operation.
This question already has answers here:
How to enforce move semantics when a vector grows?
(3 answers)
Closed 8 years ago.
I want to use C++11 move semantics. And I wrote the following class:
class ColorM
{
public:
ColorM(float _r, float _g, float _b, float _a){
qDebug()<<"Constructor";
r = _r;
g = _g;
b = _b;
a = _a;
m = new float[16];
}
ColorM(const ColorM &other){
qDebug()<<"Copy Constructor";
}
~ColorM(){
if (m != nullptr)
{
qDebug()<<"Deleting resource.";
// Delete the resource.
delete[] m;
}
}
// Move constructor.
ColorM(ColorM&& other)
{
qDebug()<<"Move Constructor";
r = other.r;
g = other.g;
b = other.b;
a = other.a;
m = other.m;
other.m = nullptr;
}
float r;
float g;
float b;
float a;
float *m;
private:
};
When I try to:
std::vector<ColorM> vec;
vec.push_back(ColorM(0.1, 0.6, 0.3, 0.7));
vec.push_back(ColorM(0.2, 0.6, 0.3, 0.7));
vec.push_back(ColorM(0.3, 0.6, 0.3, 0.7));
I got copy constructor calls. What I doing wrong?
I have used this as example. And compile it with g++.
Here is QT project I used for my tests: http://wikisend.com/download/261514/MoveConstructor.zip
You can use std::vector<T>::emplace_back function
std::vector<ColorM> vec;
vec.emplace_back(0.1, 0.6, 0.3, 0.7); // Will call
vec.emplace_back(0.2, 0.6, 0.3, 0.7); // ColorM::ColorM(float _r, float _g, ..) ctor
vec.emplace_back(0.3, 0.6, 0.3, 0.7);
Or (use ColorM move constructor)
std::vector<ColorM> vec;
vec.emplace_back(ColorM(0.1, 0.6, 0.3, 0.7)); // Should be equivalent to your code
vec.emplace_back(ColorM(0.2, 0.6, 0.3, 0.7));
vec.emplace_back(ColorM(0.3, 0.6, 0.3, 0.7));
Note: I disagree with the answer by user2485710. Since the ColorM(0.1, 0.6, 0.3, 0.7) argument to push_back is a temporary, I expect the compiler to recognize it as an r-value reference and apply the move constructor, without using std::move, since push_back has an overload for r-value references.
In other words, the emplace_back taking a ColorM object should avoid copies like push_back; in the case of emplace_back, you will necessarily construct in place.
With the second version above, you should get better diagnostic messages compared to push_back, i.e. a failure at compile time instead of this subtle unexpected use of the copy constructor.
That's because of the signatures for your constructors and the argument given to your push_back() operation.
In a nutshell T() generates a new instance of an object of type T, if this instance it's not related to a label/variable, the instance remains unnamed, but his doesn't change its own type, it's always "something" of type T ( it could be even considered as T& or const T& but that's not the argument of this topic).
To reach for the T&& signature you need to cast to T&& and in C++11 this is a job for std::move which is also an unconditional kind of cast, so it's quite easy to use pretty much anywhere.
You can add std::move to your constructor inside your class or inside the push_back, your call.
I'm trying to use the following code:
cv::MatND hist;
cv::Mat image = cv::imread("image.bmp");
float *range = new float[33];
int histSize = 32;
int channel = 0;
for (int i = 0; i < 33; ++i)
range[i] = (float)6602.0 + 21*i;
float **ranges = ⦥
cv::calcHist(&frame.get<0>(), 1, &channel, cv::Mat(), hist, 1, &histSize, ranges, false, false);
The image is grayscale, so I'm using the zeroth channel to get the histogram, I know the range is uniform but I wanted to know my boundaries exactly, and the image is CV_16U type (in the original code the image is read from a camera, but that's too long to include here)
My problem is that at compilation I get the following errors:
error C2665: 'cv::calcHist' : none of the 3 overloads could convert all the argument types
C:\opencv\build_x64\include\opencv2/imgproc/imgproc.hpp(670): could be 'void cv::calcHist(const cv::Mat *,int,const int *,cv::InputArray,cv::OutputArray,int,const int *,const float **,bool,bool)'
C:\opencv\build_x64\include\opencv2/imgproc/imgproc.hpp(676): or 'void cv::calcHist(const cv::Mat *,int,const int *,cv::InputArray,cv::SparseMat &,int,const int *,const float **,bool,bool)'
while trying to match the argument list '(cv::Mat *, int, int *, cv::Mat, cv::MatND, int, int *, float **, bool, bool)'
I know its kind of silly, but I'm about to go crazy. Any help is appreciated.
PS: I'm using opencv 2.4.2 on Microsoft Visual C++ express in 64-bit environment.
Best,
Baris
If your OpenCV version is newer than 2.3, which seems to be the case, you should know that cv::Mat and cv::MatND are combined.
But about the error, as in the new OpenCV cv::Mat can have any number of dimensions, they have changed the definition, as you can see here:
C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
You can also see in the brand new tutorial here, a simple cv::Mat would do the trick:
cv::Mat hist;
Using the new documentation would help you clear these things up, unfortunately most of the tutorials and codes available are based on the old OpenCV which has undertaken big changes to get to the current version.
If...
vec3 myVec3 = vec3(1.0, 0.0, 0.5); // myVec3 = {1.0, 0.0, 0.5}
vec3 temp = vec3(myVec3); // temp = myVec3
vec2 myVec2 = vec2(myVec3); // myVec2 = {myVec3.x, myVec3.y}
myVec4 = vec4(myVec2, temp, 0.0); // myVec4 = {myVec2.x, myVec2.y, temp.x, 0.0}
Then what does the following represent?
myVec4 = vec4(temp, myVec2, 0.0); // myVec4 =
Thanks .
If temp is indeed a vec3 as you’ve defined, both of the constructors for myVec4 are illegal, as both contain enough components in the first two arguments to initialize the entire vec4.
The way I would figure stuff like that out, assuming it compiles and runs, it to use the debugger or printf to see what you get.
On my xode 3.2.x - It does not compile. In fact vec2 myVec2 = vec2(myVec3); also does not compile.
Also: last line has an error which makes sense when you read it.
code.mm:73:0 code.mm:73: error: no matching function for call to
'Vector4<float>::Vector4(vec3&, vec2&, double)'
I have always found the constructor rules for C++ to be pretty complex. Let the compiler tell it like it is.