这是我的主要、顶点和片段着色器。我非常接近让这个工作。我的片段着色器需要根据我的 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);
}