Sign in to follow this  
payal

how to check a sin function is working properly

Recommended Posts

Hi All, I have some set of drivers for OPENGL ES which is untested so have an doubt that some functions are not working properly. I just want to check that sin function is working properly. Is there any way to check from my main.c that vertex shader executes a sin properly? I don't have a much idea of a OPENGL. Reply me if you have a suggestion. Thanks

Share this post


Link to post
Share on other sites
sin(pi) = 0
sin(0.5 * pi) = 1
sin(1.5 * pi) = -1

Take whatever value of pi you like (I'll do the clichéd guy thing: 3.14159265358979323846264).

It's probably working fine though. Just remember that the functions will almost certainly work in radians rather than degrees (Pi radians = 180 degrees).

Share this post


Link to post
Share on other sites

Hi Thanks for reply.

Actually i want to give a message to main.c that it is getting failed or pass to calculate the sin value. I can check manually to in a shaders but how to give message to main.c file?

Share this post


Link to post
Share on other sites
To copy data from a texture in GPU RAM to a texture in CPU RAM involves glReadPixels. This would involve rendering to a texture.

You could then approximate the sine value yourself using Taylor expansion, and compare that value to the one given by the vertex shader.

The source for Taylor expansion below uses 5 steps by default, which gives pretty accurate results for input values up to about 1.0. Higher step counts give more accurate results for higher input values. The input value however must be less than 2*pi. This isn't really a problem, since the sine function is periodic, and thus sin(2*pi) == sin(0) in both output value and slope.

More information on Taylor expansion: http://en.wikipedia.org/wiki/Taylor_series



#include <iostream>
using std::cout;
using std::endl;

#include <cmath>
using std::sin;


double pow_int_exp(const double &base, const long unsigned int &exp);
double factorial(const double &number);

// Increase step_number for increased precision.
// I figure I would include cos and asin too.
double cos_taylor(const double &number, long unsigned int step_number = 5);
double sin_taylor(const double &number, long unsigned int step_number = 5);
double asin_taylor(const double &number, long unsigned int step_number = 5);


int main(void)
{
double input = 0.0;

for(; input <= 1.0; input += 0.1)
{
cout << "sin_taylor(" << input << "): " << sin_taylor(input) << endl;
cout << "sin(" << input << "): " << sin(input) << endl;
}

return 0;
}

// Integer exponent when raising to a power.
double pow_int_exp(const double &base, const long unsigned int &exp)
{
if(exp == 0)
return 1.0;
else
return base*pow_int_exp(base, exp - 1);
}
// factorial(x) = 1 * 2 * ... * (x - 1) * x
double factorial(const double &number)
{
if(number <= 1.0)
return 1.0;
else
return number*factorial(number - 1);
}
// cos(x) = 1.0 - x^2/2! + x^4/4! - x^6/6! + ...
double cos_taylor(const double &number, long unsigned int step_number)
{
// make sure at least one step is taken
if(0 == step_number)
step_number = 1;

// start at the last step
const long unsigned int taylor_base = step_number*2 - 2;

// where step == 1
if(taylor_base == 0)
return 1.0;

double a = cos_taylor(number, step_number - 1);
double b = pow_int_exp(number, taylor_base)/factorial(taylor_base);

// where step > 1
if(step_number%2)
return a + b;
else
return a - b;
}

// sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
double sin_taylor(const double &number, long unsigned int step_number)
{
// make sure at least one step is taken
if(0 == step_number)
step_number = 1;

// start at the last step
const long unsigned int taylor_base = step_number*2 - 2;

// where step == 1
if(taylor_base == 0)
return number;

double a = sin_taylor(number, step_number - 1);
double b = pow_int_exp(number, taylor_base + 1)/factorial(taylor_base + 1);

// where step > 1
if(step_number%2)
return a + b;
else
return a - b;
}

// asin(x) = x + (1/2)(x^3/3) + (1/2)(3/4)(x^5/5) + (1/2)(3/4)(5/6)(x^7/7) + ...
double asin_taylor(const double &number, long unsigned int step_number)
{
// make sure at least one step is taken
double value = number;
// where step == 1
if(0 == step_number)
return value;
step_number--;
// where step > 1
long unsigned int exponent = 3;
double coefficient_val = 1;
double coefficient = 0.0;
// for each successive step
for(size_t i = 0; i < step_number; i++)
{
coefficient += coefficient_val/(coefficient_val + 1);
value += coefficient*(pow_int_exp(number, exponent)/exponent);
coefficient_val += 2;
exponent += 2;
}
return value;
}







Share this post


Link to post
Share on other sites
Quote:
Original post by taby
You could then approximate the sine value yourself using Taylor expansion


Or, uh, use the sin() in <math.h> which very probably works fine.

Quote:

Original post by payal
I can check manually to in a shaders but how to give message to main.c file?


Ah, I see. Sorry, I don't know how shaders work so I have no idea how to return a message -- if it's even possible -- to the calling/using (don't know the terminology) code. However, what I would say is that -- as far as I know -- the shaders are compiled to object code and then executed on the GPU which would suggest that the trig. functions probably work so long as the FSIN or equivalent functions provided by the GPU work fine.

Share this post


Link to post
Share on other sites
Quote:
Original post by TheUnbeliever
Ah, I see. Sorry, I don't know how shaders work so I have no idea how to return a message -- if it's even possible...


Or, uh, use the glReadPixels() in OpenGL which very definitely works fine. :)

Share this post


Link to post
Share on other sites

Thanks, Guys for suggestions.

you meant like following to do,

// Fragment shader
uniform vec4 xvalue;
void main()
{
vec4 color = sin (xvalue);
gl_color = color;
}


//in main.c

enable buffers

glReadPixels(x,y,1,1,GL_RED,GL_FLOAT,pixel)
glReadPixels(x,y,1,1,GL_GREEN,GL_FLOAT,pixel)
glReadPixels(x,y,1,1,GL_BLUE,GL_FLOAT,pixel)
glReadPixels(x,y,1,1,GL_ALPHA,GL_FLOAT,pixel)


but what the value to use instead of x,y ? i am confused? Sorry i am beginner for OpenGL Shading language. Please help me about this.

Share this post


Link to post
Share on other sites
Be profficient in Mathematics. That is all! Or, google for unit circle. It'll give you what you need.

Hope it helps. Good Luck,

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this