使用mix()
:
layout(location = 0) in vec2 vertexPos;
uniform mat4 P;
uniform mat4 MV;
uniform float time;
void main()
{
vec2 dest(0.0, 0.0);
vec2 curPos = mix(vertexPos, dest, time);
gl_Position = P * MV * vec4(curPos, 0.0, 1.0);
}
がホストタイマーに基づいてホスト・コードに1.0
に0.0
からtime
を変更します。
EDIT:すべて一緒:
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <cstdarg>
#include <vector>
using namespace std;
struct Program
{
static GLuint Load(const char* shader, ...)
{
GLuint prog = glCreateProgram();
va_list args;
va_start(args, shader);
while(shader)
{
const GLenum type = va_arg(args, GLenum);
AttachShader(prog, type, shader);
shader = va_arg(args, const char*);
}
va_end(args);
glLinkProgram(prog);
CheckStatus(prog);
return prog;
}
private:
static void CheckStatus(GLuint obj)
{
GLint status = GL_FALSE;
if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status);
if(status == GL_TRUE) return;
GLchar log[ 1 << 15 ] = { 0 };
if(glIsShader(obj)) glGetShaderInfoLog(obj, sizeof(log), NULL, log);
if(glIsProgram(obj)) glGetProgramInfoLog(obj, sizeof(log), NULL, log);
std::cerr << log << std::endl;
exit(EXIT_FAILURE);
}
static void AttachShader(GLuint program, GLenum type, const char* src)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
CheckStatus(shader);
glAttachShader(program, shader);
glDeleteShader(shader);
}
};
#define GLSL(version, shader) "#version " #version "\n" #shader
const char* vert = GLSL
(
330 core,
layout(location = 0) in vec2 vertexPos;
uniform float time;
void main()
{
vec2 dest = vec2(0.0, 0.0);
vec2 curPos = mix(vertexPos, dest, time);
gl_Position = vec4(curPos, 0.0, 1.0);
}
);
const char* frag = GLSL
(
330 core,
out vec4 color;
void main()
{
color = vec4(1.0, 1.0, 1.0, 1.0);
}
);
float rnd(const float lo, const float hi)
{
return lo + (hi - lo) * (rand()/(float)RAND_MAX);
}
GLuint prog = 0;
GLint timeLoc = -1;
void init()
{
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
std::vector<float> verts;
for(size_t i = 0; i < 100; ++i)
{
verts.push_back(rnd(-1, 1));
verts.push_back(rnd(-1, 1));
}
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * verts.size(), &verts[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
prog = Program::Load
(
vert, GL_VERTEX_SHADER,
frag, GL_FRAGMENT_SHADER,
NULL
);
glUseProgram(prog);
timeLoc = glGetUniformLocation(prog, "time");
}
float u = 0.0f;
void timer(int value)
{
const int duration = 3000;
static int startTime = glutGet(GLUT_ELAPSED_TIME);
const int curTime = glutGet(GLUT_ELAPSED_TIME);
if(curTime > startTime + duration)
{
startTime = curTime;
}
u = (curTime - startTime)/(float)duration;
glutTimerFunc(16, timer, 0);
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(timeLoc, u);
glDrawArrays(GL_POINTS, 0, 100);
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("GLUT");
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}