def common_start(sa, sb):
""" returns the longest common substring from the beginning of sa and sb """
def _iter():
for a, b in zip(sa, sb):
if a == b:
yield a
else:
return
return ''.join(_iter())
>>> common_start("apple pie available", "apple pies")
'apple pie'
Или немного страннее:
def stop_iter():
"""An easy way to break out of a generator"""
raise StopIteration
def common_start(sa, sb):
return ''.join(a if a == b else stop_iter() for a, b in zip(sa, sb))
Что может быть более читаемым как
def terminating(cond):
"""An easy way to break out of a generator"""
if cond:
return True
raise StopIteration
def common_start(sa, sb):
return ''.join(a for a, b in zip(sa, sb) if terminating(a == b))
В конце следующих строк кода
blockquote>Texture texture("ship.png"); texture.Bind(0); Texture texture2("ship2.png"); texture2.Bind(1);
2-й объект текстуры ( "ship2.png" ) привязан к единице текстуры 1, но к единице текстуры 0 привязан объект текстуры по умолчанию (0).
Обратите внимание, что при вызове
Texture texture("ship.png");
объект текстуры создается и привязывается к текущей единице текстуры, после этого объект текстуры по умолчанию (0) привязывается к текущей единице текстуры:blockquote>Texture::Texture(const std::string &path) { GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID)); // [...] GLCall(glBindTexture(GL_TEXTURE_2D, 0)); }
Обратите внимание, что то, что вы называете "unbind" , ничего не отменяет.
glBindTexture(GL_TEXTURE_2D, 0)
привязывает объект текстуры по умолчанию (0) к текстурному блоку, который в данный момент активен. В этом нет необходимости.
Просто измените порядок инструкций, чтобы решить вашу проблему. Сначала создайте и загрузите объекты текстуры. Затем привяжите объекты текстуры к текстурным блокам:
Texture texture("ship.png"); Texture texture2("ship2.png"); texture.Bind(0); texture2.Bind(1); shader.Bind(); va.Bind(); ib.Bind(); shader.SetUniform1i("u_Texture", 0); glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);
В качестве альтернативы вы можете избежать использования текстурного блока 0. Используйте текстурный блок 0 только для создания текстурного объекта:
Texture::Texture(const std::string &path, unsigned int slot) { GLCall(glActiveTexture(GL_TEXTURE0)); // [...] }
Texture texture("ship.png"); texture.Bind(1); // <--- 1 Texture texture2("ship2.png"); texture2.Bind(2); // <--- 2 shader.Bind(); va.Bind(); ib.Bind(); shader.SetUniform1i("u_Texture", 1); // <--- 1 glDrawElements(GL_TRIANGLES, ib.GetCount(), GL_UNSIGNED_INT, nullptr);
Или добавьте параметр для текстурного блока в конструктор класса
Texture
:Texture::Texture(const std::string &path, unsigned int slot) { GLCall(glGenTextures(1, &m_RendererID)); GLCall(glActiveTexture(GL_TEXTURE0 + slot)); GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID)); // [...] // GLCall(glBindTexture(GL_TEXTURE_2D, 0)); <--- delete }
Texture texture("ship.png", 0); Texture texture2("ship2.png", 1);