Hi forum,
I am trying to get the rippling effect of the plane . But i am not getting the progressing ripple effect with time. Here goes the attached code:
// Include standard headers
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#define GLFW_INCLUDE_GLU
#include <glfw3.h>
GLFWwindow* window;
// Include GLM
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include "Program.h"
#define GL_CHECK_ERRORS assert(glGetError() == GL_NO_ERROR);
int winWidth = 800;
int winHeight = 600;
GLuint vaoID = 0;
GLuint vboVerticesID= 0;
GLuint vboIndicesID = 0;
const int NUM_X = 40; //total quads on X axis
const int NUM_Z = 40; //total quads on Z axis
const float SIZE_X = 4; //size of plane in world space
const float SIZE_Z = 4;
const float HALF_SIZE_X = SIZE_X/2.0f;
const float HALF_SIZE_Z = SIZE_Z/2.0f;
//ripple displacement speed
const float SPEED = 2;
//ripple mesh vertices and indices
glm::vec3 vertices[(NUM_X+1)*(NUM_Z+1)];
const int TOTAL_INDICES = NUM_X*NUM_Z*2*3;
GLushort indices[TOTAL_INDICES];
//initialize the projection and model-view matrix
//as the identity matrix
glm::mat4 projMatrix = glm::mat4(1.0f);
glm::mat4 modelviewMatrix = glm::mat4(1.0f);
//camera transformation variables
int cursorX=0, cursorY=0;
float rX=25, rY=-40, dist = -7;
GLboolean locked = GL_FALSE;
//set the window background clearing color
static const GLfloat backgroundcolor[] = {0.0f,0.0f,0.0f,1.0f};
static const GLfloat one = 1.0f;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_button_callback(GLFWwindow *window,int button,int action,int mods);
void cursor_position_callback(GLFWwindow *window,double x, double y);
void render(float time);
void shutdown();
tdogl::Program *rippleProgram = NULL;
void loadGeometry();
void loadShaders();
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
std::cerr << "Failed to initialize GLFW." << std::endl;
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_SAMPLES, 4);
//we want the opengl 4
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//we do not want the old opengl
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow( winWidth, winHeight, "OpenGL Ripple Deformer", NULL, NULL);
if( window == NULL )
{
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 4.3 compatible. Try the 2.1 version of the tutorials.
" );
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetMouseButtonCallback(window,mouse_button_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
//make the current window context current
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwGetFramebufferSize(window,&winWidth,&winHeight);
framebuffer_size_callback(window,winWidth,winHeight);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW
");
exit(EXIT_FAILURE);
}
while(glGetError() != GL_NO_ERROR) {}
//print out information aout the graphics driver
std::cout << std::endl;
std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
std::cout << "GLEW Verion: " << glewGetString(GLEW_VERSION) << std::endl;
std::cout << "OpenGL Vendor: " << glGetString(GL_VENDOR) << std::endl;
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;
GL_CHECK_ERRORS
//set the polygon mode
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
//load the shaders
loadShaders();
loadGeometry();
do{
float time = (float)glfwGetTime();
render(time);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
glfwDestroyWindow(window);
// Close OpenGL window and terminate GLFW
glfwTerminate();
shutdown();
exit(EXIT_SUCCESS);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
winWidth = width;
winHeight = height;
glViewport(0,0,(GLsizei)width,(GLsizei)height);
//initialize the projection matrix
projMatrix = glm::perspective(45.0f,(GLfloat)width/height,1.0f,1000.f);
}
void render(float time)
{
time = (time / 1000.0f ) * SPEED;
glClearBufferfv(GL_COLOR,0,backgroundcolor);
glClearBufferfv(GL_DEPTH,0,&one);
glm::mat4 T = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f,dist));
glm::mat4 Rx = glm::rotate(T,rX,glm::vec3(1.0f,0.0f,0.0f));
modelviewMatrix = glm::rotate(Rx,rY,glm::vec3(0.0f,1.0f,0.0f));
glm::mat4 MVP = projMatrix * modelviewMatrix;
//bind the program
rippleProgram->use();
//pass the shader uniform
rippleProgram->setUniform("MVP",MVP);
rippleProgram->setUniform("time",time);
glDrawElements(GL_TRIANGLES,TOTAL_INDICES,GL_UNSIGNED_SHORT,0);
rippleProgram->stopUsing();
}
void loadGeometry()
{
//setup plane geometry
//setup plane vertices
int count = 0;
int i=0, j=0;
for( j=0;j<=NUM_Z;j++)
{
for( i=0;i<=NUM_X;i++)
{
vertices[count++] = glm::vec3( ((float(i)/(NUM_X-1)) *2-1)* HALF_SIZE_X,
0,
((float(j)/(NUM_Z-1))*2-1)*HALF_SIZE_Z);
}
}
//fill plane indices array
GLushort* id=&indices[0];
for (i = 0; i < NUM_Z; i++)
{
for (j = 0; j < NUM_X; j++)
{
int i0 = i * (NUM_X+1) + j;
int i1 = i0 + 1;
int i2 = i0 + (NUM_X+1);
int i3 = i2 + 1;
if ((j+i)%2)
{
*id++ = i0; *id++ = i2; *id++ = i1;
*id++ = i1; *id++ = i2; *id++ = i3;
}
else
{
*id++ = i0; *id++ = i2; *id++ = i3;
*id++ = i0; *id++ = i3; *id++ = i1;
}
}
}
GL_CHECK_ERRORS
//setup plane vao and vbo stuff
glGenVertexArrays(1, &vaoID);
glGenBuffers(1, &vboVerticesID);
glGenBuffers(1, &vboIndicesID);
glBindVertexArray(vaoID);
glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID);
//pass plane vertices to array buffer object
glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
GL_CHECK_ERRORS
//enable vertex attrib array for position
glEnableVertexAttribArray(rippleProgram->attrib("vVertex"));
glVertexAttribPointer(rippleProgram->attrib("vVertex"), 3, GL_FLOAT, GL_FALSE,0,0);
GL_CHECK_ERRORS
//pass the plane indices to element array buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
GL_CHECK_ERRORS
cout<<"Initialization successfull"<<endl;
}
void loadShaders()
{
std::vector<tdogl::Shader> rippleShaders;
rippleShaders.push_back(tdogl::Shader::shaderFromFile("shaders/ripple-vertex-shader.txt",GL_VERTEX_SHADER));
rippleShaders.push_back(tdogl::Shader::shaderFromFile("shaders/ripple-fragment-shader.txt",GL_FRAGMENT_SHADER));
//initialize the GLSL program object
rippleProgram = new tdogl::Program(rippleShaders);
}
void shutdown()
{
if(rippleProgram)
{
delete rippleProgram;
rippleProgram = 0;
}
//destroy vao and vbo
glDeleteBuffers(1,&vboVerticesID);
glDeleteBuffers(1,&vboIndicesID);
glDeleteVertexArrays(1,&vaoID);
std::cout << "Shutdown is successful" << std::endl;
}
And the corresponding vertex shader is as follows:
#version 430
layout (location = 0) in vec3 vVertex;
//uniforms
uniform mat4 MVP; //combined modelview projection matrix
uniform float time; //elasped time
//shader constants
const float amplitude = 0.125;
const float frequency = 4;
const float PI = 3.14159;
void main()
{
//get the Euclidean distance of the current vertex from the center of the mesh
float distance = length(vVertex);
//create a sin function using the distance, multiply frequency and add the elapsed time
float y = amplitude*sin(-PI*distance*frequency+time);
//multiply the MVP matrix with the new position to get the clipspace position
gl_Position = MVP*vec4(vVertex.x, y, vVertex.z,1);
}
Any hint ?
Thanks