gpt4 book ai didi

c++ - Qt GLSL纹理只出现一种颜色

转载 作者:行者123 更新时间:2023-11-30 05:41:38 26 4
gpt4 key购买 nike

This是我之前的问题。

现在我想将我以前遗留的 obj 加载器移植到 GLSL。

但是,纹理上只能绑定(bind)一种颜色到对象。

因此,当我渲染对象时,整个对象都是纯色。

#include <QVector>
#include <QTextStream>
#include <QVector3D>
#include <QVector2D>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QMatrix4x4>

struct Face{
QVector<QVector3D> v;
QVector<QVector3D> vn;
QVector<QVector2D> t;
Face(){
v.resize(3);
vn.resize(3);
t.resize(3);
}
};

class ModelGLSL
{
public:
ModelGLSL() {}
ModelGLSL(QString filename);
void render(QOpenGLShaderProgram* program, QMatrix4x4 MVPmarix);

QString textureName;
QVector<QVector3D> Faces_vertices;
QVector<QVector2D> Faces_textureCoordinates;
GLuint texture;

private:
QString fileName;
QImage textureImg;
void LoadMTL(QString fn, QString MTLname);
void LoadTexture();
};

在 ModelGLSL.cpp 中

#include "ModelGLSL.h"

ModelGLSL::ModelGLSL(QString filename)
{
fileName = filename;
QString texturename;
QVector3D temp3D;
QVector2D temp2D;

QVector<Face> Faces;
QVector<QVector3D> Vertices;
QVector<QVector3D> VNormals;
QVector<QVector2D> UVs;

if(!fileName.isEmpty())
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream fileText(&file);
while (!fileText.atEnd())
{
QString fileLine = fileText.readLine();
if(fileLine.startsWith("vn "))
{
QStringList lineList = fileLine.split(" ");
temp3D.setX( lineList[1].toFloat() );
temp3D.setY( lineList[2].toFloat() );
temp3D.setZ( lineList[3].toFloat() );
VNormals.push_back(temp3D);
}
else if(fileLine.startsWith("vt "))
{
QStringList lineList = fileLine.split(" ");
temp2D.setX( lineList[1].toFloat() );
temp2D.setY( lineList[2].toFloat() );
UVs.push_back(temp2D);
}
else if(fileLine.startsWith("v "))
{
QStringList lineList = fileLine.split(" ");
temp3D.setX( lineList[1].toFloat() );
temp3D.setY( lineList[2].toFloat() );
temp3D.setZ( lineList[3].toFloat() );
Vertices.push_back(temp3D);
}
else if(fileLine.startsWith("f "))
{
Face F;
QStringList lineList = fileLine.split(" ");

for(int i = 1; i <= 3; i++)
{
QStringList arg = lineList[i].split("/");
F.v[i-1] = Vertices[arg[0].toInt()-1];
F.t[i-1] = UVs[arg[1].toInt()-1];
F.vn[i-1] = VNormals[arg[2].toInt()-1];
}
Faces.push_back(F);
}
else if(fileLine.startsWith("mtllib "))
{
QStringList lineList = fileLine.split(" ");
texturename = lineList[1];
}
}
LoadMTL(":/Model/Models/", ":/Model/Models/" + texturename);
}
file.close();
}

for( int i = 0; i < Faces.size(); i++ )
{
Faces_vertices << Faces[i].v;
Faces_textureCoordinates << Faces[i].t;
}
}

void ModelGLSL::LoadMTL(QString fn, QString MTLname)
{
if(!MTLname.isEmpty())
{
QFile file(MTLname);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream fileText(&file);
while (!fileText.atEnd())
{
QString fileLine = fileText.readLine();
if(fileLine.startsWith("map_Kd "))
{
QStringList lineList = fileLine.split(" ");
textureName = fn + lineList[1];
LoadTexture();
}
}
}
file.close();
}
}

void ModelGLSL::LoadTexture()
{
textureImg = QGLWidget::convertToGLFormat( QImage(textureName) );

glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureImg.width(), textureImg.height(), 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureImg.bits());

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glBindTexture( GL_TEXTURE_2D, 0 );
}

void ModelGLSL::render(QOpenGLShaderProgram *program, QMatrix4x4 MVPmarix)
{
glEnable(GL_DEPTH_TEST);
glEnable( GL_TEXTURE_2D );

program->setUniformValue("mvpMatrix", MVPmarix);
program->setUniformValue("texture", 0);

glBindTexture(GL_TEXTURE_2D, texture);

program->setAttributeArray("vertex", Faces_vertices.constData());
program->enableAttributeArray("vertex");

program->setAttributeArray("textureCoordinate", Faces_textureCoordinates.constData());
program->enableAttributeArray("textureCoordinate");

glDrawArrays(GL_TRIANGLES, 0, Faces_vertices.size());
program->disableAttributeArray("vertex");
program->disableAttributeArray("textureCoordinate");

program->release();
glDisable(GL_DEPTH_TEST);
glDisable( GL_TEXTURE_2D );
}

垂直与垂直

#version 430 core

uniform mat4 mvpMatrix;
in vec4 vertex;
in vec2 textureCoordinate;
out vec2 varyingTextureCoordinate;

void main(void)
{
varyingTextureCoordinate = textureCoordinate;
gl_Position = mvpMatrix * vertex;
}

在 fs.frag 中

#version 430 core

uniform sampler2D texture;
in vec2 varyingTextureCoordinate;
out vec4 fragColor;

void main(void)
{
fragColor = texture2D(texture, varyingTextureCoordinate);
}

在初始化GL()中

initializeOpenGLFunctions();

program = new QOpenGLShaderProgram;

program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shader/Shaders/vs.vert");
program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shader/Shaders/fs.frag");
program->link();

OBJ = new ModelGLSL(":/Model/Models/OBJ.obj");

在 paintGL() 中

OBJ->render(program, projection * view * model);

最佳答案

我在代码中看到了很多奇怪的东西:

  • 您没有使用核心配置文件中必需的顶点数组对象。

  • 您没有使用顶点缓冲区对象来设置属性数组。它们的使用在核心配置文件中是强制性的。更糟糕的是,您要为每次重绘上传属性数组!

  • 没有 program->bind() 调用来开始使用您创建的着色器程序。如果不先使用程序,就不能在程序上设置制服等。

  • 您没有使用 QOpenGLTexture,这意味着您正在求助于手动纹理分配。不仅 glEnable(GL_TEXTURE_2D) 是核心配置文件中的错误(没有这样的启用标志),而且您没有使用不可变存储,而且您将自己置于危险之中(在你的情况:你的纹理是 mipmap 不完整的,因为它有 mipmap 并且默认的 mipmap 范围是 [0, 1000))。

  • 使用核心配置文件时,您可以使用 texture() 函数而不是 texture2D() 对着色器语言中的纹理进行采样。参数的类型将由第一个参数自动推断出来(因此,对于 sampler2D,您还需要传递一个 vec2)。

另外,你应该:

  • 检查编译着色器或链接着色器程序是否失败,并转储log()

  • 如果您有 KHR_debug 扩展,请使用 QOpenGLDebugLogger 实例,这将报告此错误以及可能的许多其他错误。

关于c++ - Qt GLSL纹理只出现一种颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31089056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com