我正在将Visual Studio C ++ OpenGL
项目翻译成Qt项目以实现UI
。
我已经翻译了所有代码,并且我使用Qt类来实现OpenGL
部分。
我现在遇到的问题是,当我链接shaderProgram
时,它会抛出一个错误,上面写着:
顶点信息(0):错误C5145:必须写入gl_Position
我正在实现QOpenGLFunctions_4_1_Core
,我调试编译函数,看看代码是否读得很好,是的
读取所有代码并且编译函数返回true(编译良好)。
GLuint shaderProgram::createShaderProgram(const char *fileName) {
// Creamos el shader program y almacenamos su identificador
if (handler) {
shaderP = new QOpenGLShaderProgram();
handler = shaderP->create();
if (!handler) {
fprintf(stderr, "Cannot create shader program: %s.\n", fileName);
return 0;
}
}
// Cargamos y compilamos cada uno de los shader objects que componen este
// shader program
char fileNameComplete[256];
strcpy_s(fileNameComplete, fileName);
strcat_s(fileNameComplete, "-vert.glsl");
QOpenGLShader* vertex = new QOpenGLShader(QOpenGLShader::Vertex);
GLuint vertexShaderObject = compileShader(fileNameComplete, QOpenGLShader::Vertex,vertex);
if (vertexShaderObject == 0) {
return 0;
}
strcpy_s(fileNameComplete, fileName);
strcat_s(fileNameComplete, "-frag.glsl");
QOpenGLShader* fragment = new QOpenGLShader(QOpenGLShader::Fragment);
GLuint fragmentShaderObject = compileShader(fileNameComplete, QOpenGLShader::Fragment, fragment);
if (fragmentShaderObject == 0) {
return 0;
}
// Asociamos los shader objects compilados sin errores al shader program
shaderP->addShader(vertex);
shaderP->addShader(fragment);
// Enlazamos el shader program y comprobamos si hay errores
handler = shaderP->link(); //Here is where the error is thrown
if(!handler)
{
QString error = shaderP->log();
std::cout<< error.toStdString()<<std::endl;
return 0;
}
else {
linked = true;
}
return handler;
}
bool shaderProgram::compileShader(const char *filename, QOpenGLShader::ShaderTypeBit type,QOpenGLShader* shaderComp) {
// Comprobamos si en la solución existe algún archivo de recursos con el
// nombre que se pasa como argumento
if (!fileExists(filename)) {
fprintf(stderr, "Shader source file %s not found.\n", filename);
return 0;
}
// Si existe se lee en una cadena de caracteres que contiene el listado
// completo del shader source
std::ifstream shaderSourceFile;
shaderSourceFile.open(filename);
if (!shaderSourceFile) {
fprintf(stderr, "Cannot open shader source file.\n");
return 0;
}
std::stringstream shaderSourceStream;
shaderSourceStream << shaderSourceFile.rdbuf();
std::string shaderSourceString = shaderSourceStream.str();
shaderSourceFile.close();
// - Creamos un shader object para ese archivo que se ha leído
QOpenGLShader shader(type);
QString code(QString::fromStdString(shaderSourceString));
bool result = shader.compileSourceCode(code);
if(!result){
const QString qs = shader.log();
std::cout << qs.toStdString();
this->logString = qs.toStdString();
return false;
}
//si ha compilado bien, creamos el shader
shaderComp = &shader;
return true;
}
我希望着色器程序链接良好,我将能够在屏幕上绘制我的对象。
您的代码中存在一些问题。
首先,我向我们推荐QOpenGLShader::compileSourceFile
:
EG
QOpenGLShader* vertex = new QOpenGLShader(QOpenGLShader::Vertex);
vertex->compileSourceFile( fileNameComplete );
在函数shaderProgram::compileShader
中使用局部变量shader
:
QOpenGLShader shader(type);
但随后将指向此变量的指针分配给输出参数shaderComp
。
shaderComp = &shader;
当函数终止时,本地对象shader
被破坏,指针最终无处可去。
参数必须是输入参数。摆脱局部变量并使用现有对象编译着色器。
您可以在QOpenGLShader
中创建一个新的shaderProgram::compileShader
对象,并通过返回值返回该对象:
QOpenGLShader* shaderProgram::compileShader(
const char *filename,
QOpenGLShader::ShaderTypeBit type)
{
// Comprobamos si en la solución existe algún archivo de recursos con el
// nombre que se pasa como argumento
if (!fileExists(filename)) {
fprintf(stderr, "Shader source file %s not found.\n", filename);
return nullptr;
}
// Si existe se lee en una cadena de caracteres que contiene el listado
// completo del shader source
std::ifstream shaderSourceFile;
shaderSourceFile.open(filename);
if (!shaderSourceFile) {
fprintf(stderr, "Cannot open shader source file.\n");
return nullptr;
}
std::stringstream shaderSourceStream;
shaderSourceStream << shaderSourceFile.rdbuf();
std::string shaderSourceString = shaderSourceStream.str();
shaderSourceFile.close();
// - Creamos un shader object para ese archivo que se ha leído
QString code(QString::fromStdString(shaderSourceString));
QOpenGLShader* shader = new QOpenGLShader(QOpenGLShader::Vertex);
bool result = shader->compileSourceCode(code);
if(!result){
const QString qs = shader->log();
std::cout << qs.toStdString();
this->logString = qs.toStdString();
delete shader;
return nullptr;
}
//si ha compilado bien, creamos el shader
return shader;
}
像这样调用方法:
std::string vertFileName = std::string(fileName) + "-vert.glsl";
QOpenGLShader* vertex = compileShader(vertFileName.c_str(), QOpenGLShader::Vertex);
if (!vertex) {
return 0;
}
std::string fragFileName = std::string(fileName) + "-frag.glsl";
QOpenGLShader* fragment = compileShader(fragFileName.c_str(), QOpenGLShader::Fragment);
if (!fragment) {
return 0;
}