void functionA() {
// ...........
auto meshIterator = mMeshes.begin();
for (const Renderable &renderable : renderQueue) {
if (renderable.mMesh == INVALID_MESH_ID) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID is invalid");
throw std::runtime_error("Renderable MeshID is invalid");
}
if (renderable.mMesh < meshIterator->first->mMeshID)
continue;
while (renderable.mMesh > meshIterator->first->mMeshID) {
meshIterator++;
if (meshIterator == mMeshes.end()) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID out of range");
throw std::runtime_error("Renderable MeshID out of range");
}
}
const bool hasDiffuseTexture =
renderable.mDiffuseTexture != INVALID_TEXTURE_ID;
const bool hasNormalTexture =
renderable.mNormalTexture != INVALID_TEXTURE_ID;
mGeometryProgram.SetUniformData(
UnifGeometry(renderable.mWVPMatrix, renderable.mWorldMatrix,
hasDiffuseTexture, hasNormalTexture,
renderable.mTextureTilingFactor));
if (hasDiffuseTexture)
BindTexture2D(OpenGLTexture::TEXTURE_UNIT_GEOMETRY_DIFFUSE,
renderable.mDiffuseTexture, mTextures, mLogger);
if (hasNormalTexture)
BindTexture2D(OpenGLTexture::TEXTURE_UNIT_GEOMETRY_NORMAL,
renderable.mNormalTexture, mTextures, mLogger);
GLCALL(glBindVertexArray(meshIterator->second));
GLCALL(glDrawElements(GL_TRIANGLES, meshIterator->first->mIndices,
GL_UNSIGNED_INT, 0));
GLCALL(glBindVertexArray(0));
}
// ...........
}
void functionB() {
//....................
// both containers are assumed to be sorted by MeshID ascending
auto meshIterator = mMeshes.begin();
for (const Renderable &renderable : renderQueue) {
if (renderable.mMesh == INVALID_MESH_ID) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID is invalid");
throw std::runtime_error("Renderable MeshID is invalid");
}
if (renderable.mMesh < meshIterator->first->mMeshID)
continue;
while (renderable.mMesh > meshIterator->first->mMeshID) {
meshIterator++;
if (meshIterator == mMeshes.end()) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID out of range");
throw std::runtime_error("Renderable MeshID out of range");
}
}
const Mat4 wvp = lightVP * renderable.mWorldMatrix;
mNullProgram.SetUniformData(UnifNull(wvp));
GLCALL(glBindVertexArray(meshIterator->second));
GLCALL(glDrawElements(GL_TRIANGLES, meshIterator->first->mIndices,
GL_UNSIGNED_INT, 0));
GLCALL(glBindVertexArray(0));
}
// ...............
}
void DrawModels(const std::function<
void(const Renderable &renderable)> &preDrawFunc) {
// both containers are assumed to be sorted by MeshID ascending
auto meshIterator = mMeshes.begin();
for (const Renderable &renderable : renderQueue) {
if (renderable.mMesh == INVALID_MESH_ID) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID is invalid");
throw std::runtime_error("Renderable MeshID is invalid");
}
if (renderable.mMesh < meshIterator->first->mMeshID)
continue;
while (renderable.mMesh > meshIterator->first->mMeshID) {
meshIterator++;
if (meshIterator == mMeshes.end()) {
JONS_LOG_ERROR(mLogger, "Renderable MeshID out of range");
throw std::runtime_error("Renderable MeshID out of range");
}
}
preDrawFunc(renderable);
GLCALL(glBindVertexArray(meshIterator->second));
GLCALL(glDrawElements(GL_TRIANGLES, meshIterator->first->mIndices,
GL_UNSIGNED_INT, 0));
GLCALL(glBindVertexArray(0));
}
}
void functionD() {
auto preDrawRenderable = [&](const Renderable &renderable) {
const bool hasDiffuseTexture =
renderable.mDiffuseTexture != INVALID_TEXTURE_ID;
const bool hasNormalTexture =
renderable.mNormalTexture != INVALID_TEXTURE_ID;
mGeometryProgram.SetUniformData(
UnifGeometry(renderable.mWVPMatrix, renderable.mWorldMatrix,
hasDiffuseTexture, hasNormalTexture,
renderable.mTextureTilingFactor));
if (hasDiffuseTexture)
BindTexture2D(OpenGLTexture::TEXTURE_UNIT_GEOMETRY_DIFFUSE,
renderable.mDiffuseTexture, mTextures, mLogger);
if (hasNormalTexture)
BindTexture2D(OpenGLTexture::TEXTURE_UNIT_GEOMETRY_NORMAL,
renderable.mNormalTexture, mTextures, mLogger);
};
DrawModels(preDrawRenderable);
}
void functionE() {
auto preDrawRenderable = [&](const Renderable &renderable) {
const Mat4 wvp = lightVP * renderable.mWorldMatrix;
mNullProgram.SetUniformData(UnifNull(wvp));
};
DrawModels(preDrawRenderable);
}
1)functionD和functionE每秒都需要运行60-100次。使用lambda和std::function是否会对性能造成重大影响?例如,是否存在隐藏的动态内存分配调用或虚拟查找,或者其他可能会影响性能的东西?我不知道使用lambdas和std::function的开销。
2)有没有比我天真的解决方案更好/更快/更干净的替代方案?
void DrawModels(const std::function< void(const Renderable &renderable)> &preDrawFunc)
与其这样做,不如这样做:
template<class RenderableFunc>
void DrawModels(RenderableFunc&& preDrawFunc)
并保持身体不变。将其放置在您正在替换的两个函数都可以看到的位置。
现在编译器有一个简单的优化问题来内联您的lambda。
我们用Android中非常典型的例子去解释它是怎么工作的:View.setOnClickListener()方法。如果我们想用Java的方式去增加点击事件的回调,我首先要编写一个OnClickListener接口: public interface OnClickListener { void onClick(View v); } 然后我们要编写一个匿名内部类去实现这个接口: view.s
假设您希望对迭代器的元素进行流式处理;让我们使用一个的具体示例,它实现了。 给定,比方说: 在给定的情况下,JDK中是否有一个工厂方法返回?
我有一个比较器,它检查字符串是否为空,并返回-1。如果它们不是null,则进行比较。我想用lambda函数实现这个。 以下是代码: 我知道如何使用lambdas返回一个简单的比较器。我对如何实现上述代码感到困惑。
最常见的类型包括容器类(container class),也称集合类(collection class),是保存一组对象集合的类。容器类通常提供插入、删除、查找、排序和测试类成员项目等操作。数组、堆栈、队列、树和链表都是容器类,第4章介绍了数组,第11章和20章将介绍其他数据结构。 容器类经常与迭代对象(iterator object;或简称迭代器,aerator)相关联。迭代对象返回集合中的下一
一个自动点唱机只有一首歌恐怕不会太流行,所以我们需要建立一个歌曲目录和一个等待播放的列表。这都是容器的例子,一个包含若干个对其它对象引用的对象。 目录和播放列表都有类似的操作,增加歌曲,删除歌曲,返回歌曲列表等等。播放列表可能还需要别的方法,比如插入广告,记录累计播放时间等,我们将在后面考率这些问题。现在,我们需要建立一个SongList类,以便在目录和播放列表中使用。 容器 在开始实现之前,我们
我有一个现有的 Azure 函数,用于解压缩文件并将每个文件添加为 blob。 我现在想迭代这些文件并执行它们(它们是SQL文件)。我不想触发一个基于blob创建的函数,而是在一个函数中运行它们。 在一个函数中,我如何在一个容器中迭代一个blobs列表并获取它们的内容? 谢谢
本文向大家介绍python迭代器实例简析,包括了python迭代器实例简析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python迭代器的简单用法,分享给大家供大家参考。具体分析如下: 生成器表达式是用来生成函数调用时序列参数的一种迭代器写法 生成器对象可以遍历或转化为列表(或元组等数据结构),但不能切片(slicing)。当函数的唯一的实参是可迭代序列时,便可以去掉生成器表达式两端>
本文向大家介绍简述 生成器、迭代器、可迭代对象 以及应用场景?相关面试题,主要包含被问及简述 生成器、迭代器、可迭代对象 以及应用场景?时的应答技巧和注意事项,需要的朋友参考一下 迭代器 含有iter和next方法 (包含next方法的可迭代对象就是迭代器) 生成器: 包括含有yield这个关键字,生成器也是迭代器,调动next把函数变成迭代器。 可迭代对象 一个类内部实现iter方法且返