Qt OpenGLアプリケーションの作成を開始します。そして、私はLearnopenglからチュートリアルに従いました。このチュートリアルでは、頂点とフラグメントのシェーダーに対応する静的なC-Stringを提供します。アプリケーションに静的C文字列シェーダを渡すと、エラーはなく、三角形が画面に表示されます。ファイルからglslコードを読み取ることができません
しかし、私は別々のファイルにすべてのシェーダコードを処理しようとすると、私のようながgl_Positionここ
に書き込む必要がありますglLinkProgramコマンド中にエラーが発生している私のC++コードです:
#include "widget.h"
Widget::Widget(QOpenGLWidget *parent)
: QOpenGLWidget(parent)
{
this->setWindowTitle("Learning OpenGL");
QString pathV="shaders/main.vert";
QString pathF="shaders/main.frag";
vertexShaderSource=loadShader(pathV);
fragmentShaderSource=loadShader(pathF);
}
Widget::~Widget()
{
}
void Widget::initializeGL()
{
this->initializeOpenGLFunctions();
qDebug()<<"Vous travaillez sur une OpenGL version:"<<QString((char*)glGetString(GL_VERSION));
compileShaders();
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void Widget::paintGL()
{
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 1.0f, 0.0f
};
GLuint VBO,VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// Draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
}
QString Widget::loadShader(QString &path)
{
QFile file(path);
file.open(QIODevice::ReadOnly);
QTextStream stream(&file);
QString lines;
while(!stream.atEnd())
{
lines.append(stream.readLine()+"\n");
}
//lines.append('\0');
file.close();
return lines;
}
void Widget::compileShaders()
{
/* //Static shaders
// Shaders
vs = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
fs = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
"}\n\0";
//*/
//Vertex shader
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
vs=vertexShaderSource.toStdString().c_str();
glShaderSource(vertexShader, 1,(const GLchar **) &vs, 0);
glCompileShader(vertexShader);
//check if any error during compilation
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
qDebug()<< "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog ;
}
else qDebug()<<"compile vertex ok";
//Fragment shader
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
fs=fragmentShaderSource.toStdString().c_str();
glShaderSource(fragmentShader, 1,(const GLchar **) &fs, 0);
glCompileShader(fragmentShader);
//Check if any error during compilation
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
qDebug()<< "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog ;
}
else qDebug()<<"compile fragment ok";
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
qDebug()<< "Linkage error\n" << infoLog;
}
}
は、
シェーダファイルから読み込んだデータをコンソールに表示すると、スタティックC-Stringシェーダコードと同じになります。
シェーダファイルが壊れている理由はわかりません。
ファイルを1行ずつ読み込むのは、ファイルを一度に読み込むよりも遅いでしょうか? 'QTextStream'は' readAll'と呼ばれる便利な機能を持っています。 –