void DirectionalLight::setLightProperties(const ProgramSP& program) const { glUniform1i(program->getUniformLocation(u_lightType), 0); glUniform4fv(program->getUniformLocation(u_ambientLightColor), 1, ambient.getRGBA()); glUniform4fv(program->getUniformLocation(u_diffuseLightColor), 1, diffuse.getRGBA()); glUniform4fv(program->getUniformLocation(u_specularLightColor), 1, specular.getRGBA()); glUniform3fv(program->getUniformLocation(u_lightDirection), 1, direction.getV()); }
SkyVAO::SkyVAO(const ProgramSP& program, const Sky& sky) : VAO(program) { generateVAO(); glBindBuffer(GL_ARRAY_BUFFER, sky.getVboVertices()); glVertexAttribPointer(program->getAttribLocation(a_vertex), 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(program->getAttribLocation(a_vertex)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sky.getVboIndices()); glEnableVertexAttribArray(0); unbind(); }
PostProcessorVAO::PostProcessorVAO(const ProgramSP& program, const PostProcessor& postProcessor) : VAO(program) { generateVAO(); glBindBuffer(GL_ARRAY_BUFFER, postProcessor.getVboVertices()); glVertexAttribPointer(program->getAttribLocation(a_vertex), 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(program->getAttribLocation(a_vertex)); glBindBuffer(GL_ARRAY_BUFFER, postProcessor.getVboTexCoords()); glVertexAttribPointer(program->getAttribLocation(a_texCoord), 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(program->getAttribLocation(a_texCoord)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, postProcessor.getVboIndices()); glEnableVertexAttribArray(0); unbind(); }
ProgramSP ProgramManager::getVertexFragmentProgramBy(const string& vertexFilename, const string& fragmentFilename, const string& type) const { multimap<string, ProgramSP>::const_iterator walker = allPrograms.begin(); ProgramSP currentProgram; while (walker != allPrograms.end()) { currentProgram = walker->second; if (currentProgram->getVertexFilename().compare(vertexFilename) == 0 && currentProgram->getFragmentFilename().compare(fragmentFilename) == 0) { return walker->second; } walker++; } currentProgram = ProgramSP(new Program(type, vertexFilename, fragmentFilename)); ProgramManager::getInstance()->addProgram(currentProgram); return currentProgram; }
void PointLight::setLightProperties(uint32_t lightNumber, const ProgramSP& program, const Point4& position, const Quaternion& rotation) const { glUniform1f(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_lightType), 1.0f); glUniform4fv(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_diffuseLightColor), 1, diffuse.getRGBA()); glUniform4fv(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_specularLightColor), 1, specular.getRGBA()); glUniform4fv(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_lightPosition), 1, position.getP()); glUniform1f(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_lightConstantAttenuation), constantAttenuation); glUniform1f(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_lightLinearAttenuation), linearAttenuation); glUniform1f(program->getUniformLocation(string(u_light) + to_string(lightNumber) + u_lightQuadraticAttenuation), quadraticAttenuation); }
ProgramSP ProgramManager::getProgramBy(const string& computeFilename) const { multimap<string, ProgramSP>::const_iterator walker = allPrograms.begin(); ProgramSP currentProgram; while (walker != allPrograms.end()) { currentProgram = walker->second; if (currentProgram->getComputeFilename().compare(computeFilename) == 0) { return walker->second; } walker++; } currentProgram = ProgramSP(new Program(ProgramManager::DEFAULT_PROGRAM_TYPE, computeFilename)); ProgramManager::getInstance()->addProgram(currentProgram); return currentProgram; }
ProgramSP ProgramManager::getProgramBy(const std::string& vertexFilename, const std::string& controlFilename, const std::string& evaluationFilename, const std::string& geometryFilename, const std::string& fragmentFilename) const { multimap<string, ProgramSP>::const_iterator walker = allPrograms.begin(); ProgramSP currentProgram; while (walker != allPrograms.end()) { currentProgram = walker->second; if (currentProgram->getVertexFilename().compare(vertexFilename) == 0 && currentProgram->getControlFilename().compare(controlFilename) == 0 && currentProgram->getEvaluationFilename().compare(evaluationFilename) == 0 && currentProgram->getGeometryFilename().compare(geometryFilename) == 0 && currentProgram->getFragmentFilename().compare(fragmentFilename) == 0) { return walker->second; } walker++; } currentProgram = ProgramSP(new Program(ProgramManager::DEFAULT_PROGRAM_TYPE, vertexFilename, fragmentFilename)); ProgramManager::getInstance()->addProgram(currentProgram); return currentProgram; }
void ProgramManager::removeProgram(const ProgramSP& program) { multimap<string, ProgramSP>::iterator walker = allPrograms.find(program->getType()); while (walker != allPrograms.end()) { if (walker->second == program) { allPrograms.erase(walker); return; } walker++; } }
void ProgramManager::addProgram(const ProgramSP& program) { allPrograms.insert(pair<string, ProgramSP>(program->getType(), program)); }
void ModelEntity::renderNode(const Node& node, const InstanceNode& instanceNode, float time, int32_t animStackIndex, int32_t animLayerIndex) const { enum RenderFilter renderFilter = Entity::getRenderFilter(); bool finalTransparent = (instanceNode.isTransparentActive() && instanceNode.isTransparent()) || (!instanceNode.isTransparentActive() && node.isTransparent()); bool renderMesh = (renderFilter == RENDER_ALL) || (finalTransparent && renderFilter == RENDER_TRANSPARENT) || (!finalTransparent && renderFilter == RENDER_OPAQUE); if (isDebug()) { if (node.getCamera().get()) { node.getCamera()->debugDraw(instanceNode.getPosition(), instanceNode.getRotation(), true); } if (node.getLight().get()) { node.getLight()->debugDraw(instanceNode.getPosition(), instanceNode.getRotation()); } } if (isWireframe()) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if (node.getMesh().get() && renderMesh) { VAOSP currentVAO; ProgramSP currentProgram; SubMeshSP currentSubMesh; SurfaceMaterialSP currentSurfaceMaterial; const std::vector<std::shared_ptr<AnimationStack> >& allAnimStacks = node.getAllAnimStacks(); for (uint32_t subMeshIndex = 0; subMeshIndex < node.getMesh()->getSubMeshesCount(); subMeshIndex++) { currentSubMesh = node.getMesh()->getSubMeshAt(subMeshIndex); if (subMeshIndex >= node.getMesh()->getSurfaceMaterialsCount()) { break; } currentSurfaceMaterial = node.getMesh()->getSurfaceMaterialAt(subMeshIndex); float currentEmissive[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentAmbient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentDiffuse[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentSpecular[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentReflection[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentRefraction[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float currentShininess = 0.0f; float currentTransparency = 0.0f; for (int32_t i = 0; i < 4; i++) { currentEmissive[i] = currentSurfaceMaterial->getEmissive().getRGBA()[i]; currentAmbient[i] = currentSurfaceMaterial->getAmbient().getRGBA()[i]; currentDiffuse[i] = currentSurfaceMaterial->getDiffuse().getRGBA()[i]; currentSpecular[i] = currentSurfaceMaterial->getSpecular().getRGBA()[i]; currentReflection[i] = currentSurfaceMaterial->getReflection().getRGBA()[i]; currentRefraction[i] = currentSurfaceMaterial->getRefraction().getRGBA()[i]; } currentShininess = currentSurfaceMaterial->getShininess(); currentTransparency = currentSurfaceMaterial->getTransparency(); if (animStackIndex >= 0 && animLayerIndex >= 0 && static_cast<decltype(allAnimStacks.size())>(animStackIndex) < allAnimStacks.size() && animLayerIndex < allAnimStacks[animStackIndex]->getAnimationLayersCount()) { // Animate values depending on time const AnimationLayerSP& animLayer = allAnimStacks[animStackIndex]->getAnimationLayer(animLayerIndex); for (enum AnimationLayer::eCHANNELS_RGBA i = AnimationLayer::R; i <= AnimationLayer::A; i = static_cast<enum AnimationLayer::eCHANNELS_RGBA>(i + 1)) { if (animLayer->hasEmissiveColorValue(i)) { currentEmissive[i] = animLayer->getEmissiveColorValue(i, time); } if (animLayer->hasAmbientColorValue(i)) { currentAmbient[i] = animLayer->getAmbientColorValue(i, time); } if (animLayer->hasDiffuseColorValue(i)) { currentDiffuse[i] = animLayer->getDiffuseColorValue(i, time); } if (animLayer->hasSpecularColorValue(i)) { currentSpecular[i] = animLayer->getSpecularColorValue(i, time); } if (animLayer->hasReflectionColorValue(i)) { currentReflection[i] = animLayer->getReflectionColorValue(i, time); } if (animLayer->hasRefractionColorValue(i)) { currentRefraction[i] = animLayer->getRefractionColorValue(i, time); } } if (animLayer->hasShininessValue(AnimationLayer::S)) { currentShininess = animLayer->getShininessValue(AnimationLayer::S, time); } if (animLayer->hasTransparencyValue(AnimationLayer::S)) { currentTransparency = animLayer->getTransparencyValue(AnimationLayer::S, time); } } currentVAO = currentSubMesh->getVAOByProgramType(getCurrentProgramType()); currentProgram = currentVAO->getProgram(); currentProgram->use(); glUniformMatrix4fv(currentProgram->getUniformLocation(u_modelMatrix), 1, GL_FALSE, instanceNode.getModelMatrix().getM()); // We have the inverse and transpose by setting the matrix glUniformMatrix3fv(currentProgram->getUniformLocation(u_normalModelMatrix), 1, GL_TRUE, instanceNode.getNormalModelMatrix().getM()); currentVAO->bind(); glUniform4fv(currentProgram->getUniformLocation(u_emissiveColor), 1, currentEmissive); glUniform4fv(currentProgram->getUniformLocation(u_ambientColor), 1, currentAmbient); if (currentSurfaceMaterial->getDiffuseTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasDiffuseTexture), 1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, currentSurfaceMaterial->getDiffuseTextureName()); glUniform1i(currentProgram->getUniformLocation(u_diffuseTexture), 0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasDiffuseTexture), 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_diffuseTexture), 0); } glUniform4fv(currentProgram->getUniformLocation(u_diffuseColor), 1, currentDiffuse); if (currentSurfaceMaterial->getSpecularTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasSpecularTexture), 1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, currentSurfaceMaterial->getSpecularTextureName()); glUniform1i(currentProgram->getUniformLocation(u_specularTexture), 1); } else { glUniform1i(currentProgram->getUniformLocation(u_hasSpecularTexture), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_specularTexture), 0); } glUniform4fv(currentProgram->getUniformLocation(u_specularColor), 1, currentSpecular); glUniform1f(currentProgram->getUniformLocation(u_shininess), currentShininess); glUniform1f(currentProgram->getUniformLocation(u_transparency), currentTransparency); if (currentSurfaceMaterial->getNormalMapTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasNormalMapTexture), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, currentSurfaceMaterial->getNormalMapTextureName()); glUniform1i(currentProgram->getUniformLocation(u_normalMapTexture), 2); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasNormalMapTexture), 0); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_normalMapTexture), 2); glActiveTexture(GL_TEXTURE0); } glUniform1i(currentProgram->getUniformLocation(u_convertDirectX), currentSurfaceMaterial->isConvertDirectX()); glUniform4fv(currentProgram->getUniformLocation(u_reflectionColor), 1, currentReflection); glUniform4fv(currentProgram->getUniformLocation(u_refractionColor), 1, currentRefraction); float environmentRefractiveIndex = refractiveIndex; if (environmentRefractiveIndex != RI_NOTHING) { float materialRefractiveIndex = currentSurfaceMaterial->getRefractiveIndex(); float eta = environmentRefractiveIndex / materialRefractiveIndex; float reflectanceNormalIncidence = ((environmentRefractiveIndex - materialRefractiveIndex) * (environmentRefractiveIndex - materialRefractiveIndex)) / ((environmentRefractiveIndex + materialRefractiveIndex) * (environmentRefractiveIndex + materialRefractiveIndex)); glUniform1f(currentProgram->getUniformLocation(u_eta), eta); glUniform1f(currentProgram->getUniformLocation(u_reflectanceNormalIncidence), reflectanceNormalIncidence); } else { glUniform1f(currentProgram->getUniformLocation(u_eta), 0.0f); glUniform1f(currentProgram->getUniformLocation(u_reflectanceNormalIncidence), 0.0f); } if (SkyManager::getInstance()->hasActiveSky()) { glUniform1i(currentProgram->getUniformLocation(u_hasCubeMapTexture), 1); SkySP activeSky = SkyManager::getInstance()->getActiveSky(); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, activeSky->getSkyTextureName()); glUniform1i(currentProgram->getUniformLocation(u_cubemap), 3); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasCubeMapTexture), 0); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glUniform1i(currentProgram->getUniformLocation(u_cubemap), 3); glActiveTexture(GL_TEXTURE0); } // Only allow dynamic cube map, if also a sky cube map is available if (Entity::getDynamicCubeMaps() && currentSurfaceMaterial->getDynamicCubeMapTextureName() != 0 && SkyManager::getInstance()->hasActiveSky()) { glUniform1i(currentProgram->getUniformLocation(u_hasDynamicCubeMapTexture), 1); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, currentSurfaceMaterial->getDynamicCubeMapTextureName()); glUniform1i(currentProgram->getUniformLocation(u_dynamicCubeMapTexture), 4); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasDynamicCubeMapTexture), 0); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glUniform1i(currentProgram->getUniformLocation(u_dynamicCubeMapTexture), 4); glActiveTexture(GL_TEXTURE0); } if (!Entity::getDynamicCubeMaps()) { glUniformMatrix4fv(currentProgram->getUniformLocation(u_cubeMapViewMatrix), 6, GL_FALSE, Entity::getCubeMapViewMatrices()[0].getM()); glUniformMatrix4fv(currentProgram->getUniformLocation(u_cubeMapProjectionMatrix), 1, GL_FALSE, Entity::getCubeMapProjectionMatrix().getM()); } // Skinning if (node.getMesh()->hasSkinning()) { glUniform1i(currentProgram->getUniformLocation(u_hasSkinning), 1); glUniformMatrix4fv(currentProgram->getUniformLocation(u_bindMatrix), model->getNumberJoints(), GL_FALSE, bindMatrices[0].getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_bindNormalMatrix), model->getNumberJoints(), GL_TRUE, bindNormalMatrices[0].getM()); glUniformMatrix4fv(currentProgram->getUniformLocation(u_inverseBindMatrix), model->getNumberJoints(), GL_FALSE, inverseBindMatrices[0].getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_inverseBindNormalMatrix), model->getNumberJoints(), GL_TRUE, inverseBindNormalMatrices[0].getM()); } else { glUniform1i(currentProgram->getUniformLocation(u_hasSkinning), 0); glUniformMatrix4fv(currentProgram->getUniformLocation(u_bindMatrix), model->getNumberJoints(), GL_FALSE, Matrix4x4().getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_bindNormalMatrix), model->getNumberJoints(), GL_TRUE, Matrix3x3().getM()); glUniformMatrix4fv(currentProgram->getUniformLocation(u_inverseBindMatrix), model->getNumberJoints(), GL_FALSE, Matrix4x4().getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_inverseBindNormalMatrix), model->getNumberJoints(), GL_TRUE, Matrix3x3().getM()); } // Write bright color glUniform1i(currentProgram->getUniformLocation(u_writeBrightColor), writeBrightColor); glUniform1f(currentProgram->getUniformLocation(u_brightColorLimit), brightColorLimit); if (finalTransparent) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glDrawElements(GL_TRIANGLES, currentSubMesh->getTriangleCount() * 3, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(currentSubMesh->getIndicesOffset() * sizeof(uint32_t))); if (finalTransparent) { glDisable(GL_BLEND); } if (currentSurfaceMaterial->getDiffuseTextureName() != 0) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); } if (currentSurfaceMaterial->getSpecularTextureName() != 0) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); } if (currentSurfaceMaterial->getNormalMapTextureName() != 0) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0); } if (SkyManager::getInstance()->hasActiveSky()) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } if (currentSurfaceMaterial->getDynamicCubeMapTexture() != 0) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } glActiveTexture(GL_TEXTURE0); currentVAO->unbind(); } } if (isWireframe()) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } }
void GroundEntity::render() const { if (isWireframe()) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } GroundVAOSP currentVAO = ground->getVAOByProgramType(GeneralEntity::currentProgramType); ProgramSP currentProgram = currentVAO->getProgram(); // We process triangle patches glPatchParameteri(GL_PATCH_VERTICES, 3); currentProgram->use(); currentVAO->bind(); glUniformMatrix4fv(currentProgram->getUniformLocation(u_modelMatrix), 1, GL_FALSE, getModelMatrix().getM()); // We have the inverse and transpose by setting the matrix glUniformMatrix3fv(currentProgram->getUniformLocation(u_normalModelMatrix), 1, GL_TRUE, getNormalModelMatrix().getM()); glUniform4fv(currentProgram->getUniformLocation(u_emissiveColor), 1, surfaceMaterial->getEmissive().getRGBA()); glUniform4fv(currentProgram->getUniformLocation(u_ambientColor), 1, surfaceMaterial->getAmbient().getRGBA()); if (surfaceMaterial->getDiffuseTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasDiffuseTexture), 1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, surfaceMaterial->getDiffuseTextureName()); glUniform1i(currentProgram->getUniformLocation(u_diffuseTexture), 0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasDiffuseTexture), 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_diffuseTexture), 0); } glUniform4fv(currentProgram->getUniformLocation(u_diffuseColor), 1, surfaceMaterial->getDiffuse().getRGBA()); if (surfaceMaterial->getSpecularTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasSpecularTexture), 1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, surfaceMaterial->getSpecularTextureName()); glUniform1i(currentProgram->getUniformLocation(u_specularTexture), 1); } else { glUniform1i(currentProgram->getUniformLocation(u_hasSpecularTexture), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_specularTexture), 0); } glUniform4fv(currentProgram->getUniformLocation(u_specularColor), 1, surfaceMaterial->getSpecular().getRGBA()); glUniform1f(currentProgram->getUniformLocation(u_shininess), surfaceMaterial->getShininess()); glUniform1f(currentProgram->getUniformLocation(u_transparency), surfaceMaterial->getTransparency()); if (surfaceMaterial->getDisplacementMapTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasNormalMapTexture), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, surfaceMaterial->getDisplacementMapTextureName()); glUniform1i(currentProgram->getUniformLocation(u_normalMapTexture), 2); glActiveTexture(GL_TEXTURE0); } else if (surfaceMaterial->getNormalMapTextureName() != 0) { glUniform1i(currentProgram->getUniformLocation(u_hasNormalMapTexture), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, surfaceMaterial->getNormalMapTextureName()); glUniform1i(currentProgram->getUniformLocation(u_normalMapTexture), 2); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasNormalMapTexture), 0); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0); glUniform1i(currentProgram->getUniformLocation(u_normalMapTexture), 2); glActiveTexture(GL_TEXTURE0); } // glUniform1f(currentProgram->getUniformLocation(u_repeat), repeat); glUniform1f(currentProgram->getUniformLocation(u_screenDistance), screenDistance); glUniform1i(currentProgram->getUniformLocation(u_doTessellate), tessellate); const Viewport& currentViewport = currentCamera->getViewport(); glUniform1f(currentProgram->getUniformLocation(u_width), static_cast<float>(currentViewport.getWidth())); glUniform1f(currentProgram->getUniformLocation(u_height), static_cast<float>(currentViewport.getHeight())); glUniform1f(currentProgram->getUniformLocation(u_displacementScale), displacementScale); glUniform1i(currentProgram->getUniformLocation(u_convertDirectX), surfaceMaterial->isConvertDirectX()); // glUniform4fv(currentProgram->getUniformLocation(u_reflectionColor), 1, surfaceMaterial->getReflection().getRGBA()); glUniform4fv(currentProgram->getUniformLocation(u_refractionColor), 1, surfaceMaterial->getRefraction().getRGBA()); float environmentRefractiveIndex = refractiveIndex; if (environmentRefractiveIndex != RI_NOTHING) { float materialRefractiveIndex = surfaceMaterial->getRefractiveIndex(); float eta = environmentRefractiveIndex / materialRefractiveIndex; float reflectanceNormalIncidence = ((environmentRefractiveIndex - materialRefractiveIndex) * (environmentRefractiveIndex - materialRefractiveIndex)) / ((environmentRefractiveIndex + materialRefractiveIndex) * (environmentRefractiveIndex + materialRefractiveIndex)); glUniform1f(currentProgram->getUniformLocation(u_eta), eta); glUniform1f(currentProgram->getUniformLocation(u_reflectanceNormalIncidence), reflectanceNormalIncidence); } else { glUniform1f(currentProgram->getUniformLocation(u_eta), 0.0f); glUniform1f(currentProgram->getUniformLocation(u_reflectanceNormalIncidence), 0.0f); } if (SkyManager::getInstance()->hasActiveSky()) { glUniform1i(currentProgram->getUniformLocation(u_hasCubeMapTexture), 1); SkySP activeSky = SkyManager::getInstance()->getActiveSky(); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, activeSky->getSkyTextureName()); glUniform1i(currentProgram->getUniformLocation(u_cubemap), 3); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasCubeMapTexture), 0); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glUniform1i(currentProgram->getUniformLocation(u_cubemap), 3); glActiveTexture(GL_TEXTURE0); } // Only allow dynamic cube map, if also a sky cube map is available if (Entity::getDynamicCubeMaps() && surfaceMaterial->getDynamicCubeMapTextureName() != 0 && SkyManager::getInstance()->hasActiveSky()) { glUniform1i(currentProgram->getUniformLocation(u_hasDynamicCubeMapTexture), 1); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, surfaceMaterial->getDynamicCubeMapTextureName()); glUniform1i(currentProgram->getUniformLocation(u_dynamicCubeMapTexture), 4); glActiveTexture(GL_TEXTURE0); } else { glUniform1i(currentProgram->getUniformLocation(u_hasDynamicCubeMapTexture), 0); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glUniform1i(currentProgram->getUniformLocation(u_dynamicCubeMapTexture), 4); glActiveTexture(GL_TEXTURE0); } if (!Entity::getDynamicCubeMaps()) { glUniformMatrix4fv(currentProgram->getUniformLocation(u_cubeMapViewMatrix), 6, GL_FALSE, Entity::getCubeMapViewMatrices()[0].getM()); glUniformMatrix4fv(currentProgram->getUniformLocation(u_cubeMapProjectionMatrix), 1, GL_FALSE, Entity::getCubeMapProjectionMatrix().getM()); } // No Skinning glUniform1i(currentProgram->getUniformLocation(u_hasSkinning), 0); glUniformMatrix4fv(currentProgram->getUniformLocation(u_bindMatrix), 0, GL_FALSE, Matrix4x4().getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_bindNormalMatrix), 0, GL_TRUE, Matrix3x3().getM()); glUniformMatrix4fv(currentProgram->getUniformLocation(u_inverseBindMatrix), 0, GL_FALSE, Matrix4x4().getM()); glUniformMatrix3fv(currentProgram->getUniformLocation(u_inverseBindNormalMatrix), 0, GL_TRUE, Matrix3x3().getM()); // Write bright color glUniform1i(currentProgram->getUniformLocation(u_writeBrightColor), writeBrightColor); glUniform1f(currentProgram->getUniformLocation(u_brightColorLimit), brightColorLimit); if (transparent) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glDrawElements(GL_PATCHES, ground->getNumberIndices(), GL_UNSIGNED_INT, 0); if (transparent) { glDisable(GL_BLEND); } if (surfaceMaterial->getDiffuseTextureName() != 0) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); } if (surfaceMaterial->getSpecularTextureName() != 0) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); } if (surfaceMaterial->getDisplacementMapTextureName() != 0 || surfaceMaterial->getNormalMapTextureName() != 0) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0); } if (SkyManager::getInstance()->hasActiveSky()) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } if (surfaceMaterial->getDynamicCubeMapTexture() != 0) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); } glActiveTexture(GL_TEXTURE0); currentVAO->unbind(); // if (isWireframe()) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // if (isDebug()) { DebugDraw::drawer.draw(getBoundingSphere(), Color::RED, isDebugAsMesh()); } }