|
@@ -115,108 +115,107 @@ bool ShaderBase::compileShader()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief 初始化纹理,返回值是生成的纹理ID
|
|
|
+ * @brief 创建纹理,可以显式的指定纹理单元编号,返回纹理单元编号,创建失败则返回的是
|
|
|
*
|
|
|
- * @param imageFile 纹理图片路径
|
|
|
- * @param uniformName 纹理对应的uniform变量名称
|
|
|
- * @return true
|
|
|
- * @return false
|
|
|
+ * @param uniformName
|
|
|
+ * @param textureUnit 如果不指定或者小于0,则会自动分配纹理单元编号
|
|
|
+ * @return int -1,创建失败,>0,创建成功
|
|
|
*/
|
|
|
-bool ShaderBase::createTexture(const QString &imageFile, const QString uniformName)
|
|
|
+int ShaderBase::createTexture(const QString uniformName, int textureUnit)
|
|
|
{
|
|
|
- bool isExist = false;
|
|
|
- for(auto& it : m_listTexture)
|
|
|
+ GLint maxTextureUnits = 0;
|
|
|
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
|
|
+ if(textureUnit > maxTextureUnits)
|
|
|
{
|
|
|
- if(it.first == uniformName)
|
|
|
+ SPDLOG_ERROR("纹理单元编号:{}已超过支持的最大单元数目:{}", textureUnit, maxTextureUnits);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ /* 制定了单元编号,先查重 */
|
|
|
+ int texUnit = textureUnit;
|
|
|
+ if(texUnit >= 0)
|
|
|
+ {
|
|
|
+ for(auto it = m_mapTexture.begin(); it != m_mapTexture.end(); ++it)
|
|
|
{
|
|
|
- QOpenGLTexture* texture = it.second;
|
|
|
- if (texture != nullptr) {
|
|
|
- texture->destroy();
|
|
|
- delete texture;
|
|
|
- texture = nullptr;
|
|
|
+ if(it.key() == texUnit)
|
|
|
+ {
|
|
|
+ if(it->first == uniformName)
|
|
|
+ {
|
|
|
+ SPDLOG_WARN("纹理单元编号:{},名称:{} 已存在", texUnit, uniformName.toStdString());
|
|
|
+ return texUnit;
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ /* 删除该纹理单元 */
|
|
|
+ SPDLOG_WARN("纹理单元编号:{},名称:{} 已存在,将被替换为名称:{}", texUnit, it->first.toStdString(), uniformName.toStdString());
|
|
|
+ if(it->second != nullptr)
|
|
|
+ {
|
|
|
+ it->second->destroy();
|
|
|
+ delete it->second;
|
|
|
+ it->second = nullptr;
|
|
|
+ }
|
|
|
+ m_mapTexture.erase(it); // 删除该纹理单元
|
|
|
+ break; // 退出循环
|
|
|
+ }
|
|
|
}
|
|
|
- /* 纹理已存在,删除纹理 */
|
|
|
- m_listTexture.removeOne(it);
|
|
|
- isExist = true;
|
|
|
- break;
|
|
|
}
|
|
|
- }
|
|
|
- if(!isExist)
|
|
|
+ }else
|
|
|
{
|
|
|
- /* 纹理图片不存在,检查是否已经超过最大的纹理数目 */
|
|
|
- int maxTextureUnits = 0;
|
|
|
- // maxTextureUnits 就是当前环境支持的最大纹理单元数
|
|
|
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
|
|
-
|
|
|
- if (m_listTexture.size() >= maxTextureUnits) {
|
|
|
- SPDLOG_ERROR("纹理图片数量超过最大限制");
|
|
|
- return false;
|
|
|
+ /* 没有分配编号,手动分配 */
|
|
|
+ texUnit = 0;
|
|
|
+ for(int i = 0; i < m_mapTexture.size(); i++)
|
|
|
+ {
|
|
|
+ if(!m_mapTexture.contains(i))
|
|
|
+ {
|
|
|
+ texUnit = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /* 加载图片 */
|
|
|
- QImage image;
|
|
|
- image.load(imageFile);
|
|
|
- if (image.isNull()) {
|
|
|
- SPDLOG_ERROR("Failed to load image: {}", imageFile.toStdString());
|
|
|
- return false;
|
|
|
- }
|
|
|
- /* 将图片转换为RGBA格式 */
|
|
|
- image = image.convertToFormat(QImage::Format_RGBA8888);
|
|
|
- /* 这里要垂直翻转 */
|
|
|
- // image = image.mirrored(false, true);
|
|
|
|
|
|
QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
|
|
- texture->setSize(image.width(), image.height(), 1); // 设置纹理大小
|
|
|
- texture->setFormat(QOpenGLTexture::RGBA8_UNorm); // 设置纹理格式
|
|
|
- texture->allocateStorage(); // 分配纹理存储空间
|
|
|
- texture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, image.bits()); // 设置纹理数据
|
|
|
/* 设置纹理参数 */
|
|
|
texture->setWrapMode(QOpenGLTexture::Repeat); // S轴环绕方式
|
|
|
texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); // 纹理缩小过滤方式
|
|
|
texture->setMagnificationFilter(QOpenGLTexture::Linear); // 纹理放大过滤方式
|
|
|
|
|
|
-
|
|
|
- texture->generateMipMaps(); // 生成多级渐远纹理
|
|
|
|
|
|
printGLerror("ShaderBase::createTextureFile");
|
|
|
/* 将纹理存储到数组中 */
|
|
|
- m_listTexture.push_back(QPair<QString, QOpenGLTexture*>(uniformName, texture));
|
|
|
+ m_mapTexture.insert(texUnit, QPair<QString, QOpenGLTexture*>(uniformName, texture));
|
|
|
|
|
|
- return true;
|
|
|
+ return texUnit;
|
|
|
}
|
|
|
|
|
|
-/* 初始化纹理,直接传入图片 */
|
|
|
-bool ShaderBase::createTexture(const QImage &image, const QString uniformName)
|
|
|
-{
|
|
|
- if(image.isNull()) {
|
|
|
- SPDLOG_WARN("Texture Image is null");
|
|
|
- return false;
|
|
|
- }
|
|
|
- QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
|
|
- texture->setSize(image.width(), image.height(), 1); // 设置纹理大小
|
|
|
- texture->setFormat(QOpenGLTexture::RGBA8_UNorm); // 设置纹理格式
|
|
|
- texture->allocateStorage(); // 分配纹理存储空间
|
|
|
- texture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, image.convertToFormat(QImage::Format_RGBA8888).bits()); // 设置纹理数据
|
|
|
- /* 设置纹理参数 */
|
|
|
- texture->setWrapMode(QOpenGLTexture::Repeat); // S轴环绕方式
|
|
|
- texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); // 纹理缩小过滤方式
|
|
|
- texture->setMagnificationFilter(QOpenGLTexture::Linear); // 纹理放大过滤方式
|
|
|
+// /* 初始化纹理,直接传入图片 */
|
|
|
+// bool ShaderBase::createTexture(const QImage &image, const QString uniformName)
|
|
|
+// {
|
|
|
+// if(image.isNull()) {
|
|
|
+// SPDLOG_WARN("Texture Image is null");
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+// QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
|
|
+// texture->setSize(image.width(), image.height(), 1); // 设置纹理大小
|
|
|
+// texture->setFormat(QOpenGLTexture::RGBA8_UNorm); // 设置纹理格式
|
|
|
+// texture->allocateStorage(); // 分配纹理存储空间
|
|
|
+// texture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, image.convertToFormat(QImage::Format_RGBA8888).bits()); // 设置纹理数据
|
|
|
+// /* 设置纹理参数 */
|
|
|
+// texture->setWrapMode(QOpenGLTexture::Repeat); // S轴环绕方式
|
|
|
+// texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); // 纹理缩小过滤方式
|
|
|
+// texture->setMagnificationFilter(QOpenGLTexture::Linear); // 纹理放大过滤方式
|
|
|
|
|
|
|
|
|
- texture->generateMipMaps(); // 生成多级渐远纹理
|
|
|
+// texture->generateMipMaps(); // 生成多级渐远纹理
|
|
|
|
|
|
- printGLerror("ShaderBase::createTextureImage");
|
|
|
- /* 将纹理存储到数组中 */
|
|
|
- m_listTexture.push_back(QPair<QString, QOpenGLTexture*>(uniformName, texture));
|
|
|
+// printGLerror("ShaderBase::createTextureImage");
|
|
|
+// /* 将纹理存储到数组中 */
|
|
|
+// m_listTexture.push_back(QPair<QString, QOpenGLTexture*>(uniformName, texture));
|
|
|
|
|
|
- return true;
|
|
|
-}
|
|
|
+// return true;
|
|
|
+// }
|
|
|
|
|
|
/* 清空纹理 */
|
|
|
void ShaderBase::clearTexture()
|
|
|
{
|
|
|
- for(auto& it : m_listTexture)
|
|
|
+ for(auto& it : m_mapTexture)
|
|
|
{
|
|
|
if(it.second != nullptr)
|
|
|
{
|
|
@@ -225,7 +224,7 @@ void ShaderBase::clearTexture()
|
|
|
it.second = nullptr;
|
|
|
}
|
|
|
}
|
|
|
- m_listTexture.clear();
|
|
|
+ m_mapTexture.clear();
|
|
|
}
|
|
|
|
|
|
/* 使用着色器 */
|
|
@@ -238,12 +237,11 @@ void ShaderBase::useShader()
|
|
|
/* 使用着色器程序 */
|
|
|
m_shaderProgramObj->bind();
|
|
|
/* 使用纹理 */
|
|
|
- if(m_listTexture.size() > 0)
|
|
|
+ if(m_mapTexture.size() > 0)
|
|
|
{
|
|
|
- int currentTextureUnit = 0;
|
|
|
- for (auto it = m_listTexture.begin(); it != m_listTexture.end(); ++it)
|
|
|
+ for (auto it = m_mapTexture.begin(); it != m_mapTexture.end(); ++it)
|
|
|
{
|
|
|
- it->second->bind(currentTextureUnit);
|
|
|
+ it->second->bind(it.key());
|
|
|
/* 绑定纹理 */
|
|
|
int location = m_shaderProgramObj->uniformLocation(it->first);
|
|
|
if (location < 0) {
|
|
@@ -251,9 +249,7 @@ void ShaderBase::useShader()
|
|
|
continue;
|
|
|
}
|
|
|
/* 设置纹理单元 */
|
|
|
- m_shaderProgramObj->setUniformValue(location, currentTextureUnit);
|
|
|
-
|
|
|
- currentTextureUnit++;
|
|
|
+ m_shaderProgramObj->setUniformValue(location, it.key());
|
|
|
}
|
|
|
}
|
|
|
}
|