void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) const { if (!_isBlendShaped) { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputStream(0, _drawMesh->getVertexStream()); } else { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputBuffer(0, _model->_blendedVertexBuffers[_meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _model->_blendedVertexBuffers[_meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); } float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; if (!_hasColorAttrib || fadeRatio < 1.0f) { batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio); } }
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) const { if (!_isBlendShaped) { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputStream(0, _drawMesh->getVertexStream()); } else { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputBuffer(0, _model->_blendedVertexBuffers[_meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _model->_blendedVertexBuffers[_meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); } // TODO: Get rid of that extra call if (!_hasColorAttrib) { batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } }
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { if (!(skybox._procedural)) { Skybox::render(batch, viewFrustum, skybox); } static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) { if (!theBuffer) { const float CLIP = 1.0f; const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } }; theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices); theFormat = std::make_shared<gpu::Stream::Format>(); theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); } glm::mat4 projMat; viewFrustum.evalProjectionMatrix(projMat); Transform viewTransform; viewFrustum.evalViewTransform(viewTransform); batch.setProjectionTransform(projMat); batch.setViewTransform(viewTransform); batch.setModelTransform(Transform()); // only for Mac batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); batch.setInputFormat(theFormat); if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { batch.setResourceTexture(0, skybox.getCubemap()); } skybox._procedural->prepare(batch, glm::vec3(1)); batch.draw(gpu::TRIANGLE_STRIP, 4); } }
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations) const { if (!_drawMaterial) { return; } auto textureCache = DependencyManager::get<TextureCache>(); batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_GPU, _drawMaterial->getSchemaBuffer()); auto materialKey = _drawMaterial->getKey(); auto textureMaps = _drawMaterial->getTextureMaps(); glm::mat4 texcoordTransform[2]; // Albedo if (materialKey.isAlbedoMap()) { auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP]; if (albedoMap && albedoMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, albedoMap->getTextureView()); if (!albedoMap->getTextureTransform().isIdentity()) { albedoMap->getTextureTransform().getMatrix(texcoordTransform[0]); } } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getGrayTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getWhiteTexture()); } // Roughness map if (materialKey.isRoughnessMap()) { auto roughnessMap = textureMaps[model::MaterialKey::ROUGHNESS_MAP]; if (roughnessMap && roughnessMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, roughnessMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture()); } // Normal map if (materialKey.isNormalMap()) { auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; if (normalMap && normalMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, nullptr); } // Metallic map if (materialKey.isMetallicMap()) { auto specularMap = textureMaps[model::MaterialKey::METALLIC_MAP]; if (specularMap && specularMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, specularMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, textureCache->getBlackTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, nullptr); } // Occlusion map if (materialKey.isOcclusionMap()) { auto specularMap = textureMaps[model::MaterialKey::OCCLUSION_MAP]; if (specularMap && specularMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, specularMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, textureCache->getWhiteTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, nullptr); } // Emissive / Lightmap if (materialKey.isLightmapMap()) { auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; if (lightmapMap && lightmapMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, lightmapMap->getTextureView()); auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); if (!lightmapMap->getTextureTransform().isIdentity()) { lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); } } else { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getGrayTexture()); } } else if (materialKey.isEmissiveMap()) { auto emissiveMap = textureMaps[model::MaterialKey::EMISSIVE_MAP]; if (emissiveMap && emissiveMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, emissiveMap->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getBlackTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, nullptr); } // Texcoord transforms ? if (locations->texcoordMatrices >= 0) { batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); } }
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations) const { if (!_drawMaterial) { return; } auto textureCache = DependencyManager::get<TextureCache>(); batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_GPU, _drawMaterial->getSchemaBuffer()); auto materialKey = _drawMaterial->getKey(); auto textureMaps = _drawMaterial->getTextureMaps(); glm::mat4 texcoordTransform[2]; // Diffuse if (materialKey.isDiffuseMap()) { auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; if (diffuseMap && diffuseMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, diffuseMap->getTextureView()); if (!diffuseMap->getTextureTransform().isIdentity()) { diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); } } else { batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, textureCache->getGrayTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::DIFFUSE_MAP, textureCache->getWhiteTexture()); } // Normal map if (materialKey.isNormalMap()) { auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; if (normalMap && normalMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView()); // texcoord are assumed to be the same has diffuse } else { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, nullptr); } // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that if (materialKey.isGlossMap()) { auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; if (specularMap && specularMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, specularMap->getTextureView()); // texcoord are assumed to be the same has diffuse } else { batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, textureCache->getBlackTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, nullptr); } // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too if (materialKey.isLightmapMap()) { auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; if (lightmapMap && lightmapMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, lightmapMap->getTextureView()); auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); if (!lightmapMap->getTextureTransform().isIdentity()) { lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); } } else { batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, textureCache->getGrayTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::LIGHTMAP_MAP, nullptr); } // Texcoord transforms ? if (locations->texcoordMatrices >= 0) { batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); } }
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) { if (!_isBlendShaped) { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputStream(0, _drawMesh->getVertexStream()); } else { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); ModelPointer model = _model.lock(); if (model) { batch.setInputBuffer(0, model->_blendedVertexBuffers[_meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, model->_blendedVertexBuffers[_meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); } else { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); batch.setInputStream(0, _drawMesh->getVertexStream()); } } if (_fadeState != FADE_COMPLETE) { batch._glColor4f(1.0f, 1.0f, 1.0f, computeFadeAlpha()); } else if (!_hasColorAttrib) { batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } }
void MeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const { batch.setModelTransform(_drawTransform); }
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool enableTextures) const { if (!_drawMaterial) { return; } auto textureCache = DependencyManager::get<TextureCache>(); batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, _drawMaterial->getSchemaBuffer()); batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::TEXMAPARRAY, _drawMaterial->getTexMapArrayBuffer()); const auto& materialKey = _drawMaterial->getKey(); const auto& textureMaps = _drawMaterial->getTextureMaps(); int numUnlit = 0; if (materialKey.isUnlit()) { numUnlit++; } if (!enableTextures) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, textureCache->getWhiteTexture()); batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture()); return; } // Albedo if (materialKey.isAlbedoMap()) { auto itr = textureMaps.find(model::MaterialKey::ALBEDO_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, itr->second->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getGrayTexture()); } } // Roughness map if (materialKey.isRoughnessMap()) { auto itr = textureMaps.find(model::MaterialKey::ROUGHNESS_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, itr->second->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); } } // Normal map if (materialKey.isNormalMap()) { auto itr = textureMaps.find(model::MaterialKey::NORMAL_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, itr->second->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture()); } } // Metallic map if (materialKey.isMetallicMap()) { auto itr = textureMaps.find(model::MaterialKey::METALLIC_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, itr->second->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture()); } } // Occlusion map if (materialKey.isOcclusionMap()) { auto itr = textureMaps.find(model::MaterialKey::OCCLUSION_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, itr->second->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture()); } } // Scattering map if (materialKey.isScatteringMap()) { auto itr = textureMaps.find(model::MaterialKey::SCATTERING_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, itr->second->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, textureCache->getWhiteTexture()); } } // Emissive / Lightmap if (materialKey.isLightmapMap()) { auto itr = textureMaps.find(model::MaterialKey::LIGHTMAP_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture()); } } else if (materialKey.isEmissiveMap()) { auto itr = textureMaps.find(model::MaterialKey::EMISSIVE_MAP); if (itr != textureMaps.end() && itr->second->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture()); } } }
void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch) { batch.setUniformBuffer(gr::Buffer::KeyLight, nullptr); batch.setUniformBuffer(gr::Buffer::AmbientLight, nullptr); batch.setResourceTexture(ru::Texture::Skybox, nullptr); }
void MeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool canCauterize) const { batch.setModelTransform(_drawTransform); }
void SkeletonModel::renderJointConstraints(gpu::Batch& batch, int jointIndex) { if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) { return; } const FBXGeometry& geometry = _geometry->getFBXGeometry(); const float BASE_DIRECTION_SIZE = 0.3f; float directionSize = BASE_DIRECTION_SIZE * extractUniformScale(_scale); // FIXME: THe line width of 3.0f is not supported anymore, we ll need a workaround do { const FBXJoint& joint = geometry.joints.at(jointIndex); const JointState& jointState = _rig->getJointState(jointIndex); glm::vec3 position = _rotation * jointState.getPosition() + _translation; glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _rotation * _rig->getJointState(joint.parentIndex).getRotation(); float fanScale = directionSize * 0.75f; Transform transform = Transform(); transform.setTranslation(position); transform.setRotation(parentRotation); transform.setScale(fanScale); batch.setModelTransform(transform); const int AXIS_COUNT = 3; auto geometryCache = DependencyManager::get<GeometryCache>(); for (int i = 0; i < AXIS_COUNT; i++) { if (joint.rotationMin[i] <= -PI + EPSILON && joint.rotationMax[i] >= PI - EPSILON) { continue; // unconstrained } glm::vec3 axis; axis[i] = 1.0f; glm::vec3 otherAxis; if (i == 0) { otherAxis.y = 1.0f; } else { otherAxis.x = 1.0f; } glm::vec4 color(otherAxis.r, otherAxis.g, otherAxis.b, 0.75f); QVector<glm::vec3> points; points << glm::vec3(0.0f, 0.0f, 0.0f); const int FAN_SEGMENTS = 16; for (int j = 0; j < FAN_SEGMENTS; j++) { glm::vec3 rotated = glm::angleAxis(glm::mix(joint.rotationMin[i], joint.rotationMax[i], (float)j / (FAN_SEGMENTS - 1)), axis) * otherAxis; points << rotated; } // TODO: this is really inefficient constantly recreating these vertices buffers. It would be // better if the skeleton model cached these buffers for each of the joints they are rendering geometryCache->updateVertices(_triangleFanID, points, color); geometryCache->renderVertices(batch, gpu::TRIANGLE_FAN, _triangleFanID); } renderOrientationDirections(batch, jointIndex, position, _rotation * jointState.getRotation(), directionSize); jointIndex = joint.parentIndex; } while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree); }
void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) { if (pipeline.locations->normalFittingMapUnit > -1) { batch.setResourceTexture(pipeline.locations->normalFittingMapUnit, DependencyManager::get<TextureCache>()->getNormalFittingTexture()); } }
void RangeTimer::begin(gpu::Batch& batch) { _headIndex++; batch.beginQuery(_timerQueries[rangeIndex(_headIndex)]); }
void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch) { batch.setUniformBuffer(gr::Buffer::Light, nullptr); batch.setUniformBuffer(ru::Buffer::LightClusterGrid, nullptr); batch.setUniformBuffer(ru::Buffer::LightClusterContent, nullptr); batch.setUniformBuffer(ru::Buffer::LightClusterFrustumGrid, nullptr); }
void MeshPartPayload::drawCall(gpu::Batch& batch) const { batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); }
void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations) const { if (!_drawMaterial) { return; } auto textureCache = DependencyManager::get<TextureCache>(); batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, _drawMaterial->getSchemaBuffer()); batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::TEXMAPARRAY, _drawMaterial->getTexMapArrayBuffer()); auto materialKey = _drawMaterial->getKey(); auto textureMaps = _drawMaterial->getTextureMaps(); int numUnlit = 0; if (materialKey.isUnlit()) { numUnlit++; } // Albedo if (materialKey.isAlbedoMap()) { auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP]; if (albedoMap && albedoMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, albedoMap->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getGrayTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture()); } // Roughness map if (materialKey.isRoughnessMap()) { auto roughnessMap = textureMaps[model::MaterialKey::ROUGHNESS_MAP]; if (roughnessMap && roughnessMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, roughnessMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); } // Normal map if (materialKey.isNormalMap()) { auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; if (normalMap && normalMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, normalMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, nullptr); } // Metallic map if (materialKey.isMetallicMap()) { auto specularMap = textureMaps[model::MaterialKey::METALLIC_MAP]; if (specularMap && specularMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, specularMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, nullptr); } // Occlusion map if (materialKey.isOcclusionMap()) { auto specularMap = textureMaps[model::MaterialKey::OCCLUSION_MAP]; if (specularMap && specularMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, specularMap->getTextureView()); // texcoord are assumed to be the same has albedo } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, nullptr); } // Emissive / Lightmap if (materialKey.isLightmapMap()) { auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; if (lightmapMap && lightmapMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, lightmapMap->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture()); } } else if (materialKey.isEmissiveMap()) { auto emissiveMap = textureMaps[model::MaterialKey::EMISSIVE_MAP]; if (emissiveMap && emissiveMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, emissiveMap->getTextureView()); } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture()); } } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, nullptr); } }
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { static gpu::PipelinePointer thePipeline; static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; static gpu::BufferPointer theConstants; int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader if (!thePipeline) { auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); gpu::Shader::BindingSet bindings; bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); if (!gpu::Shader::makeProgram(*skyShader, bindings)) { } SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); } auto skyState = gpu::StatePointer(new gpu::State()); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); const float CLIP = 1.0; const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}}; theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices)); theFormat.reset(new gpu::Stream::Format()); theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); auto color = glm::vec4(1.0f); theConstants.reset(new gpu::Buffer(sizeof(color), (const gpu::Byte*) &color)); } glm::mat4 projMat; viewFrustum.evalProjectionMatrix(projMat); Transform viewTransform; viewFrustum.evalViewTransform(viewTransform); if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { auto color = glm::vec4(1.0f); theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color); } else { theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor()); } batch.setProjectionTransform(projMat); batch.setViewTransform(viewTransform); batch.setModelTransform(Transform()); // only for Mac batch.setPipeline(thePipeline); batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); batch.setInputFormat(theFormat); batch.setUniformTexture(0, skybox.getCubemap()); batch.draw(gpu::TRIANGLE_STRIP, 4); } else { // skybox has no cubemap, just clear the color buffer auto color = skybox.getColor(); batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(skybox.getColor(),1.0f), 0.f, 0); } }
void WorldBoxRenderData::renderWorldBox(RenderArgs* args, gpu::Batch& batch) { auto geometryCache = DependencyManager::get<GeometryCache>(); // Show center of world static const glm::vec3 RED(1.0f, 0.0f, 0.0f); static const glm::vec3 GREEN(0.0f, 1.0f, 0.0f); static const glm::vec3 BLUE(0.0f, 0.0f, 1.0f); static const glm::vec3 GREY(0.5f, 0.5f, 0.5f); static const glm::vec4 GREY4(0.5f, 0.5f, 0.5f, 1.0f); static const glm::vec4 DASHED_RED(1.0f, 0.0f, 0.0f, 1.0f); static const glm::vec4 DASHED_GREEN(0.0f, 1.0f, 0.0f, 1.0f); static const glm::vec4 DASHED_BLUE(0.0f, 0.0f, 1.0f, 1.0f); static const float DASH_LENGTH = 1.0f; static const float GAP_LENGTH = 1.0f; auto transform = Transform{}; static std::array<int, 18> geometryIds; static std::once_flag initGeometryIds; std::call_once(initGeometryIds, [&] { for (size_t i = 0; i < geometryIds.size(); ++i) { geometryIds[i] = geometryCache->allocateID(); } }); batch.setModelTransform(transform); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED, geometryIds[0]); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-HALF_TREE_SCALE, 0.0f, 0.0f), DASHED_RED, DASH_LENGTH, GAP_LENGTH, geometryIds[1]); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN, geometryIds[2]); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -HALF_TREE_SCALE, 0.0f), DASHED_GREEN, DASH_LENGTH, GAP_LENGTH, geometryIds[3]); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE, geometryIds[4]); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -HALF_TREE_SCALE), DASHED_BLUE, DASH_LENGTH, GAP_LENGTH, geometryIds[5]); // X center boundaries geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY, geometryIds[6]); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, geometryIds[7]); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, geometryIds[8]); geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY, geometryIds[9]); // Z center boundaries geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, geometryIds[10]); geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY, geometryIds[11]); geometryCache->renderLine(batch, glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, geometryIds[12]); geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY, geometryIds[13]); // Center boundaries geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, geometryIds[14]); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY, geometryIds[15]); geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, geometryIds[16]); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY, geometryIds[17]); geometryCache->renderWireCubeInstance(args, batch, GREY4); // Draw meter markers along the 3 axis to help with measuring things const float MARKER_DISTANCE = 1.0f; const float MARKER_RADIUS = 0.05f; transform = Transform().setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(args, batch, RED); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(args, batch, RED); transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(args, batch, GREEN); transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(args, batch, BLUE); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(args, batch, GREY); }
void renderWorldBox(gpu::Batch& batch) { auto geometryCache = DependencyManager::get<GeometryCache>(); // Show center of world static const glm::vec3 RED(1.0f, 0.0f, 0.0f); static const glm::vec3 GREEN(0.0f, 1.0f, 0.0f); static const glm::vec3 BLUE(0.0f, 0.0f, 1.0f); static const glm::vec3 GREY(0.5f, 0.5f, 0.5f); static const glm::vec4 GREY4(0.5f, 0.5f, 0.5f, 1.0f); static const glm::vec4 DASHED_RED(1.0f, 0.0f, 0.0f, 1.0f); static const glm::vec4 DASHED_GREEN(0.0f, 1.0f, 0.0f, 1.0f); static const glm::vec4 DASHED_BLUE(0.0f, 0.0f, 1.0f, 1.0f); static const float DASH_LENGTH = 1.0f; static const float GAP_LENGTH = 1.0f; auto transform = Transform{}; batch.setModelTransform(transform); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-HALF_TREE_SCALE, 0.0f, 0.0f), DASHED_RED, DASH_LENGTH, GAP_LENGTH); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -HALF_TREE_SCALE, 0.0f), DASHED_GREEN, DASH_LENGTH, GAP_LENGTH); geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE); geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -HALF_TREE_SCALE), DASHED_BLUE, DASH_LENGTH, GAP_LENGTH); // X center boundaries geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY); geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY); // Z center boundaries geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY); // Center boundaries geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY); geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY); geometryCache->renderWireCubeInstance(batch, GREY4); // Draw meter markers along the 3 axis to help with measuring things const float MARKER_DISTANCE = 1.0f; const float MARKER_RADIUS = 0.05f; transform = Transform().setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(batch, RED); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(batch, RED); transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(batch, GREEN); transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(batch, BLUE); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); batch.setModelTransform(transform); geometryCache->renderSolidSphereInstance(batch, GREY); }