//Render lighting on geometry in gbuffer void DeferredLightingPass::render(glm::mat4 proj, glm::mat4 view, GBuffer* gBuffer, std::vector<std::shared_ptr<SceneNode>> nodes, std::vector<std::shared_ptr<Light>> lights) { glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); resultBuffer->bind(); glClear(GL_COLOR_BUFFER_BIT); gBuffer->bindAttachments(); glm::mat4 mat1 = glm::mat4(1.0f); for(auto it = lights.begin(); it != lights.end(); it++) { std::shared_ptr<Light> light = (*it); shadowPass.render(proj, view, nodes, light); // Restore gl states after shadow pass glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); resultBuffer->bind(); shadowPass.bindBufferTextures(); deferredPhong.use(); deferredPhong.setLight(light->properties); deferredPhong.setUniforms(proj, view, mat1); glm::vec3 position = glm::vec3(light->properties.position); glm::vec3 lightDir = glm::vec3(light->properties.direction); // Takes [-1, 1] to [0, 1] glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthProjectionMatrix = glm::perspective(light->properties.angle * 2, width/(float)height, 0.1f, 50.0f); glm::mat4 depthViewMatrix = glm::lookAt(position, position + lightDir, glm::vec3(0,1,0)); deferredPhong.setLightMvp(biasMatrix * depthProjectionMatrix * depthViewMatrix); unitQuad.render(); shadowPass.unbindBufferTextures(); } gBuffer->unbindAttachments(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); resultBuffer->unbind(); }
void ShadowMapShaderModule::Use(Mesh* mesh, mat4 toWorldTransform, Camera* camera) { DirectionLight* dirLight = Director::GetInstance()->GetCurrentTree()->_directionLight; if (!dirLight || !dirLight->IsOpenShadow()) { glUniform1i(_openShadowLocation, 0); } else { mat4 dirLightViewTransform = dirLight->GetViewTransform(); mat4 dirLightProjTransform = dirLight->GetProjectTransform(); bool isOpenShadow = dirLight->IsOpenShadow(); glUniform1i(_openShadowLocation, 1); if (isOpenShadow) { glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); mat4 vp = biasMatrix * dirLightProjTransform * dirLightViewTransform * toWorldTransform; glUniformMatrix4fv(_lightMVPLocation, 1, GL_FALSE, &vp[0][0]); glUniform1i(_shadowmapSamplerLocation, SHADOW_MAP_TEXTURE_DIRECTION_LIGHT_INDEX); dirLight->GetTexture()->Bind(SHADOW_MAP_TEXTURE_DIRECTION_LIGHT); } } }
void ShadowMappingShader::SetParameters(va_list uniformList) { Matrix44f biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0); m_OpenGL->SetUniformMatrix4f(theProgram, "mMVP", va_arg(uniformList, Matrix44f).GetTranspose()); m_OpenGL->SetUniformMatrix4f(theProgram, "mWorldMatrix", va_arg(uniformList, Matrix44f).GetTranspose()); m_OpenGL->SetUniformMatrix4f(theProgram, "mDepthMatrix", biasMatrix.GetTranspose()); m_OpenGL->SetUniformVector3f(theProgram, "vLight", va_arg(uniformList, Vector3f).GetValue()); // Set active the texture in the fragment shader. m_OpenGL->BindActiveShadowTexture2D(va_arg(uniformList, GLuint)); // Set the texture in the fragment shader. m_OpenGL->SetUniform1i(theProgram, "iTexture", 1); }
// TODO implement proper light system void MeshRenderer::Render(Camera& cam, GLuint shader) { // matrix to transform range [-1,1] to [0,1] glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); current_tex = 0; glUseProgram(shader); for (entityx::Entity e : entities) { Transform* transform = e.component<Transform>().get(); MeshComponent* mesh_component = e.component<MeshComponent>().get(); Mesh* mesh = mesh_component->mesh; Texture* texture = mesh_component->texture; if (!mesh) continue; if (texture && current_tex != texture->texture_id) { glActiveTexture(GL_TEXTURE0); current_tex = texture->texture_id; glBindTexture(GL_TEXTURE_2D, current_tex); } glm::mat4 worldMat = transform->WorldSpace(); glm::mat4 mvp = cam.combined * worldMat; glUniformMatrix4fv(glGetUniformLocation(shader, "MVP"), 1, GL_FALSE, glm::value_ptr(mvp)); glUniformMatrix4fv(glGetUniformLocation(shader, "worldMat"), 1, GL_FALSE, glm::value_ptr(worldMat)); glUniform2f(glGetUniformLocation(shader, "material"), mesh_component->material.roughness, mesh_component->material.metallic); glBindVertexArray(mesh->vertex_array_object); glDrawElements(GL_TRIANGLES, mesh->num_indices, GL_UNSIGNED_INT, 0); } glBindVertexArray(0); }
void Mesh::Draw(Shader shader, bool drawFBO) { // Bind appropriate textures GLuint diffuseNr = 1; GLuint specularNr = 1; GLuint reflectionNr = 1; //设备坐标系->纹理坐标系 glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); for (GLuint i = 0; i < this->textures.size(); i++) //int i = 1; { //float w = this->cam_pos[this->textures[i].id].at<float>(3, 0); glm::vec3 imageNorm(this->img_norm[this->textures[i].id].at<float>(0, 0), this->img_norm[this->textures[i].id].at<float>(1, 0), this->img_norm[this->textures[i].id].at<float>(2, 0)); glm::vec3 camPos(this->cam_pos[this->textures[i].id].at<float>(0, 0), this->cam_pos[this->textures[i].id].at<float>(1, 0), this->cam_pos[this->textures[i].id].at<float>(2, 0)); //cv::Mat VM = this->viewMatrices[i] * this->modelMatrix;// .inv() * this->modelMatrix.inv(); cv::Mat VM = this->viewMatrices[i].inv() * this->modelMatrix.inv(); cv::Mat vVM(VM, cv::Rect(3, 0, 1, 4)); glm::vec3 cam(vVM.at<float>(0, 0), vVM.at<float>(1, 0), vVM.at<float>(2, 0)); // Compute the MVP matrix from the light's point of view glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, near_plane, far_plane); glm::vec3 origin(0, 0, 0); glm::mat4 depthViewMatrix = glm::lookAt(camPos, origin, glm::vec3(0, 1, 0));//glm::lookAt(lightInvDir, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); glm::mat4 depthModelMatrix; depthModelMatrix = glm::scale(depthModelMatrix, glm::vec3(0.01f, 0.01f, 0.01f)); // It's a bit too big for our scene, so scale it down glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix; if (drawFBO == false) { glActiveTexture(GL_TEXTURE0 + i); // Active proper texture unit before binding // Retrieve texture number (the N in diffuse_textureN) stringstream ss; string number; string name = this->textures[i].type; if (name == "texture_diffuse") ss << diffuseNr++; // Transfer GLuint to stream number = ss.str(); // Now set the sampler to the correct texture unit glUniform1i(glGetUniformLocation(shader.Program, ( name).c_str()), i); glUniform3fv(glGetUniformLocation(shader.Program, "imgNorm" ), 1, glm::value_ptr(imageNorm)); glUniform3fv(glGetUniformLocation(shader.Program, "camPos"), 1, glm::value_ptr(camPos)); // And finally bind the texture glBindTexture(GL_TEXTURE_2D, i+1); glm::mat4 depthBiasMVP = biasMatrix*depthMVP; glUniformMatrix4fv(glGetUniformLocation(shader.Program, "DepthBiasMVP"), 1, GL_FALSE, glm::value_ptr(depthBiasMVP)); //zhongyao int d = this->textures.size() + i; glActiveTexture(GL_TEXTURE0 + d); glBindTexture(GL_TEXTURE_2D, in.depthTexture[i]); glUniform1i(glGetUniformLocation(shader.Program, "shadowMap"), d); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Cull back-facing triangles -> draw only front-facing triangles glBindVertexArray(this->VAO[textures[i].id]); glDrawElements(GL_TRIANGLES, this->indices4draw[textures[i].id].size(), GL_UNSIGNED_INT, 0); glCullFace(GL_FRONT); // Cull back-facing triangles -> draw only front-facing triangles glBindVertexArray(0); } else { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, in.depthMapFBO[i]); // Clear the screen glClear(GL_DEPTH_BUFFER_BIT); glm::mat4 shadowProj = glm::perspective(90.0f, 1.0f, 1.0f, 25.0f); glm::mat4 depthMVPD = shadowProj * glm::lookAt(camPos, camPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "depthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVPD)); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Cull back-facing triangles -> draw only front-facing triangles glBindVertexArray(this->VAO[textures[i].id]); glDrawElements(GL_TRIANGLES, this->indices4draw[textures[i].id].size(), GL_UNSIGNED_INT, 0); glCullFace(GL_FRONT); glBindVertexArray(0); } glActiveTexture(GL_TEXTURE0); } }
void DeferredContainer::draw() const { //"The Screen". It may not be actually the screen since a upper container might be postprocessing const RenderTargetBase* screen = RenderTargetBase::getCurrent(); GL_ASSERT(glEnable(GL_DEPTH_TEST)); GL_ASSERT(glDisable(GL_BLEND)); //Deferred pass Debugger::pushMark("Deferred Pass", "Time spent rendering geometry to the g-buffer"); drawMode = Deferred; RenderTargetBase::bind(gBuffer); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); ContainerObject::draw(); Debugger::popMark(); //deferred //Shadowmap pass Debugger::pushMark("Shadowmap Pass", "Time spent rendering geometry to the layered shadowmap"); glEnable(GL_DEPTH_CLAMP); drawMode = ShadowMap; RenderTargetBase::bind(sunTarget); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT)); ContainerObject::draw(); glDisable(GL_DEPTH_CLAMP); Debugger::popMark(); //shadow //Transparent shadowmap pass Debugger::pushMark("Transparent ShadowMap Pass", "Time spent rendering transparent geometry to the layered shadowmap"); glEnable(GL_DEPTH_CLAMP); drawMode = TransShadowMap; RenderTargetBase::bind(sunTargetTrans); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT)); ContainerObject::draw(); glDisable(GL_DEPTH_CLAMP); Debugger::popMark(); //transparent shadow Debugger::pushMark("Light Pass", "Time spent rendering deferred lights"); //bind output texture (screen) RenderTargetBase::bind(screen); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); //Light pass GL_ASSERT(glEnable(GL_BLEND)); GL_ASSERT(glBlendFunc(GL_ONE, GL_ONE)); //additive GL_ASSERT(glDepthMask(GL_FALSE)); GL_ASSERT(glDepthFunc(GL_ALWAYS)); drawMode = Light; ContainerObject::draw(); Debugger::popMark(); //lights //Ambient+Visibility pass Debugger::pushMark("Ambient+Visibility Pass", "Time spent rendering ambient light and sunlight contribution to the scene"); GL_ASSERT(glDepthMask(GL_TRUE)); const Camera* cam = (Camera*)getGame()->getObjectByName("playerCam"); Sun* sun = (Sun*)getGame()->getObjectByName("sun"); glm::mat4 biasMatrix( //gets coords from [-1..1] to [0..1] 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); //compute each of the cascaded cameras's matrices std::vector<mat4f> depthMVP(NUM_SUN_CASCADES); for(int i = 0; i < NUM_SUN_CASCADES; ++i) depthMVP[i] = biasMatrix*(sun->getVPMatrices()[i]*fullTransform); Programs.get("ambientPass").uniform("MVP")->set(mat4f(1.0f)); Programs.get("ambientPass").uniform("camMV")->set(cam->getView()*fullTransform); Programs.get("ambientPass").uniform("color0")->set(getColor0()); Programs.get("ambientPass").uniform("color1")->set(getColor1()); Programs.get("ambientPass").uniform("invResolution")->set(vec2f(1.0f/screen->getSize().x, 1.0f/screen->getSize().y)); Programs.get("ambientPass").uniform("invCamProj")->set(glm::inverse(cam->projection)); Programs.get("ambientPass").uniform("invCamView")->set(glm::inverse(cam->getView())); Programs.get("ambientPass").uniform("lightDir")->set(sun->getCam(0)->getForward()); Programs.get("ambientPass").uniform("worldsize")->set(WORLDSIZE); Programs.get("ambientPass").uniform("depthMVP")->set(depthMVP); Programs.get("ambientPass").uniform("depthPlanes")->set(sun->getDepthPlanes()); Programs.get("ambientPass").uniform("depth")->set(gBuffer.getTexture(RenderTargetBase::DEPTH)); Programs.get("ambientPass").uniform("sunDepth")->set(sunTarget.getTexture(RenderTargetBase::DEPTH)); Programs.get("ambientPass").uniform("sunDepthTrans")->set(sunTargetTrans.getTexture(RenderTargetBase::DEPTH)); quad->draw(Programs.get("ambientPass")); Debugger::popMark(); //ambient+shadowmap //Forward pass Debugger::pushMark("Forward Pass", "Time spent rendering forward-render stuff"); GL_ASSERT(glDepthMask(GL_TRUE)); GL_ASSERT(glDepthFunc(GL_LEQUAL)); GL_ASSERT(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //forward rendering blending drawMode = Forward; ContainerObject::draw(); Debugger::popMark(); }
void SuzanneGL::RenderShadowMaps() { GLuint FramebufferName = 0; glCreateFramebuffers(1, &FramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); glm::mat4 depthViewProjectionMatrices[NUMBER_OF_LIGHTS]; for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) { glCreateTextures(GL_TEXTURE_2D, 1, &shadowMaps[i]); glTextureImage2DEXT(shadowMaps[i], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SHADOW_RESOLUTION, SHADOW_RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTextureParameteri(shadowMaps[i], GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTextureParameteri(shadowMaps[i], GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTextureParameteri(shadowMaps[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTextureParameteri(shadowMaps[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTextureParameteri(shadowMaps[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTextureParameteri(shadowMaps[i], GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMaps[i], 0); glDrawBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return; glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); glViewport(0, 0, SHADOW_RESOLUTION, SHADOW_RESOLUTION); glm::vec3 lightDir = glm::normalize(glm::vec3(lighting.lights[i].position.x, lighting.lights[i].position.y, lighting.lights[i].position.z)); glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10, 10, -10, 10, -10, 20); glm::mat4 depthViewMatrix = glm::lookAt(lightDir, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); depthViewProjectionMatrices[i] = depthProjectionMatrix * depthViewMatrix; shadowModelMatrixIndex = glGetUniformLocation(shadowShaderProgram, "modelMatrix"); shadowViewProjectionMatrixIndex = glGetUniformLocation(shadowShaderProgram, "viewProjectionMatrix"); glProgramUniformMatrix4fv(shadowShaderProgram, shadowViewProjectionMatrixIndex, 1, GL_FALSE, glm::value_ptr(depthViewProjectionMatrices[i])); for (ModelGL model : models) { glProgramUniformMatrix4fv(shadowShaderProgram, shadowModelMatrixIndex, 1, GL_FALSE, glm::value_ptr(model.modelMatrix)); glNamedBufferSubData(materialBuffer, 0, sizeof(Material), &model.material); glBindVertexArray(model.vertexArray); glUseProgram(shadowShaderProgram); glDrawArrays(GL_TRIANGLES, 0, model.vertexCount); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); shadowViewProjectionMatrixIndex = glGetUniformLocation(shaderProgram, "shadowViewProjectionMatrix"); shadowBiasMatrixIndex = glGetUniformLocation(shaderProgram, "shadowBiasMatrix"); glProgramUniformMatrix4fv(shaderProgram, shadowViewProjectionMatrixIndex, 2, GL_FALSE, glm::value_ptr(depthViewProjectionMatrices[0])); glProgramUniformMatrix4fv(shaderProgram, shadowBiasMatrixIndex, 1, GL_FALSE, glm::value_ptr(biasMatrix)); }
void draw() { #pragma region shadow glm::mat4 depthMVP = glm::mat4( 1.0 ); glm::vec4 lightInvDir = mainLight->getPos(); //Only render the shadow pass if we have shadows enabled if( Settings::getShadowQuality() > 0 ) { //We'll give the meshes and shaders and whatnot to the light so it can render them however //the light returns the depthMVP depthMVP = mainLight->renderShadow( mesh, 1, depth ); } #pragma endregion #pragma region main_render // Render to the screen lastEightFrames[curFrame]->bind(); curFrame++; if( curFrame > 7 ) { curFrame = 0; } glViewport( 0, 0, width, height ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); mainCamera->update(); glm::mat4 ProjectionMatrix = mainCamera->getProjMatrix(); glm::mat4 ViewMatrix = mainCamera->getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4( 1.0 ); //change this per model glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasMVP = biasMatrix * depthMVP; // Use our shader diffuse->bind(); // Send our transformation to the currently bound shader, // in the "MVP" uniform diffuse->setUniformMat4x4( "MVP", &MVP[0][0] ); diffuse->setUniformMat4x4( "M", &ModelMatrix[0][0] ); diffuse->setUniformMat4x4( "V", &ViewMatrix[0][0] ); diffuse->setUniformMat4x4( "DepthBiasMVP", &depthBiasMVP[0][0] ); diffuse->setUniform4f( "lightPosition_worldspace", lightInvDir.x, lightInvDir.y, lightInvDir.z, lightInvDir.w ); diffuse->setUniform4f( "lightColor", mainLight->getColor().r, mainLight->getColor().g, mainLight->getColor().b, mainLight->getColor().a ); // Bind our texture in Texture Unit 0 normalMap->bind( 0 ); // Set our "myTextureSampler" sampler to user Texture Unit 0 diffuse->setUniform1i( "diffuse", 0 ); normalMap->bind( 1 ); diffuse->setUniform1i( "normalMap", 1 ); glActiveTexture( GL_TEXTURE2 ); glBindTexture( GL_TEXTURE_2D, mainLight->getDepthTexture() ); diffuse->setUniform1i( "shadowMap", 2 ); diffuse->setUniform1i( "shadowLevel", Settings::getShadowQuality() ); internalLighting->bind(); internalLighting->setUniformMat4x4( "MVP", &MVP[0][0] ); internalLighting->setUniformMat4x4( "M", &ModelMatrix[0][0] ); internalLighting->setUniformMat4x4( "V", &ViewMatrix[0][0] ); mesh->bind( internalLighting->getAttribute( "vertexPosition_worldspace" ), internalLighting->getAttribute( "vertexUV" ), internalLighting->getAttribute( "vertexNormal_modelspace" ), internalLighting->getAttribute( "vertexTangent_modelspace" ) ); mesh->draw(); #pragma endregion #pragma region debugRenders #pragma endregion glfwSwapBuffers( window ); }
int main( void ) { //init bullet initBullet(); // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //screen resolution GLFW const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); int w = mode->width; int h = mode->height; if(MessageBox(NULL, L"Would you like to run in fullscreen?", L"Fullscreen", MB_ICONQUESTION | MB_YESNO) == IDYES) { window = glfwCreateWindow( w, h, "Ray Tracing - Alfonso Oricchio", glfwGetPrimaryMonitor(), NULL); printf("fullscreen\n"); } else { window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "Ray Tracing - Alfonso Oricchio", NULL, NULL); printf("window\n"); } // Open a window and create its OpenGL context if( window == NULL ){ fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" ); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; } // Ensure we can capture the escape key being pressed below glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // Enable depth test glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); // Cull triangles which normal is not towards the camera //glEnable(GL_CULL_FACE); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Create and compile our GLSL program from the shaders GLuint depthProgramID = LoadShaders( "DepthRTT.vertexshader", "DepthRTT.fragmentshader" ); // Get a handle for our "MVP" uniform GLuint depthMatrixID = glGetUniformLocation(depthProgramID, "depthMVP"); // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. GLuint FramebufferName = 0; glGenFramebuffers(1, &FramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); // Depth texture. Slower than a depth buffer, but you can sample it later in your shader GLuint depthTexture; glGenTextures(1, &depthTexture); glBindTexture(GL_TEXTURE_2D, depthTexture); glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); // No color output in the bound framebuffer, only depth. glDrawBuffer(GL_NONE); // Always check that our framebuffer is ok if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return false; /***********************************************************/ // The quad's FBO. Used only for visualizing the shadowmap. static const GLfloat g_quad_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, }; GLuint quad_vertexbuffer; glGenBuffers(1, &quad_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); // Create and compile our GLSL program from the shaders GLuint quad_programID = LoadShaders( "Passthrough.vertexshader", "SimpleTexture.fragmentshader" ); GLuint texID = glGetUniformLocation(quad_programID, "texture"); /**********************************************************/ // Create and compile our GLSL program from the shaders GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader" ); // Get a handle for our "MVP" uniform GLuint MatrixID = glGetUniformLocation(programID, "MVP"); GLuint ViewMatrixID = glGetUniformLocation(programID, "V"); GLuint ModelMatrixID = glGetUniformLocation(programID, "M"); GLuint DepthBiasID = glGetUniformLocation(programID, "DepthBiasMVP"); GLuint ShadowMapID = glGetUniformLocation(programID, "shadowMap"); // Get a handle for our "LightPosition" uniform GLuint lightInvDirID = glGetUniformLocation(programID, "LightInvDirection_worldspace"); //CUBO1 addBox(2,2,2,0,0,0,1.0); //CUBO2 addBox2(2,2,2,0,6,0,1.0); //FLOOR initFloor(); //WALL initWall(); //BALL addScene(); do{ world->stepSimulation(1/60.f); if (glfwGetKey( window, GLFW_KEY_SPACE ) == GLFW_PRESS){ btRigidBody* ball = addBall(1.0,CamGetPosition().x,CamGetPosition().y,CamGetPosition().z,2.0); ball->setLinearVelocity(btVector3((CamGetDirection().x*50),(CamGetDirection().y*50),(CamGetDirection().z*50))); } // Render to our framebuffer glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ////////////////////////////// // Use our shader //SHADOW RENDER glUseProgram(depthProgramID); glm::vec3 lightInvDir = glm::vec3(0.5f,2,2); // Compute the MVP matrix from the light's point of view glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0)); // or, for spot light : //glm::vec3 lightPos(5, 20, 20); //glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, 2.0f, 50.0f); //glm::mat4 depthViewMatrix = glm::lookAt(lightPos, lightPos-lightInvDir, glm::vec3(0,1,0)); glm::mat4 depthModelMatrix = glm::mat4(1.0); glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix; // Send our transformation to the currently bound shader, // in the "MVP" uniform glUniformMatrix4fv(depthMatrixID, 1, GL_FALSE, &depthMVP[0][0]); // CUBE1 ------------------------------------------------------------------------- renderBox(bodies[0],true); //just a cube not really needed //CUBE2 -------------------------------------------------------------------------- renderBox2(bodies[1],true); //just a cube not really needed //FLOOR -------------------------------------------------------------------------- renderPlane(bodies[2],true); //floor //WALL --------------------------------------------------------------------------- renderWall(bodies[3],true); //back wall //CASTLE ------------------------------------------------------------------------- renderScene(true); //castle, main scene //BALL --------------------------------------------------------------------------- int iv; for(iv = 4; iv < bodies.size();iv++) { renderBall(bodies[iv],(iv - 4),true); //"cannon balls" shooted from the camera } ////////////////////////////// //STANDARD RENDER // Compute the MVP matrix from keyboard and mouse input // Clear the screen // Render to the screen glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader glUseProgram(programID); computeMatricesFromInputs(); glm::mat4 ProjectionMatrix = getProjectionMatrix(); glm::mat4 ViewMatrix = getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4(1.0); glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasMVP = biasMatrix*depthMVP; // Send our transformation to the currently bound shader, // in the "MVP" uniform glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]); glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]); glUniformMatrix4fv(DepthBiasID, 1, GL_FALSE, &depthBiasMVP[0][0]); glUniform3f(lightInvDirID, lightInvDir.x, lightInvDir.y, lightInvDir.z); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, depthTexture); glUniform1i(ShadowMapID, 0); // CUBE1 ------------------------------------------------------------------------- renderBox(bodies[0],false); //just a cube not really needed //CUBE2 -------------------------------------------------------------------------- renderBox2(bodies[1],false); //just a cube not really needed //FLOOR -------------------------------------------------------------------------- renderPlane(bodies[2],false); //floor //WALL --------------------------------------------------------------------------- renderWall(bodies[3],false); //back wall //CASTLE ------------------------------------------------------------------------- renderScene(false); //castle, main scene //BALL --------------------------------------------------------------------------- // int iv; for(iv = 4; iv < bodies.size();iv++) { renderBall(bodies[iv],(iv - 4),false); //"cannon balls" shooted from the camera } /*--------------------------------------------------*/ // Optionally render the shadowmap (for debug only) // Render only on a corner of the window (or we we won't see the real rendering...) glViewport(0,0,512,512); // Use our shader glUseProgram(quad_programID); // Bind our texture in Texture Unit 0 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, depthTexture); // Set our "renderedTexture" sampler to user Texture Unit 0 glUniform1i(texID, 0); // 1rst attribute buffer : vertices glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); glVertexAttribPointer( 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); // Draw the triangle ! // You have to disable GL_COMPARE_R_TO_TEXTURE above in order to see anything ! //glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles glDisableVertexAttribArray(0); /*--------------------------------------------------*/ // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ); deleteALL(); glDeleteProgram(programID); glDeleteVertexArrays(1, &VertexArrayID); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; }
int main( void ) { crap::audiodevice audio_device; /* openalcode */ //setup window crap::window_setup win_setup; win_setup.title = "Funny Window"; win_setup.width = 1024; win_setup.height = 768; win_setup.multisampling_count = 8; win_setup.opengl_version = 3.3f; win_setup.opengl_profile = crap::compat; //create window crap::window window( win_setup ); window.open(); //get keyboard and mouse crap::keyboard keyboard; crap::mouse mouse; // temporary crap::opengl::enable(crap::opengl::depth_test); crap::opengl::setDepthComparison(crap::opengl::less); crap::opengl::enable(crap::opengl::cull_face); //camera setup camera cam; cam.setPosition( glm::vec3( 0.0f, 0.0f, 5.0f ) ); mouse_pos = mouse.position(); //create contentmanager content_manager cm; cm.init( "spg.ini" ); //create vertex array crap::vertex_array vert_array; vert_array.bind(); //test: load vbo onto GPU vbo cube_vbo( "cube", &cm, vbo::static_draw ); vbo ape_vbo("ape", &cm, vbo::static_draw ); vbo cube_big_vbo( "cube", &cm, vbo::static_draw ); //vbo people_vbo("people", &cm, vbo::static_draw ); ////////////////////////// // Read our .obj file std::vector<glm::vec3> vertices; std::vector<glm::vec2> uvs; std::vector<glm::vec3> normals; bool res = loadOBJ("../../../data/geometry/dupercube.obj", vertices, uvs, normals); std::vector<glm::vec3> tangents; std::vector<glm::vec3> bitangents; computeTangentBasis( vertices, uvs, normals, // input tangents, bitangents // output ); std::vector<unsigned short> indices; std::vector<glm::vec3> indexed_vertices; std::vector<glm::vec2> indexed_uvs; std::vector<glm::vec3> indexed_normals; std::vector<glm::vec3> indexed_tangents; std::vector<glm::vec3> indexed_bitangents; indexVBO_TBN( vertices, uvs, normals, tangents, bitangents, indices, indexed_vertices, indexed_uvs, indexed_normals, indexed_tangents, indexed_bitangents ); GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW); GLuint uvbuffer; glGenBuffers(1, &uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW); GLuint normalbuffer; glGenBuffers(1, &normalbuffer); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW); GLuint tangentbuffer; glGenBuffers(1, &tangentbuffer); glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_tangents.size() * sizeof(glm::vec3), &indexed_tangents[0], GL_STATIC_DRAW); GLuint bitangentbuffer; glGenBuffers(1, &bitangentbuffer); glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_bitangents.size() * sizeof(glm::vec3), &indexed_bitangents[0], GL_STATIC_DRAW); // Generate a buffer for the indices as well GLuint elementbuffer; glGenBuffers(1, &elementbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW); ///////////////////////// geometry_content ig; cm.create_content( "cube" , &ig, type_name::geometry ); //test: load texture onto GPU tbo diffuse_tbo( "stone_diff", &cm, tbo::tga ); tbo normal_tbo( "stone_norm", &cm, tbo::tga ); tbo height_tbo( "stone_height", &cm, tbo::tga ); //shadow stuff crap::frame_buffer frame_buffer; frame_buffer.bind(); tbo depthmap( "", &cm, tbo::depth ); frame_buffer.unbind(); //shadow stuff crap::quad_buffer quad_buffer; //test: load linked shader progam onto GPU shader_manager sm(&cm); sm.add("epr_vert", "epr_frag"); sm.add("shadow_vert", "shadow_frag"); //get stuff from shader program //shadow shader sm.set_current("shadow_vert", "shadow_frag"); crap::uniform DepthBiasMVPID = sm.current()->uniform_location("depthMVP"); //vertex shader sm.set_current("epr_vert", "epr_frag"); crap::uniform WorldMatrixID = sm.current()->uniform_location("world_matrix4x4"); crap::uniform ViewMatrixID = sm.current()->uniform_location("view_matrix4x4"); crap::uniform ModelMatrixID = sm.current()->uniform_location("model_matrix4x4"); crap::uniform ModelView3x3MatrixID = sm.current()->uniform_location("model_view_matrix3x3"); //fragment shader crap::uniform DiffuseTextureID = sm.current()->uniform_location("diffuse_texture"); crap::uniform NormalTextureID = sm.current()->uniform_location("normal_texture"); crap::uniform HeightTextureID = sm.current()->uniform_location("height_texture"); crap::uniform LightAmbientPowerID = sm.current()->uniform_location("ambient_power"); crap::uniform LightPowerArrayID = sm.current()->uniform_location("light_power"); crap::uniform LightSpecularTypeArrayID = sm.current()->uniform_location("light_specular_type"); crap::uniform LightSpecularLobeArrayID = sm.current()->uniform_location("light_specular_lobe"); crap::uniform LightColorArrayID = sm.current()->uniform_location("light_color"); crap::uniform LightSelfShadowingOnID = sm.current()->uniform_location("selfshadowing_on"); crap::uniform DisplacementOnID = sm.current()->uniform_location("displacement_on"); crap::uniform DisplacementStepsID = sm.current()->uniform_location("displacement_steps"); crap::uniform DisplacementRefinementStepsID = sm.current()->uniform_location("displacement_refinement_steps"); crap::uniform DisplacementUVFactorID = sm.current()->uniform_location("displacement_uv_factor"); //both shaders crap::uniform LightPositionArrayID = sm.current()->uniform_location("light_position"); crap::uniform LightDirectionArrayID = sm.current()->uniform_location("light_direction"); crap::uniform LightTypeArrayID = sm.current()->uniform_location("light_type"); crap::uniform LightStateArrayID = sm.current()->uniform_location("light_state"); crap::uniform LightNormalMappingOnID = sm.current()->uniform_location("normal_mapping_on"); //shadow stuff crap::uniform ShadowMapID = sm.current()->uniform_location("shadow_map"); crap::uniform ShadowMappingOnID = sm.current()->uniform_location("shadow_mapping_on"); crap::uniform ShadowDepthBiasMVPID = sm.current()->uniform_location("depth_bias_mvp"); //SHADER DATA // Projection matrix : 60° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units float display_field_of_view = 60.f; //60° float display_ratio_horizontal = 4.f; float display_ratio_vertical = 3.f; float display_range_near = 0.1f; float display_range_far = 100.f; glm::mat4 projection_matrix = glm::perspective( display_field_of_view, display_ratio_horizontal / display_ratio_vertical, display_range_near, display_range_far); glm::mat4 model_matrix(1.0f); glm::mat4 model_view_matrix(1.0f); glm::mat4 view_matrix = cam.view(); glm::mat4 world_matrix(1.0f); glm::mat3 model_view_matrix3x3(1.0f); //light stuff float light_ambient_power = 0.5f; float light_power_array[MAX_LIGHTS] = { 1.f, 1.f, 1.f }; int light_specular_type_array[MAX_LIGHTS] = { 1, 1, 1 }; float light_specular_lobe_array[MAX_LIGHTS] = { 100.f, 100.f, 100.f }; glm::vec3 light_color_array[MAX_LIGHTS] = { glm::vec3(1.f), glm::vec3(1.f), glm::vec3(1.f) }; int light_self_shadowing_on = 1; glm::vec3 light_position_array[MAX_LIGHTS] = { glm::vec3(4,0,0), glm::vec3(0,0,-4), glm::vec3(4,4,4) }; glm::vec3 light_direction_array[MAX_LIGHTS] = { glm::vec3(-4,0,0), glm::vec3(0,0,4), glm::vec3(-4,-4,-4) }; int light_type_array[MAX_LIGHTS] = { 0, 0, 0 }; int light_state_array[MAX_LIGHTS] = { 1, 0, 0 }; int light_normal_mapping_on = 1; //shadowstuff int shadow_mapping_on = 1; //displacement stuff int displacement_on = 1; float displacement_steps = 20; float displacement_refinement_steps = 20; float displacmenet_uv_factor = 20; //GUI TwInit(TW_OPENGL, NULL); TwWindowSize(1024, 768); TwBar * GeneralGUI = TwNewBar("General settings"); TwBar * LightGUI = TwNewBar("Light Settings"); TwBar * DisplacementGUI = TwNewBar("Displacement Settings"); TwSetParam(GeneralGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); TwSetParam(LightGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); TwSetParam(DisplacementGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); //general gui TwAddSeparator(GeneralGUI, "Funny seperator", NULL); TwAddVarRW(GeneralGUI, "Field of View", TW_TYPE_FLOAT , &display_field_of_view, "help='Field of View value'"); TwAddVarRW(GeneralGUI, "Ratio Horizontal", TW_TYPE_FLOAT , &display_ratio_horizontal, "help='Ratio Horizontal'"); TwAddVarRW(GeneralGUI, "Ratio Vertical", TW_TYPE_FLOAT , &display_ratio_vertical, "help='Ratio Vertical'"); TwAddVarRW(GeneralGUI, "Range Near", TW_TYPE_FLOAT , &display_range_near, "help='Range near'"); TwAddVarRW(GeneralGUI, "Range far", TW_TYPE_FLOAT , &display_range_far, "help='Range far'"); //light gui TwAddVarRW(LightGUI, "Ambient light", TW_TYPE_FLOAT , &light_ambient_power, "help='Ambient power'"); TwAddVarRW(LightGUI, "Self Shadowing", TW_TYPE_BOOL32, &light_self_shadowing_on, NULL); TwAddVarRW(LightGUI, "Normal Mapping", TW_TYPE_BOOL32, &light_normal_mapping_on, NULL); TwType gui_light_type = TwDefineEnumFromString("LightType", "Directionallight,Pointlight"); TwType gui_light_specular_type = TwDefineEnumFromString("LightSpecularType", "Blinn,Phong"); //shadow TwAddVarRW(LightGUI, "Cast Shadows", TW_TYPE_BOOL32, &shadow_mapping_on, NULL); //light1 TwAddVarRW(LightGUI, "Light 1", TW_TYPE_BOOL32, light_state_array, NULL); TwAddVarRW(LightGUI, "Light Type 1", gui_light_type, light_type_array, NULL); TwAddVarRW(LightGUI, "Light Specular Type 1", gui_light_specular_type, light_specular_type_array, NULL); TwAddVarRW(LightGUI, "Light Power 1", TW_TYPE_FLOAT , light_power_array, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 1", TW_TYPE_FLOAT , light_specular_lobe_array, NULL); TwAddVarRW(LightGUI, "Light Color 1", TW_TYPE_COLOR3F , light_color_array, NULL); TwAddVarRW(LightGUI, "Light Position 1", TW_TYPE_DIR3F , light_position_array, NULL); TwAddVarRW(LightGUI, "Light Direction 1", TW_TYPE_DIR3F , light_direction_array, NULL); //light2 TwAddVarRW(LightGUI, "Light 2", TW_TYPE_BOOL32, light_state_array+1, NULL); TwAddVarRW(LightGUI, "Light Type 2", gui_light_type, light_type_array+1, NULL); TwAddVarRW(LightGUI, "Light Specular Type 2", gui_light_specular_type, light_specular_type_array+1, NULL); TwAddVarRW(LightGUI, "Light Power 2", TW_TYPE_FLOAT , light_power_array+1, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 2", TW_TYPE_FLOAT , light_specular_lobe_array+1, NULL); TwAddVarRW(LightGUI, "Light Color 2", TW_TYPE_COLOR3F , light_color_array+1, NULL); TwAddVarRW(LightGUI, "Light Position 2", TW_TYPE_DIR3F , light_position_array+1, NULL); TwAddVarRW(LightGUI, "Light Direction 2", TW_TYPE_DIR3F , light_direction_array+1, NULL); //light3 TwAddVarRW(LightGUI, "Light 3", TW_TYPE_BOOL32, light_state_array+2, NULL); TwAddVarRW(LightGUI, "Light Type 3", gui_light_type, light_type_array+2, NULL); TwAddVarRW(LightGUI, "Light Specular Type 3", gui_light_specular_type, light_specular_type_array+2, NULL); TwAddVarRW(LightGUI, "Light Power 3", TW_TYPE_FLOAT , light_power_array+2, NULL); TwAddVarRW(LightGUI, "Light Specular Lobe 3", TW_TYPE_FLOAT , light_specular_lobe_array+2, NULL); TwAddVarRW(LightGUI, "Light Color 3", TW_TYPE_COLOR3F , light_color_array+2, NULL); TwAddVarRW(LightGUI, "Light Position 3", TW_TYPE_DIR3F , light_position_array+2, NULL); TwAddVarRW(LightGUI, "Light Direction 3", TW_TYPE_DIR3F , light_direction_array+2, NULL); //displacement gui TwAddVarRW(DisplacementGUI, "Displacement ON/OFF", TW_TYPE_BOOL32, &displacement_on, NULL); TwAddVarRW(DisplacementGUI, "Displacment steps", TW_TYPE_FLOAT , &displacement_steps, NULL); TwAddVarRW(DisplacementGUI, "Displacement refinement", TW_TYPE_FLOAT , &displacement_refinement_steps, NULL); TwAddVarRW(DisplacementGUI, "Displacement UV factor", TW_TYPE_FLOAT , &displacmenet_uv_factor, NULL); //gui mouse setup mouse.set_on_pressed_function( (crap::mouse::user_button_callback_function)gui_mouse_down ); mouse.set_on_release_function( (crap::mouse::user_button_callback_function)gui_mouse_up ); mouse.set_on_move_function( (crap::mouse::user_move_callback_function)TwEventMousePosGLFW ); mouse.set_on_wheel_function( (crap::mouse::user_wheel_callback_function)TwEventMouseWheelGLFW ); keyboard.set_on_pressed_function( (crap::keyboard::user_callback_function)TwEventKeyGLFW ); //todo set char input // temporary crap::opengl::clearColor(1.0f, 1.0f, 1.0f, 0.0f); while( !keyboard.is_pressed( crap::keyboard::key_escape ) && window.is_open() ) { // update positions handleInput(keyboard, mouse, cam); crap::opengl::clear(crap::opengl::color_depth_buffer); frame_buffer.bind(); glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right sm.set_current("shadow_vert", "shadow_frag"); sm.activate(); glm::vec3 lightInvDir = light_direction_array[0]; //glm::vec3(0.5f,2,2); // Compute the MVP matrix from the light's point of view glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0)); glm::mat4 depthModelMatrix = glm::mat4(1.0); glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix; sm.current()->uniform_matrix4f_value( DepthBiasMVPID, 1, &depthMVP[0][0]); sm.current()->vertex_attribute_array.enable(0); cube_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); cube_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); sm.current()->vertex_attribute_array.disable(0); frame_buffer.unbind(); glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right crap::opengl::clear(crap::opengl::color_depth_buffer); sm.set_current("epr_vert", "epr_frag"); sm.activate(); /////////////////////////////////////// ////////////////////////////////////// projection_matrix = glm::perspective( display_field_of_view, display_ratio_horizontal / display_ratio_vertical, display_range_near, display_range_far); view_matrix = cam.view(); model_view_matrix = view_matrix * world_matrix; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix; glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasMVP = biasMatrix*depthMVP; sm.current()->uniform_matrix4f_value( ShadowDepthBiasMVPID, 1, &depthBiasMVP[0][0]); sm.current()->uniform_1i(ShadowMappingOnID, shadow_mapping_on); //activate shader porgram and connect data //sm.activate(); //default stuff sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix[0][0]); sm.current()->uniform_matrix4f_value( ViewMatrixID, 1, &view_matrix[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //light sm.activate(); sm.current()->uniform_1f(LightAmbientPowerID, light_ambient_power); sm.current()->uniform_1i(LightSelfShadowingOnID, light_self_shadowing_on); sm.current()->uniform_1i(LightNormalMappingOnID, light_normal_mapping_on); sm.current()->uniform_1f_value( LightPowerArrayID, 3, light_power_array ); sm.current()->uniform_1i_value( LightSpecularTypeArrayID, 3, light_specular_type_array ); sm.current()->uniform_1f_value( LightSpecularLobeArrayID, 3, light_specular_lobe_array ); sm.current()->uniform_3f_value( LightColorArrayID, 3, (f32*)light_color_array ); sm.current()->uniform_3f_value( LightPositionArrayID, 3, (f32*)light_position_array ); sm.current()->uniform_3f_value( LightDirectionArrayID, 3, (f32*)light_direction_array ); sm.current()->uniform_1i_value( LightTypeArrayID, 3, light_type_array ); sm.current()->uniform_1i_value( LightStateArrayID, 3, light_state_array ); //displacement sm.current()->uniform_1i( DisplacementOnID, displacement_on ); sm.current()->uniform_1f( DisplacementStepsID, displacement_steps); sm.current()->uniform_1f( DisplacementRefinementStepsID, displacement_refinement_steps); sm.current()->uniform_1f( DisplacementUVFactorID, displacmenet_uv_factor); //activate texture buffer and connect data diffuse_tbo.activate(); diffuse_tbo.bind_buffer(); sm.current()->uniform_1i( DiffuseTextureID, 0); normal_tbo.activate(); normal_tbo.bind_buffer(); sm.current()->uniform_1i( NormalTextureID, 1); height_tbo.activate(); height_tbo.bind_buffer(); sm.current()->uniform_1i( HeightTextureID, 2 ); depthmap.activate(); depthmap.bind_buffer(); sm.current()->uniform_1i( ShadowMapID, 4); //define data of buffers sm.current()->vertex_attribute_array.enable(0); //cube_vbo.bind_buffer( vbo::verticies ); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); //cube_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); //cube_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer); //cube_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer( 3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer); //cube_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); ////draw the f**k cube_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); //next object glm::mat4 model_matrix_2 = model_matrix * glm::translate(3.f,0.f,0.f); model_view_matrix = view_matrix * model_matrix_2; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix_2; //activate shader porgram and connect data //sm.activate(); sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_2[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //attempt //define data of buffers sm.current()->vertex_attribute_array.enable(0); ape_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); ape_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); ape_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); ape_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); ape_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); //draw the f**k ape_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode ape_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); //disable data define stuff sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); //next object glm::mat4 model_matrix_3 = model_matrix * glm::translate(0.f,-2.f,0.f); model_view_matrix = view_matrix * model_matrix_2; model_view_matrix3x3 = glm::mat3(model_view_matrix); world_matrix = projection_matrix * view_matrix * model_matrix_3; //activate shader porgram and connect data //sm.activate(); sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]); sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_3[0][0]); sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]); //attempt //define data of buffers sm.current()->vertex_attribute_array.enable(0); cube_big_vbo.bind_buffer( vbo::verticies ); sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(1); cube_big_vbo.bind_buffer( vbo::uvs ); sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(2); cube_big_vbo.bind_buffer( vbo::normals ); sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(3); cube_big_vbo.bind_buffer( vbo::tangents ); sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0); sm.current()->vertex_attribute_array.enable(4); cube_big_vbo.bind_buffer( vbo::binormals ); sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0); //draw the f**k cube_big_vbo.bind_buffer( vbo::indicies ); crap::opengl::draw_elements( crap::opengl::triangles, // mode cube_big_vbo.indicies_size, // count crap::opengl::unsigned_short // type ); //disable data define stuff sm.current()->vertex_attribute_array.disable(0); sm.current()->vertex_attribute_array.disable(1); sm.current()->vertex_attribute_array.disable(2); sm.current()->vertex_attribute_array.disable(3); sm.current()->vertex_attribute_array.disable(4); glMatrixMode(GL_PROJECTION); glLoadMatrixf((const GLfloat*)&projection_matrix[0]); glMatrixMode(GL_MODELVIEW); glm::mat4 MV = view_matrix * model_matrix; glLoadMatrixf((const GLfloat*)&MV[0]); sm.activate(); // normals glColor3f(0,0,1); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.normals[ig.indices[i]].x, ig.normals[ig.indices[i]].y, ig.normals[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); // tangents glColor3f(1,0,0); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.tangents[ig.indices[i]].x, ig.tangents[ig.indices[i]].y, ig.tangents[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); // bitangents glColor3f(0,1,0); glBegin(GL_LINES); for (unsigned int i=0; i<ig.indices_size; i++){ glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z ); glVertex3fv(&p.x); glm::vec3 o = glm::normalize( glm::vec3(ig.binormals[ig.indices[i]].x, ig.binormals[ig.indices[i]].y, ig.binormals[ig.indices[i]].z) ); p+=o*0.1f; glVertex3fv(&p.x); } glEnd(); glm::vec3 debug_light; // light pos 1 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[0]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // light pos 2 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[1]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // light pos3 glColor3f(1,1,1); glBegin(GL_LINES); debug_light = light_position_array[2]; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light-=glm::vec3(1,0,0)*0.1f; glVertex3fv(&debug_light.x); debug_light+=glm::vec3(0,1,0)*0.1f; glVertex3fv(&debug_light.x); glEnd(); // Draw GUI TwDraw(); //poll and swap window.swap(); window.poll_events(); } TwTerminate(); //geometry_content ig; //cm.create_content( "ape" , &ig, type_name::geometry ); //texture_content tc; //cm.create_content( "color", &tc, type_name::texture ); //shader_content sc; //cm.create_content( "fragment_texture_only", &sc, type_name::shader ); //cm.save_content( "fragment_texture_only", &sc, type_name::shader ); return 0; }