bool OpenGLRenderer::renderBoundingSphere(const BoundingSphere &sphere, const glm::vec3 ¢er, const glm::vec3 &color, Camera &camera, RenderTarget &renderTarget) { /* Calculate MVP matrix, bounding box coordinates are already in world coordinates */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix(); /* Bind the render target */ renderTarget.bind(); { GLuint boxPosVAO, boxPosVBO; __(glEnable(GL_DEPTH_TEST)); //__(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); //__(glEnable(GL_CULL_FACE)); /* Bind program to upload the uniform */ _renderBoundingSphere.attach(); /* Send our transformation to the currently bound _renderBoundingSpheres, in the "MVP" uniform */ _renderBoundingSphere.setUniformMat4("u_MVPMatrix", &MVP); _renderBoundingSphere.setUniformMat4("u_projectionMatrix", &camera.getPerspectiveMatrix()); _renderBoundingSphere.setUniformVec3("u_boxColor", const_cast<glm::vec3 &>(color)); _renderBoundingSphere.setUniformFloat("u_radius", sphere.getRadius()); __(glGenVertexArrays(1, &boxPosVAO)); __(glBindVertexArray(boxPosVAO)); __(glGenBuffers(1, &boxPosVBO)); __(glBindBuffer(GL_ARRAY_BUFFER, boxPosVBO)); __(glBufferData(GL_ARRAY_BUFFER, sizeof center, ¢er[0], GL_STATIC_DRAW)); __(glEnableVertexAttribArray(0)); __(glVertexAttribPointer(0, // attribute. No particular reason for 0, but must match the layout in the _renderBoundingSpheres. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *)0 // array buffer offset )); __(glDrawArrays(GL_POINTS, 0, 1)); __(glBindVertexArray(0)); __(glDeleteBuffers(1, &boxPosVBO)); __(glDeleteVertexArrays(1, &boxPosVAO)); /* Unbind */ _renderBoundingSphere.detach(); } renderTarget.unbind(); return true; }
bool OpenGLRenderer::renderModel3DWireframe(Model3D &model3D, const glm::vec4 &color, Camera &camera, RenderTarget &renderTarget) { __(glDepthRangef(camera.getNear(), camera.getFar())); /* Enable wireframe mode */ __(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); __(glEnable(GL_LINE_SMOOTH)); __(glDisable(GL_CULL_FACE)); /* Calculate MVP matrix */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix() * model3D.getModelMatrix(); /* Cast the model into an internal type */ OpenGLAsset3D *glObject = static_cast<OpenGLAsset3D *>(model3D.getAsset3D()); /* Set the color for the wireframe shader */ _wireframeShader->setColor(color); /* Bind the render target */ renderTarget.bind(); { __(glEnable(GL_MULTISAMPLE)); __(glEnable(GL_DEPTH_TEST)); __(glDepthFunc(GL_LEQUAL)); __(glBlendEquation(GL_FUNC_ADD)); __(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); __(glEnable(GL_BLEND)); /* Bind program to upload the uniform */ _wireframeShader->attach(); /* Send our transformation to the currently bound shader, in the "MVP" uniform */ _wireframeShader->setUniformMat4("u_MVPMatrix", &MVP); /* Set the shader custom parameters */ _wireframeShader->setCustomParams(); /* Draw the model */ __(glBindVertexArray(glObject->getVertexArrayID())); { std::vector<uint32_t> offset = glObject->getIndicesOffsets(); std::vector<uint32_t> count = glObject->getIndicesCount(); for (size_t i = 0; i < offset.size(); ++i) { __(glDrawElements(GL_TRIANGLES, count[i], GL_UNSIGNED_INT, (void *)(offset[i] * sizeof(GLuint)))); } } __(glBindVertexArray(0)); /* Unbind */ _wireframeShader->detach(); } renderTarget.unbind(); return true; }
bool OpenGLRenderer::renderLight(Light &light, Camera &camera, RenderTarget &renderTarget, uint32_t lightNumber) { glm::vec3 ambient = (light.getAmbient() + light.getDiffuse() + light.getSpecular()) / 3.0f; /* Calculate MVP matrix */ glm::mat4 MV = camera.getViewMatrix() * light.getModelMatrix(); glm::mat4 P = camera.getPerspectiveMatrix(); /* Bind the render target */ renderTarget.bind(); { __(glEnable(GL_DEPTH_TEST)); __(glBlendEquation(GL_FUNC_ADD)); __(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); __(glEnable(GL_BLEND)); __(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); GLuint lightPosVAO, lightPosVBO; /* Bind program to upload the uniform */ _renderLightShader.attach(); /* Send our transformation to the currently bound shader, in the "MVP" uniform */ _renderLightShader.setUniformMat4("u_MVMatrix", &MV); _renderLightShader.setUniformMat4("u_PMatrix", &P); _renderLightShader.setUniformVec3("u_lightColor", ambient); _renderLightShader.setUniformUint("u_lightNumber", lightNumber); __(glGenVertexArrays(1, &lightPosVAO)); __(glBindVertexArray(lightPosVAO)); __(glGenBuffers(1, &lightPosVBO)); __(glBindBuffer(GL_ARRAY_BUFFER, lightPosVBO)); __(glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3), &light.getPosition()[0], GL_STATIC_DRAW)); __(glEnable(GL_PROGRAM_POINT_SIZE)); __(glDrawArrays(GL_POINTS, 0, 1)); __(glDisable(GL_PROGRAM_POINT_SIZE)); __(glBindVertexArray(0)); __(glDeleteBuffers(1, &lightPosVBO)); __(glDeleteVertexArrays(1, &lightPosVAO)); /* Unbind */ _renderLightShader.detach(); } renderTarget.unbind(); return true; }
bool OpenGLRenderer::renderModelNormals(Model3D &model3D, Camera &camera, RenderTarget &renderTarget, float normalSize) { /* Calculate MVP matrix */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix() * model3D.getModelMatrix(); /* Calculate normal matrix */ glm::mat3 normalMatrix = glm::transpose(glm::inverse(glm::mat3(model3D.getModelMatrix()))); /* Cast the model into an internal type */ OpenGLAsset3D *glObject = static_cast<OpenGLAsset3D *>(model3D.getAsset3D()); /* Bind the render target */ renderTarget.bind(); { /* Bind program to upload the uniform */ _renderNormals.attach(); _renderNormals.setUniformMat4("u_MVPMatrix", &MVP); _renderNormals.setUniformFloat("u_normalSize", normalSize); /* Draw the model */ __(glBindVertexArray(glObject->getVertexArrayID())); { std::vector<uint32_t> offset = glObject->getIndicesOffsets(); std::vector<uint32_t> count = glObject->getIndicesCount(); for (size_t i = 0; i < offset.size(); ++i) { __(glDrawElements(GL_TRIANGLES, count[i], GL_UNSIGNED_INT, (void *)(offset[i] * sizeof(GLuint)))); } } __(glBindVertexArray(0)); /* Unbind */ _renderNormals.detach(); } renderTarget.unbind(); return true; }
void RenderTarget::push(RenderTarget &f) { _renderTargets.push(&f); f.bind(); }
void GameScreen::shadow_render_pass(bool ovr, long time) { RenderTarget *rtarg; if (ovr){ rtarg = &game::engine::ovr_manager.get_ovr_render_target(); } else{ rtarg = &game::engine::rtarg; } game::engine::rndr_pass_type = RNDR_PASS_SHADOW; Matrix4x4 orig_proj = get_projection_matrix(); Matrix4x4 orig_view = get_view_matrix(); Vector3 l_pos = Vector3(500, 500, -500); Vector3 l_target = -l_pos; glCullFace(GL_FRONT); rtarg->bind(RT_SHADOW); glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Matrix4x4 l_proj; l_proj.set_perspective(DEG_TO_RAD(6.0), 1.0, 600, 890); set_projection_matrix(l_proj); glViewport(0, 0, game::engine::rtarg.get_shad_tex_width(), game::engine::rtarg.get_shad_tex_height()); Matrix4x4 l_view; l_view.set_lookat(l_pos, l_target, Vector3(0, 1, 0)); set_view_matrix(l_view); shad_mat.reset_identity(); shad_mat = l_proj * l_view; glColorMask(0, 0, 0, 0); game::engine::current_sdr = game::engine::depth_pass_sdr; game::engine::active_stage->render(STAGE_RENDER_ENEMIES, time); glColorMask(1, 1, 1, 1); rtarg->unbind(); /*2nd shadow pass*/ game::engine::rtarg2.bind(RT_SHADOW); glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); l_proj.reset_identity(); l_proj.set_perspective(DEG_TO_RAD(0.4), 1.0, 600, 890); set_projection_matrix(l_proj); glViewport(0, 0, game::engine::rtarg2.get_shad_tex_width(), game::engine::rtarg2.get_shad_tex_height()); l_view.reset_identity(); l_view.set_lookat(l_pos, l_target, Vector3(0, 1, 0)); set_view_matrix(l_view); shad_mat2.reset_identity(); shad_mat2 = l_proj * l_view; glColorMask(0, 0, 0, 0); game::engine::active_stage->render(STAGE_RENDER_GUNS | STAGE_RENDER_COCKPIT, time); glColorMask(1, 1, 1, 1); game::engine::rtarg2.unbind(); /*------------------------------------------------------------*/ set_projection_matrix(orig_proj); set_view_matrix(orig_view); glViewport(0, 0, game::engine::rtarg.get_fb_width(), game::engine::rtarg.get_fb_height()); glCullFace(GL_BACK); }
bool ParticleLiquidDrawStage::stepSimulation() throw(SimulatorException) { URE_INSTANCE->getSimulator(VISUAL_SIM_DOMAIN)->toLightingSimulator()->getMainCamera() ->setGLViewPort( Vector2Di(0,0), Vector2Di(WindowManager::getInstance().getWindowResolution()) ); // if(! mRenderToScreen) // { // //render to FBO // mUsedRenderTarget->bind(); // RenderTarget::setEnableDepthTest(true); // mUsedRenderTarget->attachStoredColorTexture(FINAL_RENDERING_SEMANTICS,0); // mUsedRenderTarget->renderToAttachedTextures(); // } //TODO continue //ensure that render target is unbound so that it's not used on accident by following stages RenderTarget::renderToScreen(); //TODO maybe clear srceen? should actualle be done by dimulator at the beginning... //-------------------------------------------------- //TEST: just render the result from previous stage as texture show to test the render target stuff //enable the texture show shader with the respective texture bound RenderTarget* rt = dynamic_cast<LightingSimStageBase*>( URE_INSTANCE->getSimulator(VISUAL_SIM_DOMAIN) ->getStage("DefaultLightingStage"))->getUsedRenderTarget(); assert(rt); Texture* renderingOfDefaultLightingStage = dynamic_cast<Texture*>( URE_INSTANCE->getSimulator(VISUAL_SIM_DOMAIN) ->getStage("DefaultLightingStage")->getRenderingResult(FINAL_RENDERING_SEMANTICS) ); assert("The DefaultLightingStage must expose a Texture with final rendering semantics! " && renderingOfDefaultLightingStage); //render to FBO rt->bind(); rt->detachAllColorTextures(); //free from previous stage's relicts rt->attachColorTexture(mCompositedRendering,0); //attach own texture RenderTarget::setEnableDepthTest(true); rt->attachStoredDepthBuffer(); rt->renderToAttachedTextures(); //haxx: just copy the texture to have both an image to sample from //and to amend by direct fluid rendering mTextureShowShader->use(renderingOfDefaultLightingStage); WindowManager::getInstance().drawFullScreenQuad(); RenderTarget::setEnableDepthTest(true); //now, render fluid onto the just copied texture; //again: this hack is needed to have a consistent depth buffer! int numCurrentFluids = dynamic_cast<ParticleMechanicsStage*>( URE_INSTANCE->getSimulator(MECHANICAL_SIM_DOMAIN) ->getStage("ParticleMechanicsStage") )->getParticleSceneRepresentation() ->getNumCurrentFluids(); for(int i=0; i< numCurrentFluids; i++) { ParticleFluid* fluid = dynamic_cast<ParticleMechanicsStage*>( URE_INSTANCE->getSimulator(MECHANICAL_SIM_DOMAIN) ->getStage("ParticleMechanicsStage") )->getParticleSceneRepresentation() ->getFluid(i); assert( ! fluid->getSubObjects(VISUAL_SIM_DOMAIN).empty()); SubObject* so = fluid->getSubObjects(VISUAL_SIM_DOMAIN)[0]; ParticleLiquidVisualMaterial* mat = dynamic_cast<ParticleLiquidVisualMaterial*>(so->getMaterial()); assert(mat); RenderTarget::setEnableDepthTest(true); mat->mCompositionShader->use(so); so->getGeometry()->draw(); //draw fullscreenquad //WindowManager::getInstance().drawFullScreenQuad(); } //now, just show the result rendered into the FBO //damn, so many useless copies, but time pressure is forcing me to do so... RenderTarget::renderToScreen(); mTextureShowShader->use(mCompositedRendering); WindowManager::getInstance().drawFullScreenQuad(); //------------------- return true; }
void WViewport::draw(const ClipRect &rect) { if (get(ix::source) == Null) { //Use camera and scene Camera *cam = camera(); Scene *sc = scene(); if (cam == 0 || sc == 0) return; if (Extensions::hasColourClamp()) { WGDglClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE); WGDglClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE); } vector2d pos = screenPosition(); int w = width(); int h = height(); int wh = wgd::window->height() - h; //clip window ClipRect r; r.top = (int)pos.y; r.left = (int)pos.x; r.right = r.left + w; r.bottom = r.top + h; clip(rect, r); cam->size(w, h); //glScissor((int)pos.x,wh-(int)pos.y,w,h); glViewport((int)pos.x,wh-(int)pos.y,w,h); glEnable(GL_DEPTH_TEST); glDepthMask(1); cam->bind(); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glShadeModel(GL_SMOOTH); glDisable(GL_TEXTURE_2D); //glEnable(GL_BLEND); float poss[] = {0.0, 1.0f, 1.0f, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, poss); float amb[] = {0.3f, 0.3f, 0.3f, 1.0f}; glLightfv(GL_LIGHT0, GL_AMBIENT, amb); float diff[] = {1.0f, 1.0f, 1.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_DIFFUSE, diff); float spec[] = {0.5f, 0.5f, 0.5f, 1.0f}; glLightfv(GL_LIGHT0, GL_SPECULAR, spec); //clear colour - would be cool to do some stencil stuff so we can draw to an arbitrary shape if(get("clear")!=Null) { colour c = get("clear"); if(c.a > 0.0f) { glClearColor(c.r, c.g, c.b, c.a); glClear(GL_COLOR_BUFFER_BIT); } } sc->draw(cam); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); cam->unbind(); if (Extensions::hasColourClamp()) { WGDglClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_TRUE); WGDglClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FIXED_ONLY_ARB); } glDepthMask(0); glDisable(GL_DEPTH_TEST); glViewport(0,0,wgd::window->width(),wgd::window->height()); } else { RenderTarget *src = source(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); src->draw(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); vector2d pos = screenPosition(); int w = width(); int h = height(); int wh = wgd::window->height() - h; glScissor((int)pos.x,wh-(int)pos.y,w,h); glViewport((int)pos.x,wh-(int)pos.y,w,h); glMatrixMode(GL_PROJECTION); glPushMatrix(); // Store The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix glOrtho(0,w,0,h,-1,1); // Set Up An Ortho Screen glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Store The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix //Reset raster position glRasterPos2f(0.0,0.0); glTranslatef(0.0, 0.0, -1.0); //glEnable(GL_DEPTH_TEST); //glDepthMask(1); //Use rendertarget. src->bind(); glColor4f(1.0,1.0,1.0,1.0); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f((float)w, 0.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f((float)w, (float)h, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, (float)h, 0.0); glEnd(); src->unbind(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glViewport(0,0,wgd::window->width(),wgd::window->height()); } drawChildren(rect); }
void RenderTarget::draw() { if (get(ix::source) == Null) { //Use camera and scene Camera *cam = camera(); Scene *sc = scene(); if (cam == 0 || sc == 0) return; //glEnable(GL_TEXTURE_2D); begin(); if (clear()) doclear(); if (Extensions::hasColourClamp()) { WGDglClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE); WGDglClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE); } //glViewport(0,m_height,m_width,m_height); cam->size(m_width, m_height); glEnable(GL_DEPTH_TEST); glDepthMask(1); cam->bind(); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glShadeModel(GL_SMOOTH); glDisable(GL_TEXTURE_2D); //glEnable(GL_BLEND); float poss[] = {0.0f,0.0f,0.0f,1.0f}; glLightfv(GL_LIGHT0, GL_POSITION, poss); float amb[] = {0.2f,0.2f,0.2f, 1.0f}; glLightfv(GL_LIGHT0, GL_AMBIENT, amb); float diff[] = {1.0f,1.0f,1.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_DIFFUSE, diff); float spec[] = {1.0f,1.0f,1.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_SPECULAR, spec); sc->draw(cam); //glDisable(GL_BLEND); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); cam->unbind(); glDepthMask(0); glDisable(GL_DEPTH_TEST); if (Extensions::hasColourClamp()) { WGDglClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_TRUE); WGDglClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FIXED_ONLY_ARB); } end(); } else { //glEnable(GL_DEPTH_TEST); //glDepthMask(1); //Use rendertarget. RenderTarget *src = source(); Material *mat = material(); src->draw(); begin(); if (clear()) doclear(); src->bind(); if (mat) mat->bind(); glColor4f(1.0,1.0,1.0,1.0); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2i(-1, -1); glTexCoord2f(1.0, 0.0); glVertex2i(1, -1); glTexCoord2f(1.0, 1.0); glVertex2i(1, 1); glTexCoord2f(0.0, 1.0); glVertex2i(-1, 1); glEnd(); if (mat) mat->unbind(); src->unbind(); //glDepthMask(0); //glDisable(GL_DEPTH_TEST); end(); } }
bool OpenGLRenderer::renderBoundingBox(const BoundingBox &box, const glm::mat4 &modelMatrix, const glm::vec3 &color, Camera &camera, RenderTarget &renderTarget) { /* Generate the box lines */ GLfloat boxFaces[] = { /* First face */ box.getMin().x, box.getMin().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMin().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMin().z, /*--*/ box.getMin().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMin().y, box.getMax().z, box.getMax().x, box.getMin().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMax().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMax().x, box.getMax().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMin().z, }; /* Calculate MVP matrix, bounding box coordinates are already in world coordinates */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix() * modelMatrix; __(glEnable(GL_DEPTH_TEST)); /* Bind the render target */ renderTarget.bind(); { GLuint boxPosVAO, boxPosVBO; /* Bind program to upload the uniform */ _renderBoundingBox.attach(); /* Send our transformation to the currently bound _renderBoundingBox, in the "MVP" uniform */ _renderBoundingBox.setUniformMat4("u_MVPMatrix", &MVP); _renderBoundingBox.setUniformVec3("u_boxColor", const_cast<glm::vec3 &>(color)); __(glGenVertexArrays(1, &boxPosVAO)); __(glBindVertexArray(boxPosVAO)); __(glGenBuffers(1, &boxPosVBO)); __(glBindBuffer(GL_ARRAY_BUFFER, boxPosVBO)); __(glBufferData(GL_ARRAY_BUFFER, sizeof boxFaces, boxFaces, GL_STATIC_DRAW)); __(glEnableVertexAttribArray(0)); __(glVertexAttribPointer(0, // attribute. 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 )); __(glDrawArrays(GL_LINES, 0, sizeof boxFaces / (2 * sizeof *boxFaces))); __(glBindVertexArray(0)); __(glDeleteBuffers(1, &boxPosVBO)); __(glDeleteVertexArrays(1, &boxPosVAO)); /* Unbind */ _renderBoundingBox.detach(); } renderTarget.unbind(); return true; }
bool OpenGLRenderer::renderModel3D(Model3D &model3D, Camera &camera, LightingShader &shader, DirectLight *sun, std::vector<PointLight *> &pointLights, std::vector<SpotLight *> &spotLights, float ambientK, RenderTarget &renderTarget, bool disableDepth) { 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); GLuint textureUnit = 0; GLuint dummyTextureUnit = 0; __(glDepthRangef(camera.getNear(), camera.getFar())); /* Calculate MVP matrix */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix() * model3D.getModelMatrix(); /* Calculate normal matrix */ glm::mat3 normalMatrix = glm::transpose(glm::inverse(glm::mat3(model3D.getModelMatrix()))); /* Cast the model into an internal type */ OpenGLAsset3D *glObject = static_cast<OpenGLAsset3D *>(model3D.getAsset3D()); /* TODO: is this even used????? below we enable it always :P */ if (disableDepth) { glDisable(GL_DEPTH_TEST); } else { glEnable(GL_DEPTH_TEST); } if (getWireframeMode() == Renderer::RENDER_WIREFRAME_ONLY) { __(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); __(glEnable(GL_LINE_SMOOTH)); __(glDisable(GL_CULL_FACE)); } else { __(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); __(glDisable(GL_LINE_SMOOTH)); __(glEnable(GL_CULL_FACE)); } /* Bind the render target */ renderTarget.bind(); { __(glEnable(GL_MULTISAMPLE)); __(glEnable(GL_DEPTH_TEST)); __(glBlendEquation(GL_FUNC_ADD)); __(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); __(glEnable(GL_BLEND)); /* Bind program to upload the uniform */ shader.attach(); /* Send our transformation to the currently bound shader, in the "MVP" uniform */ shader.setUniformMat4("u_MVPMatrix", &MVP); shader.setUniformMat4("u_viewMatrix", &camera.getViewMatrix()); shader.setUniformMat4("u_modelMatrix", &model3D.getModelMatrix()); shader.setUniformMat3("u_normalMatrix", &normalMatrix); shader.setUniformTexture2D("u_diffuseMap", textureUnit++); shader.setUniformFloat("u_ambientK", ambientK); /* Activate and bind unit 0 for the dummy texture */ dummyTextureUnit = textureUnit++; __(glActiveTexture(GL_TEXTURE0 + dummyTextureUnit)); __(glBindTexture(GL_TEXTURE_2D, _dummyTexture)); /* Set the sun light */ if (sun != NULL) { glm::mat4 shadowMVP = sun->getProjectionMatrix() * sun->getViewMatrix() * model3D.getModelMatrix(); shadowMVP = biasMatrix * shadowMVP; shader.setDirectLight(*sun); shader.setUniformUint("u_numDirectLights", 1); /* TODO: This has to be set in a matrix array */ shader.setUniformMat4("u_shadowMVPDirectLight", &shadowMVP); shader.setUniformTexture2D("u_shadowMapDirectLight", textureUnit); __(glActiveTexture(GL_TEXTURE0 + textureUnit)); if (model3D.isShadowReceiver()) { sun->getShadowMap()->bindDepth(); } else { __(glBindTexture(GL_TEXTURE_2D, _noshadowTexture)); } textureUnit++; } else { shader.setUniformUint("u_numDirectLights", 0); shader.setUniformTexture2D("u_shadowMapDirectLight", dummyTextureUnit); } /* Point lights */ glm::mat4 *shadowMVPArray = new glm::mat4[pointLights.size()]; GLuint texturesArray[OpenGLLightingShader::MAX_LIGHTS]; for (uint32_t numLight = 0; numLight < pointLights.size(); ++numLight) { shader.setPointLight(numLight, *pointLights[numLight]); /* Calculate adjusted shadow map matrix */ glm::mat4 shadowMVP = pointLights[numLight]->getProjectionMatrix() * pointLights[numLight]->getViewMatrix() * model3D.getModelMatrix(); shadowMVPArray[numLight] = biasMatrix * shadowMVP; texturesArray[numLight] = textureUnit; __(glActiveTexture(GL_TEXTURE0 + textureUnit)); if (model3D.isShadowReceiver()) { pointLights[numLight]->getShadowMap()->bindDepth(); } else { __(glBindTexture(GL_TEXTURE_2D, _noshadowTexture)); } textureUnit++; } for (uint32_t numLight = pointLights.size(); numLight < OpenGLLightingShader::MAX_LIGHTS; ++numLight) { texturesArray[numLight] = dummyTextureUnit; } shader.setUniformMat4("u_shadowMVPPointLight[0]", shadowMVPArray, pointLights.size()); shader.setUniformTexture2DArray("u_shadowMapPointLight[0]", texturesArray, OpenGLLightingShader::MAX_LIGHTS); shader.setUniformUint("u_numPointLights", pointLights.size()); /* Free the resources */ delete[] shadowMVPArray; /* Spotlights */ shadowMVPArray = new glm::mat4[spotLights.size()]; for (uint32_t numLight = 0; numLight < spotLights.size(); ++numLight) { shader.setSpotLight(numLight, *spotLights[numLight]); /* Calculate adjusted shadow map matrix */ glm::mat4 shadowMVP = spotLights[numLight]->getProjectionMatrix() * spotLights[numLight]->getViewMatrix() * model3D.getModelMatrix(); shadowMVPArray[numLight] = biasMatrix * shadowMVP; texturesArray[numLight] = textureUnit; __(glActiveTexture(GL_TEXTURE0 + textureUnit)); if (model3D.isShadowReceiver()) { spotLights[numLight]->getShadowMap()->bindDepth(); } else { __(glBindTexture(GL_TEXTURE_2D, _noshadowTexture)); } textureUnit++; } for (uint32_t numLight = spotLights.size(); numLight < OpenGLLightingShader::MAX_LIGHTS; ++numLight) { texturesArray[numLight] = dummyTextureUnit; } shader.setUniformMat4("u_shadowMVPSpotLight[0]", shadowMVPArray, spotLights.size()); shader.setUniformTexture2DArray("u_shadowMapSpotLight[0]", texturesArray, OpenGLLightingShader::MAX_LIGHTS); shader.setUniformUint("u_numSpotLights", spotLights.size()); /* Free the resources */ delete[] shadowMVPArray; /* Set the shader custom parameters */ shader.setCustomParams(); /* Draw the model */ __(glBindVertexArray(glObject->getVertexArrayID())); { __(glActiveTexture(GL_TEXTURE0)); std::vector<Material> materials = glObject->getMaterials(); std::vector<uint32_t> texturesIDs = glObject->getTexturesIDs(); std::vector<uint32_t> offset = glObject->getIndicesOffsets(); std::vector<uint32_t> count = glObject->getIndicesCount(); for (size_t i = 0; i < materials.size(); ++i) { __(glBindTexture(GL_TEXTURE_2D, texturesIDs[i])); shader.setMaterial(materials[i]); __(glDrawElements(GL_TRIANGLES, count[i], GL_UNSIGNED_INT, (void *)(offset[i] * sizeof(GLuint)))); } } __(glBindVertexArray(0)); /* Unbind */ shader.detach(); } renderTarget.unbind(); return true; }