Reputation: 715
I'm working on what should be a simple OpenGl 4 project. All I am looking to do is change the alpha value around the mouse pointer and blend. After some work, I managed to get a circle to change values, but it's static (doesn't move with the mouse) and is centered on (0,512), very much not the location of my mouse. I send the mouse values through my passiveMotionFunc:
void
motion ( int x, int y)
{
MousePos.x = x;
MousePos.y = y;
printf("x=%i\ny=%i\n\n", x, y);
glUniform2fv(glGetUniformLocation(program, "MousePos"), 2, MousePos);
glutPostRedisplay();
}
Where MousePos is just a simple float container. I have the print statement just so I can see the values of my mouse location.
my frag shader is simply:
in vec4 color;
in vec4 vPosition;
in vec2 MousePos;
out vec4 fColor;
void
main()
{
//float x = gl_FragCoord.X;
//float y = gl_FragCoord.Y;
float distance = sqrt(pow(MousePos.x-gl_FragCoord.x, 2) + pow(MousePos.y-gl_FragCoord.y, 2));
if(distance > 30)
fColor = color;
else{
float a = .1;
fColor = color;
fColor.a = a;
}
}
I am absolutely stuck on this. I am assuming that the frag shader isn't getting updated mouse coordinates because if the FragCoord was messed up it wouldn't be producing a circle.
EDIT: I set up my blending in an init() function that precedes my glutDisplay and glutPassiveFunc in main().
void
init()
{
wall();
redwall();
// Create a vertex array object
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(quad_colors), NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(quad_colors), quad_colors );
// Load shaders and use the resulting shader program
program = InitShader( "p6v.glsl", "p6f.glsl" );
glUseProgram( program );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(sizeof(points)) );
//glEnable(GL_DEPTH_TEST);
glEnable( GL_BLEND );
glEnable( GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glClearColor( 0.0, 0.5, 1.0, 1.0 );
}
EDIT2: Here is my vec2 definition:
struct vec2 {
GLfloat x;
GLfloat y;
//
// --- Constructors and Destructors ---
//
vec2( GLfloat s = GLfloat(0.0) ) :
x(s), y(s) {}
vec2( GLfloat x, GLfloat y ) :
x(x), y(y) {}
vec2( const vec2& v )
{ x = v.x; y = v.y; }
//
// --- Indexing Operator ---
//
GLfloat& operator [] ( int i ) { return *(&x + i); }
const GLfloat operator [] ( int i ) const { return *(&x + i); }
//
// --- (non-modifying) Arithematic Operators ---
//
vec2 operator - () const // unary minus operator
{ return vec2( -x, -y ); }
vec2 operator + ( const vec2& v ) const
{ return vec2( x + v.x, y + v.y ); }
vec2 operator - ( const vec2& v ) const
{ return vec2( x - v.x, y - v.y ); }
vec2 operator * ( const GLfloat s ) const
{ return vec2( s*x, s*y ); }
vec2 operator * ( const vec2& v ) const
{ return vec2( x*v.x, y*v.y ); }
friend vec2 operator * ( const GLfloat s, const vec2& v )
{ return v * s; }
vec2 operator / ( const GLfloat s ) const {
#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
return vec2();
}
#endif // DEBUG
GLfloat r = GLfloat(1.0) / s;
return *this * r;
}
//
// --- (modifying) Arithematic Operators ---
//
vec2& operator += ( const vec2& v )
{ x += v.x; y += v.y; return *this; }
vec2& operator -= ( const vec2& v )
{ x -= v.x; y -= v.y; return *this; }
vec2& operator *= ( const GLfloat s )
{ x *= s; y *= s; return *this; }
vec2& operator *= ( const vec2& v )
{ x *= v.x; y *= v.y; return *this; }
vec2& operator /= ( const GLfloat s ) {
#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
}
#endif // DEBUG
GLfloat r = GLfloat(1.0) / s;
*this *= r;
return *this;
}
//
// --- Insertion and Extraction Operators ---
//
friend std::ostream& operator << ( std::ostream& os, const vec2& v ) {
return os << "( " << v.x << ", " << v.y << " )";
}
friend std::istream& operator >> ( std::istream& is, vec2& v )
{ return is >> v.x >> v.y ; }
//
// --- Conversion Operators ---
//
operator const GLfloat* () const
{ return static_cast<const GLfloat*>( &x ); }
operator GLfloat* ()
{ return static_cast<GLfloat*>( &x ); }
};
Upvotes: 0
Views: 2289
Reputation: 830
You need to declare MousePos as a uniform
in order to pass it in as one. Your fragment shader has it declared as an "in".
Also you are using the vector uniform upload glUniform2fv
to load from your vec2 class instance MousePos. You should load this in the 2-arg form glUniform2f
. The glUniform2fv
form is looking for an argument which is a pointer to a block of 2 float values as its last argument. You are passing it MousePos
there, which is an actual class instance, and you are counting on your casting operators to do the job.
Upvotes: 1