如何将球的中心的更新值传递到我的片段着色器?

时间:2012-09-19 19:40:10

标签: opengl

这是我的主要和顶点和片段着色器。我非常接近让这个工作。我的片段着色器需要根据update_balls函数中更新的中心计算f。我不知道该怎么做。

#include "Angel.h"
#include <assert.h>
#include <vector>

using namespace std;

typedef Angel::vec4 vec4_t;
typedef Angel::vec3 vec3_t;
typedef Angel::vec2 vec2_t;

// the data structure of a 2D ball
typedef struct {
    vec2_t center;
    float radius;
    float currentTime;
    vec2_t velocity;
    vec2_t vertices[4];
    vec4_t color;   
} ball_t;

// the boundary
typedef enum {
    LEFT, RIGHT, TOP, BOTTOM, NONE
} boundary_t;

//the number of balls
int theNumBalls = 0;

//the ball array using the STL vector
vector<ball_t> theBalls;

//the program object
GLuint theProgram = 0;

//the minimal and maximal radiuses
const float theMinRadius = 0.05;
const float theMaxRadius = 0.5;

//the window size
const int   theWinWidth = 512;
const int   theWinHeight = 512;

//the time interval for advecting balls
const float theTimeInterval = 0.005;

//create a new 2D ball where the center is (x, y) and the radius
ball_t new_ball(float x, float y, float radius)
{
    ball_t ball;

    ball.center = vec2_t(x, y);
    ball.radius = radius;

    ball.vertices[0] = vec2_t(ball.center.x - ball.radius, ball.center.y - ball.radius);
    ball.vertices[1] = vec2_t(ball.center.x + ball.radius, ball.center.y - ball.radius);
    ball.vertices[2] = vec2_t(ball.center.x + ball.radius, ball.center.y + ball.radius);
    ball.vertices[3] = vec2_t(ball.center.x - ball.radius, ball.center.y + ball.radius);

    //random color
    ball.color = vec4_t((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 1.0f);

    //random velocity
    ball.velocity = normalize(vec2(((float)rand()/RAND_MAX) - 0.5f, ((float)rand()/RAND_MAX) - 0.5f));

    return ball;
}

//return the boundary edge if collision
boundary_t collision_boundary(ball_t &ball)
{
    return NONE;
}

void renderBitmapString(float x, float y, void *font, string str) 
{
  glRasterPos2f(x,y);
  for (string::iterator c = (&str)->begin(); c != (&str)->end(); ++c) 
  {
    glutBitmapCharacter(font, *c);
  }
}

 // update the position or size of the balls
void update_balls()
{

    //change the size of a new ball if pressing the left button

    //or advect the ball according to the ball's velocity
    //string a ("UpdateBallsTest");
    //renderBitmapString(20, 20, GLUT_BITMAP_TIMES_ROMAN_24, a);


    for (int i = 0; i < theNumBalls; i++) {

    theBalls[i].center = vec2_t(theBalls[i].center.x + theBalls[i].velocity.x * theTimeInterval, theBalls[i].center.y + theBalls[i].velocity.y * theTimeInterval);

    //assign the uniform center
    GLuint nCenter = glGetUniformLocation(theProgram, "vCenter");
    glUniform2f(nCenter, theBalls[i].center.x, theBalls[i].center.y);
        theBalls[i].vertices[0] =  vec2_t(theBalls[i].vertices[0].x + (theBalls[i].velocity.x * theTimeInterval), theBalls[i].vertices[0].y + (theBalls[i].velocity.y * theTimeInterval));
        theBalls[i].vertices[1] =  vec2_t(theBalls[i].vertices[1].x + (theBalls[i].velocity.x * theTimeInterval), theBalls[i].vertices[1].y + (theBalls[i].velocity.y * theTimeInterval));
        theBalls[i].vertices[2] =  vec2_t(theBalls[i].vertices[2].x + (theBalls[i].velocity.x * theTimeInterval), theBalls[i].vertices[2].y + (theBalls[i].velocity.y * theTimeInterval));
        theBalls[i].vertices[3] =  vec2_t(theBalls[i].vertices[3].x + (theBalls[i].velocity.x * theTimeInterval), theBalls[i].vertices[3].y + (theBalls[i].velocity.y * theTimeInterval));


    }
     //change the ball's velocity according to the return value of collision_boundary 
}


// OpenGL initialization
void init()
{
    //create a inital ball
    ball_t ball = new_ball(0, 0, 0.05);
    theBalls.push_back(ball);
    theNumBalls = theBalls.size();

    // Load shaders and use the resulting shader program
    theProgram = InitShader("vshader02.glsl", "fshader02.glsl");
    glUseProgram(theProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor( 1.0, 1.0, 1.0, 0.0 ); 
}

void mydisplay( void )
{
    update_balls();

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (int i = 0; i < theNumBalls; i++) {

        //assign the uniform variabe color
        GLuint nColor = glGetUniformLocation(theProgram, "vColor");
        glUniform4f(nColor, theBalls[i].color.x, theBalls[i].color.y, theBalls[i].color.z, theBalls[i].color.w);

        //render the ball as a qaud
        GLuint nPosition = glGetAttribLocation(theProgram, "vPosition");

        glBegin(GL_QUADS);
        glVertexAttrib2fv(nPosition, theBalls[i].vertices[0]);
        glVertexAttrib2fv(nPosition, theBalls[i].vertices[1]);
        glVertexAttrib2fv(nPosition, theBalls[i].vertices[2]);
        glVertexAttrib2fv(nPosition, theBalls[i].vertices[3]);
        glEnd();
    }
    glutSwapBuffers();
    glFlush();
}

void mymouse(int button, int state, int x, int y)
{
    //create a new ball under the curret mouse position if pressing the left button
}

void myidle()
{
    glutPostRedisplay();
}

int
main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(theWinWidth, theWinHeight);

    glutCreateWindow( "Derek Meyer 73379861" );

    glewInit();

    init();

    glutDisplayFunc(mydisplay);
    glutMouseFunc(mymouse);
    glutIdleFunc(myidle);

    glutMainLoop();
    return 0;
}


/////////VSHADER

#version 150

in vec2 vPosition;
uniform vec2    vCenter;
out vec4 color;

void main() 
{
gl_Position = vec4(vCenter, 0.0, 1.0);
color = gl_Position;
} 


/////////// FSHADER

#version 150
uniform vec4    vColor;
uniform vec2    vCenter;

in vec4 color;

out vec4    FragColor;

void main() 
{ 
float f = sqrt(((color.x - vCenter.x) * (color.x - vCenter.x)) + ((color.y - vCenter.y)               * (color.y - vCenter.y)));     
if (f < 0.043)
    FragColor = vColor;
else if (f < 0.05)
    FragColor = vec4(0, 0, 0, 1);
else
    FragColor = vec4(0, 1, 0, 0);
} 

0 个答案:

没有答案