void InitGL() { glClearColor(1,1,1,1); glGenQueries(1, &query); glGenQueries(1, &t_query); texture_size_x = numX+1; texture_size_y = numY+1; CHECK_GL_ERRORS startTime = (float)glutGet(GLUT_ELAPSED_TIME); // get ticks per second QueryPerformanceFrequency(&frequency); // start timer QueryPerformanceCounter(&t1); size_t i=0, j=0, count=0; int l1=0, l2=0; int v = numY+1; int u = numX+1; printf("Total triangles: %3d\n",numX*numY*2); indices.resize( numX*numY*2*3); X.resize(total_points); X_last.resize(total_points); F.resize(total_points); //fill in positions for(int j=0;j<=numY;j++) { for(int i=0;i<=numX;i++) { X[count] = glm::vec4( ((float(i)/(u-1)) *2-1)* hsize, sizeX+1, ((float(j)/(v-1) )* sizeY),1); X_last[count] = X[count]; count++; } } //fill in indices GLushort* id=&indices[0]; for (int i = 0; i < numY; i++) { for (int j = 0; j < numX; j++) { int i0 = i * (numX+1) + j; int i1 = i0 + 1; int i2 = i0 + (numX+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; } } } glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glEnable(GL_CULL_FACE); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glCullFace(GL_BACK); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); //Disable vsync wglSwapIntervalEXT(0); // Setup springs // Horizontal for (l1 = 0; l1 < v; l1++) // v for (l2 = 0; l2 < (u - 1); l2++) { AddSpring((l1 * u) + l2,(l1 * u) + l2 + 1,KsStruct,KdStruct); } // Vertical for (l1 = 0; l1 < (u); l1++) for (l2 = 0; l2 < (v - 1); l2++) { AddSpring((l2 * u) + l1,((l2 + 1) * u) + l1,KsStruct,KdStruct); } // Shearing Springs for (l1 = 0; l1 < (v - 1); l1++) for (l2 = 0; l2 < (u - 1); l2++) { AddSpring((l1 * u) + l2,((l1 + 1) * u) + l2 + 1,KsShear,KdShear); AddSpring(((l1 + 1) * u) + l2,(l1 * u) + l2 + 1,KsShear,KdShear); } // Bend Springs for (l1 = 0; l1 < (v); l1++) { for (l2 = 0; l2 < (u - 2); l2++) { AddSpring((l1 * u) + l2,(l1 * u) + l2 + 2,KsBend,KdBend); } AddSpring((l1 * u) + (u - 3),(l1 * u) + (u - 1),KsBend,KdBend); } for (l1 = 0; l1 < (u); l1++) { for (l2 = 0; l2 < (v - 2); l2++) { AddSpring((l2 * u) + l1,((l2 + 2) * u) + l1,KsBend,KdBend); } AddSpring(((v - 3) * u) + l1,((v - 1) * u) + l1,KsBend,KdBend); } massSpringShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Spring.vp"); particleShader.LoadFromFile(GL_VERTEX_SHADER,"shaders/Basic.vp"); particleShader.LoadFromFile(GL_FRAGMENT_SHADER,"shaders/Basic.fp"); renderShader.LoadFromFile(GL_VERTEX_SHADER,"shaders/Passthrough.vp"); renderShader.LoadFromFile(GL_FRAGMENT_SHADER,"shaders/Passthrough.fp"); massSpringShader.CreateAndLinkProgram(); massSpringShader.Use(); massSpringShader.AddAttribute("position_mass"); massSpringShader.AddAttribute("prev_position"); massSpringShader.AddUniform("tex_position_mass"); massSpringShader.AddUniform("tex_pre_position_mass"); massSpringShader.AddUniform("MVP"); massSpringShader.AddUniform("dt"); massSpringShader.AddUniform("gravity"); massSpringShader.AddUniform("ksStr"); massSpringShader.AddUniform("ksShr"); massSpringShader.AddUniform("ksBnd"); massSpringShader.AddUniform("kdStr"); massSpringShader.AddUniform("kdShr"); massSpringShader.AddUniform("kdBnd"); massSpringShader.AddUniform("DEFAULT_DAMPING"); massSpringShader.AddUniform("texsize_x"); massSpringShader.AddUniform("texsize_y"); massSpringShader.AddUniform("step"); massSpringShader.AddUniform("inv_cloth_size"); massSpringShader.AddUniform("ellipsoid"); glUniform1i(massSpringShader("tex_position_mass"), 0); glUniform1i(massSpringShader("tex_pre_position_mass"), 1); massSpringShader.UnUse(); CHECK_GL_ERRORS particleShader.CreateAndLinkProgram(); particleShader.Use(); particleShader.AddAttribute("position_mass"); particleShader.AddUniform("pointSize"); particleShader.AddUniform("MV"); particleShader.AddUniform("MVP"); particleShader.AddUniform("vColor"); particleShader.AddUniform("selected_index"); glUniform1f(particleShader("pointSize"), pointSize); glUniform4fv(particleShader("vColor"),1, vRed); particleShader.UnUse(); renderShader.CreateAndLinkProgram(); renderShader.Use(); renderShader.AddAttribute("position_mass"); renderShader.AddUniform("MVP"); renderShader.AddUniform("vColor"); glUniform4fv(renderShader("vColor"),1, vGray); renderShader.UnUse(); CHECK_GL_ERRORS //create vbo createVBO(); //setup transform feedback attributes glGenTransformFeedbacks(1, &tfID); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID); const char* varying_names[]={"out_position_mass", "out_prev_position"}; glTransformFeedbackVaryings(massSpringShader.GetProgram(), 2, varying_names, GL_SEPARATE_ATTRIBS); glLinkProgram(massSpringShader.GetProgram()); }
//initialize OpenGL void InitGL() { //set the background colour to white glClearColor(1,1,1,1); //generate hardware query objects glGenQueries(1, &query); glGenQueries(1, &t_query); //setup texture size for shaders texture_size_x = numX+1; texture_size_y = numY+1; CHECK_GL_ERRORS //get initial time startTime = (float)glutGet(GLUT_ELAPSED_TIME); // get ticks per second QueryPerformanceFrequency(&frequency); // start timer QueryPerformanceCounter(&t1); //local variables size_t i=0, j=0, count=0; int l1=0, l2=0; int v = numY+1; int u = numX+1; printf("Total triangles: %3d\n",numX*numY*2); //resize the cloth indices, position, previous position and force vectors indices.resize( numX*numY*2*3); X.resize(total_points); X_last.resize(total_points); F.resize(total_points); //fill in positions for(int j=0;j<=numY;j++) { for(int i=0;i<=numX;i++) { X[count] = glm::vec4( ((float(i)/(u-1)) *2-1)* hsize, sizeX+1, ((float(j)/(v-1) )* sizeY),1); X_last[count] = X[count]; count++; } } //fill in indices GLushort* id=&indices[0]; for (int i = 0; i < numY; i++) { for (int j = 0; j < numX; j++) { int i0 = i * (numX+1) + j; int i1 = i0 + 1; int i2 = i0 + (numX+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; } } } //set the polygon rendering to render them as lines glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //enable back face culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); //set smooth line rendering glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //enable state to use the vertex shader to reset the particle size //by writing to gl_PointSize value glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); // Setup springs // Horizontal for (l1 = 0; l1 < v; l1++) // v for (l2 = 0; l2 < (u - 1); l2++) { AddSpring((l1 * u) + l2,(l1 * u) + l2 + 1,KsStruct,KdStruct); } // Vertical for (l1 = 0; l1 < (u); l1++) for (l2 = 0; l2 < (v - 1); l2++) { AddSpring((l2 * u) + l1,((l2 + 1) * u) + l1,KsStruct,KdStruct); } // Shearing Springs for (l1 = 0; l1 < (v - 1); l1++) for (l2 = 0; l2 < (u - 1); l2++) { AddSpring((l1 * u) + l2,((l1 + 1) * u) + l2 + 1,KsShear,KdShear); AddSpring(((l1 + 1) * u) + l2,(l1 * u) + l2 + 1,KsShear,KdShear); } // Bend Springs for (l1 = 0; l1 < (v); l1++) { for (l2 = 0; l2 < (u - 2); l2++) { AddSpring((l1 * u) + l2,(l1 * u) + l2 + 2,KsBend,KdBend); } AddSpring((l1 * u) + (u - 3),(l1 * u) + (u - 1),KsBend,KdBend); } for (l1 = 0; l1 < (u); l1++) { for (l2 = 0; l2 < (v - 2); l2++) { AddSpring((l2 * u) + l1,((l2 + 2) * u) + l1,KsBend,KdBend); } AddSpring(((v - 3) * u) + l1,((v - 1) * u) + l1,KsBend,KdBend); } //setup shader loading massSpringShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Spring.vert"); particleShader.LoadFromFile(GL_VERTEX_SHADER,"shaders/Basic.vert"); particleShader.LoadFromFile(GL_FRAGMENT_SHADER,"shaders/Basic.frag"); renderShader.LoadFromFile(GL_VERTEX_SHADER,"shaders/Passthrough.vert"); renderShader.LoadFromFile(GL_FRAGMENT_SHADER,"shaders/Passthrough.frag"); //compile and link mass spring shader massSpringShader.CreateAndLinkProgram(); massSpringShader.Use(); //add attributes and uniforms massSpringShader.AddAttribute("position_mass"); massSpringShader.AddAttribute("prev_position"); massSpringShader.AddUniform("tex_position_mass"); massSpringShader.AddUniform("tex_pre_position_mass"); massSpringShader.AddUniform("MVP"); massSpringShader.AddUniform("dt"); massSpringShader.AddUniform("gravity"); massSpringShader.AddUniform("ksStr"); massSpringShader.AddUniform("ksShr"); massSpringShader.AddUniform("ksBnd"); massSpringShader.AddUniform("kdStr"); massSpringShader.AddUniform("kdShr"); massSpringShader.AddUniform("kdBnd"); massSpringShader.AddUniform("DEFAULT_DAMPING"); massSpringShader.AddUniform("texsize_x"); massSpringShader.AddUniform("texsize_y"); massSpringShader.AddUniform("step"); massSpringShader.AddUniform("inv_cloth_size"); massSpringShader.AddUniform("ellipsoid_xform"); massSpringShader.AddUniform("inv_ellipsoid"); massSpringShader.AddUniform("ellipsoid"); massSpringShader.UnUse(); CHECK_GL_ERRORS //compile and link particle shader particleShader.CreateAndLinkProgram(); particleShader.Use(); //setup attributes and uniforms particleShader.AddAttribute("position_mass"); particleShader.AddUniform("pointSize"); particleShader.AddUniform("MV"); particleShader.AddUniform("MVP"); particleShader.AddUniform("vColor"); particleShader.AddUniform("selected_index"); //pass values to contant uniforms glUniform1f(particleShader("pointSize"), pointSize); glUniform4fv(particleShader("vColor"),1, vRed); particleShader.UnUse(); //compile and link render shader renderShader.CreateAndLinkProgram(); renderShader.Use(); //setup attributes and uniforms renderShader.AddAttribute("position_mass"); renderShader.AddUniform("MVP"); renderShader.AddUniform("vColor"); //pass values to constant uniforms glUniform4fv(renderShader("vColor"),1, vGray); renderShader.UnUse(); CHECK_GL_ERRORS //create vbo createVBO(); //collision ellipsoid ellipsoid = glm::translate(glm::mat4(1),glm::vec3(0,2,0)); ellipsoid = glm::rotate(ellipsoid, 45.0f ,glm::vec3(1,0,0)); ellipsoid = glm::scale(ellipsoid, glm::vec3(fRadius,fRadius,fRadius/2)); inverse_ellipsoid = glm::inverse(ellipsoid); //setup transform feedback attributes glGenTransformFeedbacks(1, &tfID); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID); //pass the vertex shader outputs for transform feedback const char* varying_names[]={"out_position_mass", "out_prev_position"}; glTransformFeedbackVaryings(massSpringShader.GetProgram(), 2, varying_names, GL_SEPARATE_ATTRIBS); //relink the massSpringShader program glLinkProgram(massSpringShader.GetProgram()); //set the mass spring shader and pass values to constant uniforms massSpringShader.Use(); glUniform1f(massSpringShader("dt"), timeStep); glUniform3fv(massSpringShader("gravity"),1,&gravity.x); glUniform1i(massSpringShader("tex_position_mass"), 0); glUniform1i(massSpringShader("tex_pre_position_mass"), 1); glUniform1i(massSpringShader("texsize_x"),texture_size_x); glUniform1i(massSpringShader("texsize_y"),texture_size_y); glUniformMatrix4fv(massSpringShader("ellipsoid_xform"), 1, GL_FALSE, glm::value_ptr(ellipsoid)); glUniformMatrix4fv(massSpringShader("inv_ellipsoid"), 1, GL_FALSE, glm::value_ptr(inverse_ellipsoid)); glUniform4f(massSpringShader("ellipsoid"),0, 0, 0, fRadius); glUniform2f(massSpringShader("inv_cloth_size"),float(sizeX)/numX,float(sizeY)/numY); glUniform2f(massSpringShader("step"),1.0f/(texture_size_x-1.0f),1.0f/(texture_size_y-1.0f)); glUniform1f(massSpringShader("ksStr"), KsStruct); glUniform1f(massSpringShader("ksShr"), KsShear); glUniform1f(massSpringShader("ksBnd"), KsBend); glUniform1f(massSpringShader("kdStr"), KdStruct/1000.0f); glUniform1f(massSpringShader("kdShr"), KdShear/1000.0f); glUniform1f(massSpringShader("kdBnd"), KdBend/1000.0f); glUniform1f(massSpringShader("DEFAULT_DAMPING"), DEFAULT_DAMPING); massSpringShader.UnUse(); //disable vsync wglSwapIntervalEXT(0); }