I'm looking at some newer GLSL code that doesn't compile to my current version of OpenGL and I'm wondering what the short form of the following means:
vec4 base;
if (base < 0.5) {
result = (2.0 * base * blend);
}
Is this equivalent to:
if (base.r < 0.5 && base.g < 0.5 && base.b < 0.5 && base.a < 0.5) {
result.r = 2.0 * base.r * blend.r;
result.g = 2.0 * base.g * blend.g;
result.b = 2.0 * base.b * blend.b;
result.a = 2.0 * base.a * blend.a;
}
Edit:
Error:
Fragment shader failed to compile with the following errors:
Wrong operand types no operation '<' exists that takes a left-hand operand of type 'highp 3-component vector of float' and a right operand of type 'const float' (or there is no acceptable conversion)
I've also tried:
(base.rgb < vec3(0.5))
... Wrong operand types no operation '<' exists that takes a left-hand operand of type 'highp 3-component vector of float' and a right operand of type 'const highp 3-component vector of float'
I'm assuming this is because I'm using GLSL 1.2.
ATI Radeon 3450
From the spec, section 5.9 (top of page 38):
The relational operators greater than
(>), less than (<), greater than or
equal (>=), and less than or equal
(<=) operate only on scalar integer
and scalar floating-point expressions.
The result is scalar Boolean. Either
the operands’ types must match, or the
conversions from Section 4.1.10
“Implicit Conversions” will be applied
to the integer operand, after which
the types must match. To do
component-wise relational comparisons
on vectors, use the built-in functions
lessThan, lessThanEqual, greaterThan,
and greaterThanEqual.
Looks like you want the lessThan function. Check section 8.6 (page 62).
lessThan() - http://www.opengl.org/ (see also: all())
Related
The following error is thrown at the two assignments of targets in the if statement.
error: expression must have integral or enum type
All the variables in the operation are or return floating values as they are declared as such. Yet it doesn't like the conversion to integers. Why is this? Are there differences between different kinds of floats or integers?
__global__
void generateTargets(int* targets, int targetAmount, float radius, float angleStep){
float i = blockIdx.x;
if(i < targetAmount){ // Ensure it stays in range
// Access the 1d array representation of the 2d array [MAX_TARGETS][2]
targets[i + MAX_TARGETS*0] = __float2int_rd(radius*__cosf(i*angleStep)); // X value
targets[i + MAX_TARGETS*1] = __float2int_rd(radius*__sinf(i*angleStep)); // Y value
}
}
In targets[i + MAX_TARGETS*0] and targets[i + MAX_TARGETS*1] you are using i which is a float. That makes the entire expression to calculate the array index a float. You can't do this though as array indexes must be an integer type (there is no element 4.5).
If you want to keep i a float you will need to cast/convert it to an `integer type or cast/convert the result of the expression to an integer type.
I have a line of code
double i = 1 + (long)1.5* 5.0f
My question is what is the conversion order and the result? Been searching for examples like this, but to no avail. Any good guides out there that may help me understand it?
My question is what is the conversion order and the result?
The cast is applied to 1.5, giving a long with value 1.
That's converted to float for multiplication with 5.0f, giving a float with value 5.0f.
1 is converted to float for addition with that value, giving a float with value 6.0f.
Finally, that's promoted to double (retaining the value 6.0) to assign to i.
This assumes a non-crazy floating point format that can represent small integers exactly; otherwise, there may be rounding errors.
If you wanted to cast the result of the multiplication, then use parentheses to control the operator precedence:
double i = 1 + (long)(1.5* 5.0f); // = 8.0
or use a C++-style cast, which forces the use of parentheses:
double i = 1 + static_cast<long>(1.5* 5.0f)
Any good guides out there that may help me understand it?
Here's one: http://en.cppreference.com/w/cpp/language/operator_precedence. Note that the type cast has a higher precedence than multiplication, which is in turn higher than addition (3 vs. 5 vs. 6).
As you can see from this table, the cast operator has higher precedence than multiplication, but follow the advice to use parentheses.
This precedence table should tell you everything you need to know.
Casting: 1.5 is cast to a long
Multiplication: 1.5 * 5.0f, which casts this product as a float
Addition: 1 + ( ((long) 1.5) * 5.0f)
Assignment: i = 1 + ((long) 1.5 * 5.0f)
If you're not sure what the precedence of the casting operator is then rewrite the expression (in your head)
(long)1.5 * 5.0
to
5.0 * (long)1.5
Here its pretty obvious what has precedence and its the same with the first version
Consider the following code:
void f(float x)
{
x * (true ? 1.f : 0.0);
}
The type of declval(bool) ? declval(float) : declval(double) is double according to the C++ standard [expr.cond].
Does this mean that the above code has to be equivalent to:
void f(float x)
{
double(x) * 1.0;
}
Or is there a statement that allows an optimization in case the first operand of ?: is a compile time constant expression ?
Yes, it does mean that the above codes are equivalent.
Using RTTI we can check that at least both clang and g++ are standard conformant and give d (e.g. double) as an output to this program:
#include <iostream>
#include <typeinfo>
int main() {
float x = 3.;
auto val = x * (true ? 1.f : 0.0);
std::cout << typeid(val).name() << std::endl;
}
And the alternative way using C++11 type traits
#include <iostream>
#include <typeinfo>
int main() {
float x = 3.;
auto val = x * (true ? 1.f : 0.0);
std::cout << std::boolalpha <<
std::is_same<decltype(val), double>::value << std::endl;
}
Outputs true.
A C++ compiler can optimize as it sees fit, provided that it does not alter the "observable behaviour" of a conforming program (§1.9p1, the so-called "as if" rule).
For example, if on a given platform it is known that multiplying by 1.0 is an identity transformation without the potential to trap, then the multiplication does not actually need to be performed. (This may or may not be true for a given architecture, since it is possible that multiplying a NaN value by 1.0 could trap. However, the compiler could also replace the multiplication by any other operation which would produce the same trap under the same circumstances.)
In the absence of traps and assuming that multiplication by 1.0 is an identity transform, the entire body of your function f can be eliminated, because the standard requires that the set of float values is a subset of the set of double values (possibly the same set). Consequently, the float->double->float round trip must return to the original value or trap. (§3.9.1p8: "The set of values of the type float is a subset of the set of values of the type double". §4.8p1: "A prvalue of floating point type can be converted to a prvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation.")
So, yes, optimizations may be possible. But that does not affect the type of the ?: expression, in the case that the type is observable (for example, if the expression were to be used for template deduction or as the operand of decltype).
I am using following shader for unsigned integer textures to read a data:
Fragment shader:
Code :
#version 150
out uvec4 fragColor;
uniform uint factor;
void main()
{
uint temp=factor;
temp=temp/2;
fragColor = uvec4(temp,temp,temp,temp);
}
But i am getting error on driver A:
"Compile failed.
ERROR: 0:7: '/' : Wrong operand types. No operation '/' exists that takes a left-hand operand of type 'uint' and a right operand of type 'const int' (and there is no acceptable conversion)
ERROR: 1 compilation errors. No code generated."
on driver B it runs perfectly. Is driver A is buggy or my shader is wrong? if wrong, how can i achieve the same result?
Try this:
temp = temp / uint(2);
GLSL does not allow implicit conversions between signed and unsigned ints, so both operands of a binary operand must be the same. Use:
temp = temp / 2u;
to use an unsigned int constant.
JavaScript:
var lon2 = (lon1.toRad()+L+3*Math.PI)%(2*Math.PI) - Math.PI;
I have converted to c++:
double lon2 = (Deg2Rad(lon1)+L+3*PI)%(2*PI) - PI;
Note: Deg2Rad func returns double, PI is a double also, L and lon1 also double. Then I got the following errors for the same line:
error C2296: '%' : illegal, left operand has type 'double'
error C2297: '%' : illegal, right operand has type 'double'
Whats wrong with this % modulo?
the modulo operator is not defined for floats and doubles (only integer types), use fmod instead (or consider changing how you perform your calculation).
C++ will not perform a modulo operation on a double - I suggest using fmod() in <math.h>
If you wanted to be very fancy about it, you could overload the modulo (%) operator to handle your desired datatypes.
% is defined for integers only. Use the fmod() function in <cmath> to calculate the modulus of a floating point number (float or double).