void onInit() { //tex = loadImage("../textures/texture.png"); tex = loadImage("../textures/dots.png"); tex2 = loadImage("../textures/dots.png"); ctv = new CTextureViewer(0, "../shaders/textureViewer.vs", "../shaders/textureViewer.frag"); ctv->setTexture(tex); ctv->setTexture2(tex2); hist.LoadFromFile(GL_VERTEX_SHADER, "../shaders/histogram.vs"); hist.LoadFromFile(GL_FRAGMENT_SHADER, "../shaders/histogram.frag"); hist.CreateAndLinkProgram(); hist.Use(); //Create uniforms and attributes (filled later) hist.AddAttribute("vPosition"); hist.AddUniform("tex"); hist.AddUniform("textureWidth"); hist.AddUniform("textureHeight"); hist.UnUse(); initTex(); initPointVBO(); initHistogramFBO(); }
void InitShaders(void) { shader.LoadFromFile(GL_VERTEX_SHADER, "../CGE_solarsystem/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "../CGE_solarsystem/shader.frag"); shader.CreateAndLinkProgram(); shader.Use(); shader.AddAttribute("vVertex"); shader.AddAttribute("vUV"); shader.AddUniform("MVP"); shader.AddUniform("textureMap"); glUniform1i(shader("textureMap"), 0); shader.UnUse(); GL_CHECK_ERRORS }
//OpenGL initialization void OnInit() { //set the instance modeling matrix M[0] = glm::translate(glm::mat4(1), glm::vec3(-5,0,-5)); M[1] = glm::translate(M[0], glm::vec3(10,0,0)); M[2] = glm::translate(M[1], glm::vec3(0,0,10)); M[3] = glm::translate(M[2], glm::vec3(-10,0,0)); GL_CHECK_ERRORS //load the shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_GEOMETRY_SHADER, "shaders/shader.geom"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //create and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attribute and uniform shader.AddAttribute("vVertex"); shader.AddUniform("PV"); shader.AddUniform("M"); shader.AddUniform("sub_divisions"); //set values of constant uniforms at initialization glUniform1i(shader("sub_divisions"), sub_divisions); glUniformMatrix4fv(shader("M"), 4, GL_FALSE, glm::value_ptr(M[0])); shader.UnUse(); GL_CHECK_ERRORS //setup quad geometry //setup quad vertices vertices[0] = glm::vec3(-5,0,-5); vertices[1] = glm::vec3(-5,0,5); vertices[2] = glm::vec3(5,0,5); vertices[3] = glm::vec3(5,0,-5); //setup quad indices GLushort* id=&indices[0]; *id++ = 0; *id++ = 1; *id++ = 2; *id++ = 0; *id++ = 2; *id++ = 3; GL_CHECK_ERRORS //setup quad vao and vbo stuff glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass the quad vertices to buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,0,0); GL_CHECK_ERRORS //pass the quad 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 //set the polygon mode to render lines glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_CHECK_ERRORS cout<<"Initialization successfull"<<endl; }
//OpenGL initialization function void OnInit() { GL_CHECK_ERRORS //initialize FBO initFBO(); //generate hardwre query glGenQueries(1, &queryId); //create a uniform grid of size 20x20 in XZ plane grid = new CGrid(20,20); GL_CHECK_ERRORS //generate the quad vertices glm::vec2 quadVerts[4]; quadVerts[0] = glm::vec2(0,0); quadVerts[1] = glm::vec2(1,0); quadVerts[2] = glm::vec2(1,1); quadVerts[3] = glm::vec2(0,1); //generate quad indices GLushort quadIndices[]={ 0,1,2,0,2,3}; //generate quad vertex array and vertex buffer objects glGenVertexArrays(1, &quadVAOID); glGenBuffers(1, &quadVBOID); glGenBuffers(1, &quadIndicesID); glBindVertexArray(quadVAOID); glBindBuffer (GL_ARRAY_BUFFER, quadVBOID); //pass quad vertices to buffer object memory glBufferData (GL_ARRAY_BUFFER, sizeof(quadVerts), &quadVerts[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,0,0); //pass the quad indices to the element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, quadIndicesID); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof(quadIndices), &quadIndices[0], GL_STATIC_DRAW); //setup unit cube vertex array and vertex buffer objects glGenVertexArrays(1, &cubeVAOID); glGenBuffers(1, &cubeVBOID); glGenBuffers(1, &cubeIndicesID); //unit cube vertices glm::vec3 vertices[8]={ glm::vec3(-0.5f,-0.5f,-0.5f), glm::vec3( 0.5f,-0.5f,-0.5f), glm::vec3( 0.5f, 0.5f,-0.5f), glm::vec3(-0.5f, 0.5f,-0.5f), glm::vec3(-0.5f,-0.5f, 0.5f), glm::vec3( 0.5f,-0.5f, 0.5f), glm::vec3( 0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f)}; //unit cube indices GLushort cubeIndices[36]={0,5,4, 5,0,1, 3,7,6, 3,6,2, 7,4,6, 6,4,5, 2,1,3, 3,1,0, 3,0,7, 7,0,4, 6,5,2, 2,5,1}; glBindVertexArray(cubeVAOID); glBindBuffer (GL_ARRAY_BUFFER, cubeVBOID); //pass cube vertices to buffer object memory glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &(vertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attributre array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,0,0); //pass cube indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, cubeIndicesID); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), &cubeIndices[0], GL_STATIC_DRAW); glBindVertexArray(0); //Load the cube shader cubeShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/cube_shader.vert"); cubeShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/cube_shader.frag"); //compile and link the shader cubeShader.CreateAndLinkProgram(); cubeShader.Use(); //add attributes and uniforms cubeShader.AddAttribute("vVertex"); cubeShader.AddUniform("MVP"); cubeShader.AddUniform("vColor"); cubeShader.UnUse(); //Load the front to back peeling shader frontPeelShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/front_peel.vert"); frontPeelShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/front_peel.frag"); //compile and link the shader frontPeelShader.CreateAndLinkProgram(); frontPeelShader.Use(); //add attributes and uniforms frontPeelShader.AddAttribute("vVertex"); frontPeelShader.AddUniform("MVP"); frontPeelShader.AddUniform("vColor"); frontPeelShader.AddUniform("depthTexture"); //pass constant uniforms at initialization glUniform1i(frontPeelShader("depthTexture"), 0); frontPeelShader.UnUse(); //Load the blending shader blendShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/blend.vert"); blendShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/blend.frag"); //compile and link the shader blendShader.CreateAndLinkProgram(); blendShader.Use(); //add attributes and uniforms blendShader.AddAttribute("vVertex"); blendShader.AddUniform("tempTexture"); //pass constant uniforms at initialization glUniform1i(blendShader("tempTexture"), 0); blendShader.UnUse(); //Load the final shader finalShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/blend.vert"); finalShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/final.frag"); //compile and link the shader finalShader.CreateAndLinkProgram(); finalShader.Use(); //add attributes and uniforms finalShader.AddAttribute("vVertex"); finalShader.AddUniform("colorTexture"); finalShader.AddUniform("vBackgroundColor"); //pass constant uniforms at initialization glUniform1i(finalShader("colorTexture"), 0); finalShader.UnUse(); cout<<"Initialization successfull"<<endl; }
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()); }
//OpenGL initialization function void OnInit() { GL_CHECK_ERRORS //create a uniform grid of size 20x20 in XZ plane grid = new CGrid(20,20); GL_CHECK_ERRORS //create a new TetrahedraMarcher instance marcher = new TetrahedraMarcher(); //set the volume dataset dimensions marcher->SetVolumeDimensions(256,256,256); //load the volume dataset marcher->LoadVolume(volume_file); //set the isosurface value marcher->SetIsosurfaceValue(48); //set the number of sampling voxels marcher->SetNumSamplingVoxels(128,128,128); //begin tetrahedra marching marcher->MarchVolume(); //setup the volume marcher vertex array object and vertex buffer object glGenVertexArrays(1, &volumeMarcherVAO); glGenBuffers(1, &volumeMarcherVBO); glBindVertexArray(volumeMarcherVAO); glBindBuffer (GL_ARRAY_BUFFER, volumeMarcherVBO); //pass the obtained vertices from the tetrahedra marcher and pass to the //buffer object memory glBufferData (GL_ARRAY_BUFFER, marcher->GetTotalVertices()*sizeof(Vertex), marcher->GetVertexPointer(), GL_STATIC_DRAW); //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); //enable vertex attribute array for normals glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),(const GLvoid*)offsetof(Vertex, normal)); GL_CHECK_ERRORS //load the shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/marcher.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/marcher.frag"); //compile and link the shader program shader.CreateAndLinkProgram(); shader.Use(); //add attribute and uniform shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddUniform("MVP"); shader.UnUse(); GL_CHECK_ERRORS //set the background colour glClearColor(bg.r, bg.g, bg.b, bg.a); //enable depth test and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { GL_CHECK_ERRORS //create a uniform grid of size 20x20 in XZ plane grid = new CGrid(20,20); GL_CHECK_ERRORS //Load the raycasting shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/raycaster.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/raycaster.frag"); //compile and link the shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddUniform("MVP"); shader.AddUniform("volume"); shader.AddUniform("camPos"); shader.AddUniform("step_size"); //pass constant uniforms at initialization glUniform3f(shader("step_size"), 1.0f/XDIM, 1.0f/YDIM, 1.0f/ZDIM); glUniform1i(shader("volume"),0); shader.UnUse(); GL_CHECK_ERRORS //load volume data if(LoadVolume()) { std::cout<<"Volume data loaded successfully."<<std::endl; } else { std::cout<<"Cannot load volume data."<<std::endl; exit(EXIT_FAILURE); } //set background colour glClearColor(bg.r, bg.g, bg.b, bg.a); //setup unit cube vertex array and vertex buffer objects glGenVertexArrays(1, &cubeVAOID); glGenBuffers(1, &cubeVBOID); glGenBuffers(1, &cubeIndicesID); //unit cube vertices glm::vec3 vertices[8]= { glm::vec3(-0.5f,-0.5f,-0.5f), glm::vec3( 0.5f,-0.5f,-0.5f), glm::vec3( 0.5f, 0.5f,-0.5f), glm::vec3(-0.5f, 0.5f,-0.5f), glm::vec3(-0.5f,-0.5f, 0.5f), glm::vec3( 0.5f,-0.5f, 0.5f), glm::vec3( 0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f) }; //unit cube indices GLushort cubeIndices[36]= {0,5,4, 5,0,1, 3,7,6, 3,6,2, 7,4,6, 6,4,5, 2,1,3, 3,1,0, 3,0,7, 7,0,4, 6,5,2, 2,5,1 }; glBindVertexArray(cubeVAOID); glBindBuffer (GL_ARRAY_BUFFER, cubeVBOID); //pass cube vertices to buffer object memory glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &(vertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attributre array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,0,0); //pass indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, cubeIndicesID); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), &cubeIndices[0], GL_STATIC_DRAW); glBindVertexArray(0); //enable depth test glEnable(GL_DEPTH_TEST); //set the over blending function glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { //set the polygon mode to render lines glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_CHECK_ERRORS //load shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add shader attribute and uniforms shader.AddAttribute("vVertex"); shader.AddUniform("MVP"); shader.AddUniform("time"); shader.UnUse(); GL_CHECK_ERRORS //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(shader["vVertex"]); glVertexAttribPointer(shader["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; }
//OpenGL initialization void OnInit() { GL_CHECK_ERRORS //load shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddUniform("textureMap"); //pass values of constant uniforms at initialization glUniform1i(shader("textureMap"), 0); shader.UnUse(); GL_CHECK_ERRORS //setup quad geometry //setup quad vertices vertices[0] = glm::vec2(0.0,0.0); vertices[1] = glm::vec2(1.0,0.0); vertices[2] = glm::vec2(1.0,1.0); vertices[3] = glm::vec2(0.0,1.0); //fill quad indices array GLushort* id=&indices[0]; *id++ =0; *id++ =1; *id++ =2; *id++ =0; *id++ =2; *id++ =3; GL_CHECK_ERRORS //setup quad vao and vbo stuff glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass quad vertices to buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 2, GL_FLOAT, GL_FALSE,0,0); GL_CHECK_ERRORS //pass quad 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 //load the image using SOIL int texture_width = 0, texture_height = 0, channels=0; GLubyte* pData = SOIL_load_image(filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_AUTO); if(pData == NULL) { cerr<<"Cannot load image: "<<filename.c_str()<<endl; exit(EXIT_FAILURE); } //vertically flip the image on Y axis since it is inverted int i,j; for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width * channels; int index2 = (texture_height - 1 - j) * texture_width * channels; for( i = texture_width * channels; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //setup OpenGL texture and bind to texture unit 0 glGenTextures(1, &textureID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); //set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); //allocate texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, pData); //free SOIL image data SOIL_free_image_data(pData); GL_CHECK_ERRORS cout<<"Initialization successfull"<<endl; }
//OpenGL initialization function void OnInit() { //setup fullscreen quad geometry glm::vec2 quadVerts[4]; quadVerts[0] = glm::vec2(-1,-1); quadVerts[1] = glm::vec2(1,-1); quadVerts[2] = glm::vec2(1,1); quadVerts[3] = glm::vec2(-1,1); //setup quad indices GLushort quadIndices[]={ 0,1,2,0,2,3}; //setup quad vertex array and vertex buffer objects glGenVertexArrays(1, &quadVAOID); glGenBuffers(1, &quadVBOID); glGenBuffers(1, &quadIndicesID); glBindVertexArray(quadVAOID); glBindBuffer (GL_ARRAY_BUFFER, quadVBOID); //pass quad vertices to vertex buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(quadVerts), &quadVerts[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,0,0); //pass quad indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, quadIndicesID); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof(quadIndices), &quadIndices[0], GL_STATIC_DRAW); //get the mesh path for loading of textures std::string mesh_path = mesh_filename.substr(0, mesh_filename.find_last_of("/")+1); //load the obj model vector<unsigned short> indices2; vector<glm::vec3> vertices2; if(!obj.Load(mesh_filename.c_str(), meshes, vertices, indices, materials, aabb, vertices2, indices2)) { cout<<"Cannot load the 3ds mesh"<<endl; exit(EXIT_FAILURE); } GL_CHECK_ERRORS int total =0; //check the total number of non empty textures since we will use this //information to creare a single array texture to store all textures for(size_t k=0;k<materials.size();k++) { if(materials[k]->map_Kd != "") { total++; } } //load material textures for(size_t k=0;k<materials.size();k++) { //if the diffuse texture name is not empty if(materials[k]->map_Kd != "") { if(k==0) { //generate a new OpenGL array texture glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D_ARRAY, textureID); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP); } int texture_width = 0, texture_height = 0, channels=0; const string& filename = materials[k]->map_Kd; std::string full_filename = mesh_path; full_filename.append(filename); //use SOIL to load the texture GLubyte* pData = SOIL_load_image(full_filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_AUTO); if(pData == NULL) { cerr<<"Cannot load image: "<<full_filename.c_str()<<endl; exit(EXIT_FAILURE); } //Flip the image on Y axis int i,j; for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width * channels; int index2 = (texture_height - 1 - j) * texture_width * channels; for( i = texture_width * channels; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //get the image format GLenum format = GL_RGBA; switch(channels) { case 2: format = GL_RG32UI; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } //if this is the first texture, allocate the array texture if(k==0) { glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, texture_width, texture_height, total, 0, format, GL_UNSIGNED_BYTE, NULL); } //modify the existing texture glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0,0,0,k, texture_width, texture_height, 1, format, GL_UNSIGNED_BYTE, pData); //release the SOIL image data SOIL_free_image_data(pData); } } GL_CHECK_ERRORS //load flat shader flatShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/flat.vert"); flatShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/flat.frag"); //compile and link shader flatShader.CreateAndLinkProgram(); flatShader.Use(); //add attribute and uniform flatShader.AddAttribute("vVertex"); flatShader.AddUniform("MVP"); flatShader.UnUse(); //load raytracing shader raytraceShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/raytracer.vert"); raytraceShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/raytracer.frag"); //compile and link shader raytraceShader.CreateAndLinkProgram(); raytraceShader.Use(); //add attribute and uniform raytraceShader.AddAttribute("vVertex"); raytraceShader.AddUniform("eyePos"); raytraceShader.AddUniform("invMVP"); raytraceShader.AddUniform("light_position"); raytraceShader.AddUniform("backgroundColor"); raytraceShader.AddUniform("aabb.min"); raytraceShader.AddUniform("aabb.max"); raytraceShader.AddUniform("vertex_positions"); raytraceShader.AddUniform("triangles_list"); raytraceShader.AddUniform("VERTEX_TEXTURE_SIZE"); raytraceShader.AddUniform("TRIANGLE_TEXTURE_SIZE"); //set values of constant uniforms as initialization glUniform1f(raytraceShader("VERTEX_TEXTURE_SIZE"), (float)vertices2.size()); glUniform1f(raytraceShader("TRIANGLE_TEXTURE_SIZE"), (float)indices2.size()/4); glUniform3fv(raytraceShader("aabb.min"),1, glm::value_ptr(aabb.min)); glUniform3fv(raytraceShader("aabb.max"),1, glm::value_ptr(aabb.max)); glUniform4fv(raytraceShader("backgroundColor"),1, glm::value_ptr(bg)); glUniform1i(raytraceShader("vertex_positions"), 1); glUniform1i(raytraceShader("triangles_list"), 2); raytraceShader.UnUse(); GL_CHECK_ERRORS //load mesh rendering shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attribute and uniform shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddAttribute("vUV"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("P"); shader.AddUniform("textureMap"); shader.AddUniform("textureIndex"); shader.AddUniform("useDefault"); shader.AddUniform("diffuse_color"); shader.AddUniform("light_position"); //set values of constant uniforms as initialization glUniform1i(shader("textureMap"), 0); shader.UnUse(); GL_CHECK_ERRORS //setup the vertex array object and vertex buffer object for the mesh //geometry handling glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass mesh vertices glBufferData (GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), &(vertices[0].pos.x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for vertex normal glEnableVertexAttribArray(shader["vNormal"]); glVertexAttribPointer(shader["vNormal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal)) ); GL_CHECK_ERRORS //enable vertex attribute array for vertex texture coordinates glEnableVertexAttribArray(shader["vUV"]); glVertexAttribPointer(shader["vUV"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, uv)) ); GL_CHECK_ERRORS //if we have a single material, it means the 3ds model contains one mesh //we therefore load it into an element array buffer if(materials.size()==1) { //pass indices to the element array buffer if there is a single material glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*indices.size(), &(indices[0]), GL_STATIC_DRAW); } GL_CHECK_ERRORS glBindVertexArray(0); //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //setup light gizmo vertex array and vertex buffer object IDs glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); //pass crosshair vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //use spherical coordinates to get the light position lightPosOS.x = radius * cos(theta)*sin(phi); lightPosOS.y = radius * cos(phi); lightPosOS.z = radius * sin(theta)*sin(phi); //pass position to 1D texture bound to texture unit 1 glGenTextures(1, &texVerticesID); glActiveTexture(GL_TEXTURE1); glBindTexture( GL_TEXTURE_2D, texVerticesID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GLfloat* pData = new GLfloat[vertices2.size()*4]; int count = 0; for(size_t i=0;i<vertices2.size();i++) { pData[count++] = vertices2[i].x; pData[count++] = vertices2[i].y; pData[count++] = vertices2[i].z; pData[count++] = 0; } //allocate a floating point texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, vertices2.size(),1, 0, GL_RGBA, GL_FLOAT, pData); //delete the data pointer delete [] pData; GL_CHECK_ERRORS //store the mesh topology in another texture bound to texture unit 2 glGenTextures(1, &texTrianglesID); glActiveTexture(GL_TEXTURE2); glBindTexture( GL_TEXTURE_2D, texTrianglesID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GLushort* pData2 = new GLushort[indices2.size()]; count = 0; for(size_t i=0;i<indices2.size();i+=4) { pData2[count++] = (indices2[i]); pData2[count++] = (indices2[i+1]); pData2[count++] = (indices2[i+2]); pData2[count++] = (indices2[i+3]); } //allocate an integer format texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, indices2.size()/4,1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, pData2); //delete heap allocated buffer delete [] pData2; GL_CHECK_ERRORS //set texture unit 0 as active texture unit glActiveTexture(GL_TEXTURE0); //enable depth test and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //set the background colour glClearColor(bg.x, bg.y, bg.z, bg.w); cout<<"Initialization successfull"<<endl; //get the initial time lastTime = (float)glutGet(GLUT_ELAPSED_TIME); }
//OpenGL initialization void OnInit() { //init high performance timer QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&last); //get mesh path std::string mesh_path = mesh_filename.substr(0, mesh_filename.find_last_of("//")+1); glm::vec3 min, max; //load the EZmesh file if(!ezm.Load(mesh_filename.c_str(), skeleton, animations, submeshes, vertices, indices, material2ImageMap, min, max)) { cout<<"Cannot load the EZMesh file"<<endl; exit(EXIT_FAILURE); } //check the absolute value y and z dimensions of the bounding box float dy = fabs(max.y-min.y); float dz = fabs(max.z-min.z); bYup = (dy>dz); //get the combined bone transform UpdateCombinedMatrices(); //resize bind pose, inverse bind pose, animatedXform and dualQuaternion vectors bindPose.resize(skeleton.size()); invBindPose.resize(skeleton.size()); animatedXform.resize(skeleton.size()); dualQuaternions.resize(skeleton.size()); //store the bind pose matrices which are the absolute transform of //each bone. Also store their inverse which is used in skinning for(size_t i=0;i<skeleton.size();i++) { bindPose[i] = (skeleton[i].comb); invBindPose[i] = glm::inverse(bindPose[i]); } GL_CHECK_ERRORS //store the loaded material names into a vector for(iter i = material2ImageMap.begin();i!=material2ImageMap.end();++i) { materialNames.push_back(i->second); } //calculate the distance the camera has to be moved to properly view the EZMesh model center = (max + min) * 0.5f; glm::vec3 diagonal = (max-min); radius = glm::length(center- diagonal * 0.5f); dist = -glm::length(diagonal); //generate OpenGL textures from the loaded material names for(size_t k=0;k<materialNames.size();k++) { if(materialNames[k].length()==0) continue; //get the full image name int texture_width = 0, texture_height = 0, channels=0; const string& filename = materialNames[k]; std::string full_filename = mesh_path; full_filename.append(filename); //pass the full image name including the path and use SOIL library to load the image GLubyte* pData = SOIL_load_image(full_filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_AUTO); if(pData == NULL) { cerr<<"Cannot load image: "<<full_filename.c_str()<<endl; exit(EXIT_FAILURE); } //Flip the image on Y axis int i,j; for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width * channels; int index2 = (texture_height - 1 - j) * texture_width * channels; for( i = texture_width * channels; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //determine the image format GLenum format = GL_RGBA; switch(channels) { case 2: format = GL_RG32UI; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } GLuint id = 0; //generate new texture id glGenTextures(1, &id); glBindTexture(GL_TEXTURE_2D, id); //set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //allocate the texture glTexImage2D(GL_TEXTURE_2D, 0, format, texture_width, texture_height, 0, format, GL_UNSIGNED_BYTE, pData); //delete the SOIL image data SOIL_free_image_data(pData); //store the texture id into the material map. Refer to the texture by name //will give us its OpenGL texture id materialMap[filename] = id ; } GL_CHECK_ERRORS //setup shaders flatShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/flat.vert"); flatShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/flat.frag"); //compile and link flat shader flatShader.CreateAndLinkProgram(); flatShader.Use(); //add shader attributes and uniforms flatShader.AddAttribute("vVertex"); flatShader.AddUniform("MVP"); flatShader.UnUse(); //For the skinning vertex shader, we pass the Bones array dynamcially //since we may not know the total number of bones in the model at compile //time. Since the GLSL arrays have to be a compile time constant, we //dynamically generate the shader string to add the uniform in the shader. //To achieve this, we overload the GLSLShader::LoadFromFile function with //a thid parameter, the string we want to add before the shader main function. stringstream str( ios_base::app | ios_base::out); str<<"\nconst int NUM_BONES="<<skeleton.size()*2<<";"<<endl; str<<"uniform vec4 Bones[NUM_BONES];"<<endl; shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert", str.str()); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add shader attributes and uniforms shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddAttribute("vUV"); shader.AddAttribute("vBlendWeights"); shader.AddAttribute("viBlendIndices"); shader.AddUniform("Bones"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("P"); shader.AddUniform("textureMap"); shader.AddUniform("useDefault"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); glUniform1i(shader("textureMap"), 0); //pass values to uniforms at initialization, since we have a dual quaternion we pass //it as 2 vec4 variables hence the multiplication by 2 glUniform4fv(shader("Bones"), skeleton.size()*2, &(dualQuaternions[0].ordinary.x)); shader.UnUse(); GL_CHECK_ERRORS //setup geometry //setup vao and vbo stuff glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass vertices to buffer object memory glBufferData (GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), &(vertices[0].pos.x), GL_DYNAMIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable normal attribute glEnableVertexAttribArray(shader["vNormal"]); glVertexAttribPointer(shader["vNormal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal)) ); GL_CHECK_ERRORS //enable texture coordinate attribute glEnableVertexAttribArray(shader["vUV"]); glVertexAttribPointer(shader["vUV"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, uv)) ); GL_CHECK_ERRORS //enable blend weights attribute array glEnableVertexAttribArray(shader["vBlendWeights"]); glVertexAttribPointer(shader["vBlendWeights"], 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, blendWeights)) ); GL_CHECK_ERRORS //enable blend indices attribute array glEnableVertexAttribArray(shader["viBlendIndices"]); glVertexAttribIPointer(shader["viBlendIndices"], 4, GL_INT, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, blendIndices)) ); GL_CHECK_ERRORS //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //generate light vertex array and buffer object glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); //pass the cross hair data to the buffer object memory glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_DYNAMIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //get the light position using the center and the spherical coordinates lightPosOS.x = center.x + radius * cos(theta)*sin(phi); lightPosOS.y = center.y + radius * cos(phi); lightPosOS.z = center.z + radius * sin(theta)*sin(phi); //enable depth test and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //set clear color to corn blue glClearColor(0.5,0.5,1,1); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { //load the per-fragment point light shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/PointLight.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/PointLight.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddUniform("MVP"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); shader.UnUse(); GL_CHECK_ERRORS //setup sphere geometry CreateSphere(1.0f,10,10, vertices, indices); //setup sphere vao and vbo stuff glGenVertexArrays(1, &sphereVAOID); glGenBuffers(1, &sphereVerticesVBO); glGenBuffers(1, &sphereIndicesVBO); glBindVertexArray(sphereVAOID); glBindBuffer (GL_ARRAY_BUFFER, sphereVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass sphere indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); //store the total number of sphere triangles totalSphereTriangles = indices.size(); //clear the vertices and indices vectors as we will reuse them //for cubes vertices.clear(); indices.clear(); //setup cube geometry CreateCube(2,vertices, indices); //setup cube vao and vbo stuff glGenVertexArrays(1, &cubeVAOID); glGenBuffers(1, &cubeVerticesVBO); glGenBuffers(1, &cubeIndicesVBO); glBindVertexArray(cubeVAOID); glBindBuffer (GL_ARRAY_BUFFER, cubeVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass cube indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, cubeIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //setup light gizmo vertex array and buffer object glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); //pass light crosshair gizmo vertices to buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //enable depth testing and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); GL_CHECK_ERRORS //create a grid of 10x10 size in XZ plane grid = new CGrid(); GL_CHECK_ERRORS //get the grid shader for rendering of the light's crosshair gizmo pFlatShader = grid->GetShader(); //get the light position using the spherical coordinates lightPosOS.x = radius * cos(theta)*sin(phi); lightPosOS.y = radius * cos(phi); lightPosOS.z = radius * sin(theta)*sin(phi); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { GL_CHECK_ERRORS //load heightmap shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddUniform("heightMapTexture"); shader.AddUniform("scale"); shader.AddUniform("half_scale"); shader.AddUniform("HALF_TERRAIN_SIZE"); shader.AddUniform("MVP"); //set values of constant uniforms as initialization glUniform1i(shader("heightMapTexture"), 0); glUniform2i(shader("HALF_TERRAIN_SIZE"), TERRAIN_WIDTH>>1, TERRAIN_DEPTH>>1); glUniform1f(shader("scale"), scale); glUniform1f(shader("half_scale"), half_scale); shader.UnUse(); GL_CHECK_ERRORS //fill indices array GLuint* id=&indices[0]; int i=0, j=0; //setup vertices int count = 0; //fill terrain vertices for( j=0;j<TERRAIN_DEPTH;j++) { for( i=0;i<TERRAIN_WIDTH;i++) { vertices[count] = glm::vec3( (float(i)/(TERRAIN_WIDTH-1)), 0, (float(j)/(TERRAIN_DEPTH-1))); count++; } } //fill terrain indices for (i = 0; i < TERRAIN_DEPTH-1; i++) { for (j = 0; j < TERRAIN_WIDTH-1; j++) { int i0 = j+ i*TERRAIN_WIDTH; int i1 = i0+1; int i2 = i0+TERRAIN_WIDTH; int i3 = i2+1; *id++ = i0; *id++ = i2; *id++ = i1; *id++ = i1; *id++ = i2; *id++ = i3; } } GL_CHECK_ERRORS //setup terrain vertex array and vertex buffer objects glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass terrain vertices to buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,0,0); GL_CHECK_ERRORS //pass the terrain indices array 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 //load the heightmap texture using SOIL int texture_width = 0, texture_height = 0, channels=0; GLubyte* pData = SOIL_load_image(filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_L); //vertically flip the heightmap image on Y axis since it is inverted for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width ; int index2 = (texture_height - 1 - j) * texture_width ; for( i = texture_width ; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //setup OpenGL texture glGenTextures(1, &heightMapTextureID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, heightMapTextureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, texture_width, texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, pData); //free SOIL image data SOIL_free_image_data(pData); GL_CHECK_ERRORS //set polygon mode to draw lines glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_CHECK_ERRORS cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { //load the per-vertex lighting shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/perVertexLighting.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/perVertexLighting.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddUniform("MVP"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); shader.AddUniform("specular_color"); shader.AddUniform("shininess"); shader.UnUse(); GL_CHECK_ERRORS //cerate sphere geometry CreateSphere(1.0f,10,10, vertices, indices); //setup sphere vao and vbo stuff glGenVertexArrays(1, &sphereVAOID); glGenBuffers(1, &sphereVerticesVBO); glGenBuffers(1, &sphereIndicesVBO); glBindVertexArray(sphereVAOID); glBindBuffer (GL_ARRAY_BUFFER, sphereVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass sphere indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); //store the total number of sphere triangles totalSphereTriangles = indices.size(); //clear the vertices and indices vectors as we will reuse them //for cubes vertices.clear(); indices.clear(); //setup cube geometry CreateCube(1,vertices, indices); //setup cube vao and vbo stuff glGenVertexArrays(1, &cubeVAOID); glGenBuffers(1, &cubeVerticesVBO); glGenBuffers(1, &cubeIndicesVBO); glBindVertexArray(cubeVAOID); glBindBuffer (GL_ARRAY_BUFFER, cubeVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribut array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribut array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass cube indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, cubeIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable depth testing and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //create a grid of 10x10 size in XZ plane grid = new CGrid(); GL_CHECK_ERRORS cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { //load the flat shader flatshader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); flatshader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader flatshader.CreateAndLinkProgram(); flatshader.Use(); //add attributes and uniforms flatshader.AddAttribute("vVertex"); flatshader.AddUniform("MVP"); flatshader.UnUse(); //load the shadow mapping shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/PointLightShadowMapped.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/PointLightShadowMapped.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attributes and uniforms shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddUniform("MVP"); shader.AddUniform("MV"); shader.AddUniform("M"); shader.AddUniform("N"); shader.AddUniform("S"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); shader.AddUniform("bIsLightPass"); shader.AddUniform("shadowMap"); //pass value of constant uniforms at initialization glUniform1i(shader("shadowMap"),0); shader.UnUse(); GL_CHECK_ERRORS //setup sphere geometry CreateSphere(1.0f,10,10, vertices, indices); //setup sphere vao and vbo stuff glGenVertexArrays(1, &sphereVAOID); glGenBuffers(1, &sphereVerticesVBO); glGenBuffers(1, &sphereIndicesVBO); glBindVertexArray(sphereVAOID); glBindBuffer (GL_ARRAY_BUFFER, sphereVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass sphere indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); //store the total number of sphere triangles totalSphereTriangles = indices.size(); //clear the vertices and indices vectors as we will reuse them //for cubes vertices.clear(); indices.clear(); //setup cube geometry CreateCube(2,vertices, indices); //setup cube vao and vbo stuff glGenVertexArrays(1, &cubeVAOID); glGenBuffers(1, &cubeVerticesVBO); glGenBuffers(1, &cubeIndicesVBO); glBindVertexArray(cubeVAOID); glBindBuffer (GL_ARRAY_BUFFER, cubeVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normals glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass cube indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, cubeIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //clear the vertices and indices vectors as we will reuse them //for plane vertices.clear(); indices.clear(); //create a plane object CreatePlane(100,100,vertices, indices); //setup plane VAO and VBO glGenVertexArrays(1, &planeVAOID); glGenBuffers(1, &planeVerticesVBO); glGenBuffers(1, &planeIndicesVBO); glBindVertexArray(planeVAOID); glBindBuffer (GL_ARRAY_BUFFER, planeVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normals glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass plane indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, planeIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //setup light gizmo vertex array and buffer object glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); //pass light crosshair gizmo vertices to buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //get light position from spherical coordinates lightPosOS.x = radius * cos(theta)*sin(phi); lightPosOS.y = radius * cos(phi); lightPosOS.z = radius * sin(theta)*sin(phi); //setup the shadowmap texture glGenTextures(1, &shadowMapTexID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, shadowMapTexID); //set texture parameters GLfloat border[4]={1,0,0,0}; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC,GL_LEQUAL); glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,border); glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT24,SHADOWMAP_WIDTH,SHADOWMAP_HEIGHT,0,GL_DEPTH_COMPONENT,GL_UNSIGNED_BYTE,NULL); //set up FBO to get the depth component glGenFramebuffers(1,&fboID); glBindFramebuffer(GL_FRAMEBUFFER,fboID); glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,shadowMapTexID,0); //check framebuffer completeness status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if(status == GL_FRAMEBUFFER_COMPLETE) { cout<<"FBO setup successful."<<endl; } else { cout<<"Problem in FBO setup."<<endl; } //unbind FBO glBindFramebuffer(GL_FRAMEBUFFER,0); //set the light MV, P and bias matrices MV_L = glm::lookAt(lightPosOS,glm::vec3(0,0,0),glm::vec3(0,1,0)); P_L = glm::perspective(glm::radians(50.0f),1.0f,1.0f, 25.0f); B = glm::scale(glm::translate(glm::mat4(1),glm::vec3(0.5,0.5,0.5)), glm::vec3(0.5,0.5,0.5)); BP = B*P_L; S = BP*MV_L; //enable depth testing and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization function void OnInit() { //generate the pseudorandom noise data glm::vec4 pData[64][64]; for(int j=0;j<64;j++) { for(int i=0;i<64;i++) { pData[i][j].x = (float)rand() / RAND_MAX; pData[i][j].y = (float)rand() / RAND_MAX; pData[i][j].z = (float)rand() / RAND_MAX; pData[i][j].w = (float)rand() / RAND_MAX; } } //use the pseudorandom noise data to generate a 64x64 nosie texture glGenTextures(1, &noiseTexID); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, noiseTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 64, 64, 0, GL_BGRA, GL_FLOAT, pData); //get the mesh path for loading of textures std::string mesh_path = mesh_filename.substr(0, mesh_filename.find_last_of("/")+1); //load the obj model if(!obj.Load(mesh_filename.c_str(), meshes, vertices, indices, materials)) { cout<<"Cannot load the Obj mesh"<<endl; exit(EXIT_FAILURE); } GL_CHECK_ERRORS //bind texture 0 as active texture unit glActiveTexture(GL_TEXTURE0); //load material textures for(size_t k=0;k<materials.size();k++) { //if the diffuse texture name is not empty if(materials[k]->map_Kd != "") { GLuint id = 0; //generate a new OpenGL texture glGenTextures(1, &id); glBindTexture(GL_TEXTURE_2D, id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); int texture_width = 0, texture_height = 0, channels=0; const string& filename = materials[k]->map_Kd; std::string full_filename = mesh_path; full_filename.append(filename); //use SOIL to load the texture GLubyte* pData = SOIL_load_image(full_filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_AUTO); if(pData == NULL) { cerr<<"Cannot load image: "<<full_filename.c_str()<<endl; exit(EXIT_FAILURE); } //Flip the image on Y axis int i,j; for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width * channels; int index2 = (texture_height - 1 - j) * texture_width * channels; for( i = texture_width * channels; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //get the image format GLenum format = GL_RGBA; switch(channels) { case 2: format = GL_RG32UI; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } //allocate the texture glTexImage2D(GL_TEXTURE_2D, 0, format, texture_width, texture_height, 0, format, GL_UNSIGNED_BYTE, pData); //release the SOIL image data SOIL_free_image_data(pData); //add the texture id to a vector textures.push_back(id); } } GL_CHECK_ERRORS //setup flat shader flatShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/flat.vert"); flatShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/flat.frag"); //compile and link shader flatShader.CreateAndLinkProgram(); flatShader.Use(); //add attribute and uniform flatShader.AddAttribute("vVertex"); flatShader.AddUniform("MVP"); flatShader.UnUse(); //load final shader finalShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Passthrough.vert"); finalShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/final.frag"); //compile and link shader finalShader.CreateAndLinkProgram(); finalShader.Use(); //add attribute and uniform finalShader.AddAttribute("vVertex"); finalShader.AddUniform("MVP"); finalShader.AddUniform("textureMap"); //set values of constant uniforms as initialization glUniform1i(finalShader("textureMap"), 4); finalShader.UnUse(); //load the point light rendering shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); shader.CreateAndLinkProgram(); shader.Use(); //add attribute and uniform shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddAttribute("vUV"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("P"); shader.AddUniform("textureMap"); shader.AddUniform("useDefault"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); //set values of constant uniforms as initialization glUniform1i(shader("textureMap"), 0); shader.UnUse(); //load the horizontal Gaussian blurring shader gaussianH_shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Passthrough.vert"); gaussianH_shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/GaussH.frag"); //compile and link shader gaussianH_shader.CreateAndLinkProgram(); gaussianH_shader.Use(); //add attribute and uniform gaussianH_shader.AddAttribute("vVertex"); gaussianH_shader.AddUniform("textureMap"); //set values of constant uniforms as initialization glUniform1i(gaussianH_shader("textureMap"),5); gaussianH_shader.UnUse(); //load the vertical Gaussian blurring shader gaussianV_shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Passthrough.vert"); gaussianV_shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/GaussV.frag"); //compile and link shader gaussianV_shader.CreateAndLinkProgram(); gaussianV_shader.Use(); //add attribute and uniform gaussianV_shader.AddAttribute("vVertex"); gaussianV_shader.AddUniform("textureMap"); //set values of constant uniforms as initialization glUniform1i(gaussianV_shader("textureMap"),4); gaussianV_shader.UnUse(); //load the first step SSAO shader ssaoFirstShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/SSAO_FirstStep.vert"); ssaoFirstShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/SSAO_FirstStep.frag"); //compile and link shader ssaoFirstShader.CreateAndLinkProgram(); ssaoFirstShader.Use(); //add attribute and uniform ssaoFirstShader.AddAttribute("vVertex"); ssaoFirstShader.AddAttribute("vNormal"); ssaoFirstShader.AddUniform("MVP"); ssaoFirstShader.AddUniform("N"); ssaoFirstShader.UnUse(); //load the second step SSAO shader ssaoSecondShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/Passthrough.vert"); ssaoSecondShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/SSAO_SecondStep.frag"); //compile and link shader ssaoSecondShader.CreateAndLinkProgram(); ssaoSecondShader.Use(); //add attribute and uniform ssaoSecondShader.AddAttribute("vVertex"); ssaoSecondShader.AddUniform("samples"); ssaoSecondShader.AddUniform("invP"); ssaoSecondShader.AddUniform("normalTex"); ssaoSecondShader.AddUniform("depthTex"); ssaoSecondShader.AddUniform("noiseTex"); ssaoSecondShader.AddUniform("radius"); ssaoSecondShader.AddUniform("viewportSize"); ssaoSecondShader.AddUniform("invViewportSize"); //set values of constant uniforms as initialization glUniform2f(ssaoSecondShader("viewportSize"), float(RTT_WIDTH), float(RTT_HEIGHT)); glUniform2f(ssaoSecondShader("invViewportSize"), 1.0f/float(RTT_WIDTH), 1.0f/float(RTT_HEIGHT)); glUniform1i(ssaoSecondShader("normalTex"),1); glUniform1i(ssaoSecondShader("noiseTex"),2); glUniform1i(ssaoSecondShader("depthTex"),3); glm::mat4 biasMat; biasMat = glm::translate(glm::mat4(1),glm::vec3(0.5,0.5,0.5)); biasMat = glm::scale(biasMat, glm::vec3(0.5,0.5,0.5)); glm::mat4 invP = biasMat*glm::inverse(P); glUniformMatrix4fv(ssaoSecondShader("invP"), 1, GL_FALSE, glm::value_ptr(invP)); glm::vec2 samples[16]; float angle = (float)M_PI_4; for(int i=0;i<16;i++) { samples[i].x = cos(angle) * (float)(i+1)/16.0f; samples[i].y = sin(angle) * (float)(i+1)/16.0f; angle += (float)M_PI_2; if(((i + 1) % 4) == 0) angle += (float)M_PI_4; } glUniform2fv(ssaoSecondShader("samples"), 16, &(samples[0].x)); ssaoSecondShader.UnUse(); GL_CHECK_ERRORS //setup the vertex array object and vertex buffer object for the mesh //geometry handling glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass mesh vertices glBufferData (GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), &(vertices[0].pos.x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for vertex normal glEnableVertexAttribArray(shader["vNormal"]); glVertexAttribPointer(shader["vNormal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal)) ); GL_CHECK_ERRORS //enable vertex attribute array for vertex texture coordinates glEnableVertexAttribArray(shader["vUV"]); glVertexAttribPointer(shader["vUV"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, uv)) ); //if we have a single material, it means the 3ds model contains one mesh //we therefore load it into an element array buffer if(materials.size()==1) { //pass indices to the element array buffer if there is a single material glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*indices.size(), &(indices[0]), GL_STATIC_DRAW); } GL_CHECK_ERRORS //setup fullscreen quad vertices glm::vec2 quadVerts[4]; quadVerts[0] = glm::vec2(0,0); quadVerts[1] = glm::vec2(1,0); quadVerts[2] = glm::vec2(1,1); quadVerts[3] = glm::vec2(0,1); //setup quad indices GLushort quadIndices[]={ 0,1,2,0,2,3}; //setup quad vertex array and vertex buffer objects glGenVertexArrays(1, &quadVAOID); glGenBuffers(1, &quadVBOID); glGenBuffers(1, &quadIndicesID); glBindVertexArray(quadVAOID); glBindBuffer (GL_ARRAY_BUFFER, quadVBOID); //pass quad vertices to vertex buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(quadVerts), &quadVerts[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,0,0); //pass quad indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, quadIndicesID); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof(quadIndices), &quadIndices[0], GL_STATIC_DRAW); //glBindVertexArray(0); //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //setup light gizmo vertex array and vertex buffer object IDs glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); //pass crosshair vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //use spherical coordinates to get the light position lightPosOS.x = radius * cos(theta)*sin(phi); lightPosOS.y = radius * cos(phi); lightPosOS.z = radius * sin(theta)*sin(phi); //enable depth test and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //set clear colour to corn blue glClearColor(0.5,0.5,1,1); //initializa FBO InitFBO(); cout<<"Initialization successfull"<<endl; }
void OnInit() { GL_CHECK_ERRORS //setup shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_GEOMETRY_SHADER, "shaders/shader.geom"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); shader.CreateAndLinkProgram(); shader.Use(); shader.AddAttribute("vVertex"); shader.AddUniform("heightMapTexture"); shader.AddUniform("scale"); shader.AddUniform("half_scale"); shader.AddUniform("HALF_TERRAIN_SIZE"); shader.AddUniform("MVP"); glUniform1i(shader("heightMapTexture"), 0); glUniform2i(shader("HALF_TERRAIN_SIZE"), TERRAIN_WIDTH>>1, TERRAIN_DEPTH>>1); glUniform1f(shader("scale"), scale); glUniform1f(shader("half_scale"), half_scale); shader.UnUse(); GL_CHECK_ERRORS //setup geometry //fill indices array GLuint* id=&indices[0]; int i=0, j=0; //setup vertices int count = 0; for( j=0;j<TERRAIN_DEPTH;j++) { for( i=0;i<TERRAIN_WIDTH;i++) { /* vertices[count] = glm::vec3( ( (float(i)/(TERRAIN_WIDTH-1))*2.0f-1)*TERRAIN_HALF_WIDTH, (pData[count]/255.0f)*scale-half_scale, ( (float(j)/(TERRAIN_DEPTH-1))*2.0-1)*TERRAIN_HALF_DEPTH); */ vertices[count] = glm::vec3( (float(i)/(TERRAIN_WIDTH-1)), 0, (float(j)/(TERRAIN_DEPTH-1))); count++; } } for (i = 0; i < TERRAIN_DEPTH-1; i++) { for (j = 0; j < TERRAIN_WIDTH-1; j++) { int i0 = j+ i*TERRAIN_WIDTH; int i1 = i0+1; int i2 = i0+TERRAIN_WIDTH; int i3 = i2+1; *id++ = i0; *id++ = i2; *id++ = i1; *id++ = i1; *id++ = i2; *id++ = i3; } } GL_CHECK_ERRORS //setup vao and vbo stuff glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,0,0); GL_CHECK_ERRORS glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //load the heightmap texture using SOIL int texture_width = 0, texture_height = 0, format=0; GLubyte* pData = SOIL_load_image(filename.c_str(), &texture_width, &texture_height, &format, SOIL_LOAD_L); //setup OpenGL texture glGenTextures(1, &heightMapTextureID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, heightMapTextureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, texture_width, texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, pData); free(pData); GL_CHECK_ERRORS glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); GL_CHECK_ERRORS cout<<"Initialization successfull"<<endl; }
//OpenGL initialization function void OnInit() { //get the mesh path for loading of textures std::string mesh_path = mesh_filename.substr(0, mesh_filename.find_last_of("/")+1); //load the obj model if(!obj.Load(mesh_filename.c_str(), meshes, vertices, indices, materials)) { cout<<"Cannot load the 3ds mesh"<<endl; exit(EXIT_FAILURE); } GL_CHECK_ERRORS //load material textures for(size_t k=0;k<materials.size();k++) { //if the diffuse texture name is not empty if(materials[k]->map_Kd != "") { //generate a new OpenGL array texture GLuint id = 0; glGenTextures(1, &id); glBindTexture(GL_TEXTURE_2D, id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); int texture_width = 0, texture_height = 0, channels=0; const string& filename = materials[k]->map_Kd; std::string full_filename = mesh_path; full_filename.append(filename); //use SOIL to load the texture GLubyte* pData = SOIL_load_image(full_filename.c_str(), &texture_width, &texture_height, &channels, SOIL_LOAD_AUTO); if(pData == NULL) { cerr<<"Cannot load image: "<<full_filename.c_str()<<endl; exit(EXIT_FAILURE); } //Flip the image on Y axis int i,j; for( j = 0; j*2 < texture_height; ++j ) { int index1 = j * texture_width * channels; int index2 = (texture_height - 1 - j) * texture_width * channels; for( i = texture_width * channels; i > 0; --i ) { GLubyte temp = pData[index1]; pData[index1] = pData[index2]; pData[index2] = temp; ++index1; ++index2; } } //get the image format GLenum format = GL_RGBA; switch(channels) { case 2: format = GL_RG32UI; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } //allocate texture glTexImage2D(GL_TEXTURE_2D, 0, format, texture_width, texture_height, 0, format, GL_UNSIGNED_BYTE, pData); //release the SOIL image data SOIL_free_image_data(pData); //add loaded texture ID to vector textures.push_back(id); } } GL_CHECK_ERRORS //load flat shader flatShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/flat.vert"); flatShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/flat.frag"); //compile and link shader flatShader.CreateAndLinkProgram(); flatShader.Use(); //add attribute and uniform flatShader.AddAttribute("vVertex"); flatShader.AddUniform("MVP"); flatShader.UnUse(); //load mesh rendering shader shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert"); shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag"); //compile and link shader shader.CreateAndLinkProgram(); shader.Use(); //add attribute and uniform shader.AddAttribute("vVertex"); shader.AddAttribute("vNormal"); shader.AddAttribute("vUV"); shader.AddUniform("MV"); shader.AddUniform("N"); shader.AddUniform("P"); shader.AddUniform("textureMap"); shader.AddUniform("useDefault"); shader.AddUniform("light_position"); shader.AddUniform("diffuse_color"); //set values of constant uniforms as initialization glUniform1i(shader("textureMap"), 0); shader.UnUse(); GL_CHECK_ERRORS //setup the vertex array object and vertex buffer object for the mesh //geometry handling glGenVertexArrays(1, &vaoID); glGenBuffers(1, &vboVerticesID); glGenBuffers(1, &vboIndicesID); //here we are using interleaved attributes so we can just push data to one //buffer object and then assign different atribute pointer to identofy the //different attributes glBindVertexArray(vaoID); glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID); //pass mesh vertices glBufferData (GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), &(vertices[0].pos.x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(shader["vVertex"]); glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for vertex normal glEnableVertexAttribArray(shader["vNormal"]); glVertexAttribPointer(shader["vNormal"], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal)) ); GL_CHECK_ERRORS //enable vertex attribute array for vertex texture coordinates glEnableVertexAttribArray(shader["vUV"]); glVertexAttribPointer(shader["vUV"], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, uv)) ); GL_CHECK_ERRORS //if we have a single material, it means the 3ds model contains one mesh //we therefore load it into an element array buffer if(materials.size()==1) { //pass indices to the element array buffer if there is a single material glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*indices.size(), &(indices[0]), GL_STATIC_DRAW); } GL_CHECK_ERRORS glBindVertexArray(0); //setup vao and vbo stuff for the light position crosshair glm::vec3 crossHairVertices[6]; crossHairVertices[0] = glm::vec3(-0.5f,0,0); crossHairVertices[1] = glm::vec3(0.5f,0,0); crossHairVertices[2] = glm::vec3(0, -0.5f,0); crossHairVertices[3] = glm::vec3(0, 0.5f,0); crossHairVertices[4] = glm::vec3(0,0, -0.5f); crossHairVertices[5] = glm::vec3(0,0, 0.5f); //setup light gizmo vertex array and vertex buffer object IDs glGenVertexArrays(1, &lightVAOID); glGenBuffers(1, &lightVerticesVBO); glBindVertexArray(lightVAOID); glBindBuffer (GL_ARRAY_BUFFER, lightVerticesVBO); //pass crosshair vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, sizeof(crossHairVertices), &(crossHairVertices[0].x), GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for vertex position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); GL_CHECK_ERRORS //use spherical coordinates to get the light position lightPosOS.x = radius * cos(theta)*sin(phi); lightPosOS.y = radius * cos(phi); lightPosOS.z = radius * sin(theta)*sin(phi); //enable depth test and culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); //set the background colour to corn blue glClearColor(0.5,0.5,1,1); cout<<"Initialization successfull"<<endl; }
//OpenGL initialization void OnInit() { //load the cubemap shader cubemapShader.LoadFromFile(GL_VERTEX_SHADER, "shaders/cubemap.vert"); cubemapShader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/cubemap.frag"); //compile and link shader cubemapShader.CreateAndLinkProgram(); cubemapShader.Use(); //add shader attribute and uniforms cubemapShader.AddAttribute("vVertex"); cubemapShader.AddAttribute("vNormal"); cubemapShader.AddUniform("MVP"); cubemapShader.AddUniform("eyePosition"); cubemapShader.AddUniform("cubeMap"); //set values of constant uniforms at initialization glUniform1i(cubemapShader("cubeMap"), 1); cubemapShader.UnUse(); GL_CHECK_ERRORS //setup sphere geometry createSphere(1,10,10); GL_CHECK_ERRORS //setup sphere vao and vbo stuff glGenVertexArrays(1, &sphereVAOID); glGenBuffers(1, &sphereVerticesVBO); glGenBuffers(1, &sphereIndicesVBO); glBindVertexArray(sphereVAOID); glBindBuffer (GL_ARRAY_BUFFER, sphereVerticesVBO); //pass vertices to the buffer object glBufferData (GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); GL_CHECK_ERRORS //enable vertex attribute array for position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex),0); GL_CHECK_ERRORS //enable vertex attribute array for normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, normal))); GL_CHECK_ERRORS //pass sphere indices to element array buffer glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, sphereIndicesVBO); glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLushort), &indices[0], GL_STATIC_DRAW); //generate the dynamic cubemap texture and bind to texture unit 1 glGenTextures(1, &dynamicCubeMapID); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, dynamicCubeMapID); //set texture parameters glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); //for all 6 cubemap faces for (int face = 0; face < 6; face++) { //allocate a different texture for each face and assign to the cubemap texture target glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, CUBEMAP_SIZE, CUBEMAP_SIZE, 0, GL_RGBA, GL_FLOAT, NULL); } GL_CHECK_ERRORS //setup FBO glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID); //setup render buffer object (RBO) glGenRenderbuffers(1, &rboID); glBindRenderbuffer(GL_RENDERBUFFER, rboID); //set the renderbuffer storage to have the same dimensions as the cubemap texture //also set the renderbuffer as the depth attachment of the FBO glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, CUBEMAP_SIZE, CUBEMAP_SIZE); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboID); //set the dynamic cubemap texture as the colour attachment of FBO glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, dynamicCubeMapID, 0); //check the framebuffer completeness status GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if(status != GL_FRAMEBUFFER_COMPLETE) { cerr<<"Frame buffer object setup error."<<endl; exit(EXIT_FAILURE); } else { cerr<<"FBO setup successfully."<<endl; } //unbind FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //unbind renderbuffer glBindRenderbuffer(GL_RENDERBUFFER, 0); GL_CHECK_ERRORS //create a grid object grid = new CGrid(); //create a unit cube object cube = new CUnitCube(glm::vec3(1,0,0)); GL_CHECK_ERRORS //enable depth testing and back face culling glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); cout<<"Initialization successfull"<<endl; }
//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); }