Вот моя маленькая функция У меня возникли проблемы с:чтение файла с станд :: ifstream скомпилировать OpenGL шейдер не работает
GLuint LoadShaders()
{
// open and compile vertex shader
std::ifstream VSS("glfwtest.vert", std::ifstream::ate);
int len = VSS.tellg() + 1;
GLchar* vertexSource = new GLchar[len];
VSS.clear();
VSS.seekg(0, VSS.beg);
for(int i=0; i<len ; i++) { VSS.get(vertexSource[i]); }
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
VSS.close();
// open and compile the fragment shader
std::ifstream FSS("glfwtest.frag", std::ifstream::ate);
len = FSS.tellg() + 1;
GLchar* fragmentSource = new GLchar[len];
FSS.clear();
FSS.seekg(0, FSS.beg);
for(int i=0; i<len ; i++) { FSS.get(fragmentSource[i]); }
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
FSS.close();
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
return shaderProgram;
}
Я следовал this руководство, и мне удалось оказать белого треугольника. После этого я подумал, что это может быть хорошим упражнением, чтобы разделить все это на функции, чтобы повторно использовать их позже. Поэтому я поместил свой шейдерный исходный код для обоих шейдеров в отдельные файлы (вместо этого они были непосредственно в моем источнике на C++) и написал вышеприведенную функцию, чтобы прочитать их из соответствующих файлов.
Теперь вот улов: мой вершинный шейдер загружается и компилируется отлично, в то время как мой шейдер фрагмента не работает. Но когда я положил фрагмент шейдер в код, как этот
const GLchar* fragmentSource =
"#version 150 core\n"
"out vec4 outColor;"
"void main()"
"{"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
GLuint LoadShaders()
{
[...]
// open and compile the fragment shader
//std::ifstream FSS("glfwtest.frag", std::ifstream::ate);
//len = FSS.tellg() + 1;
//GLchar* fragmentSource = new GLchar[len];
//FSS.clear();
//FSS.seekg(0, FSS.beg);
//for(int i=0; i<len ; i++) { FSS.get(fragmentSource[i]); }
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
[...]
return shaderProgram;
}
он отлично работает и показывает белый треугольник. Таким образом, тот же код, который загружает и компилирует мой вершинный шейдер из «glfwtest.vert», не работает для шейдера фрагментов.
Я никогда не работал с <fstream>
в C++ и собирал его из online documentation example. Я предполагаю, что ошибка там где-то есть, но я не могу ее найти, так как я не мастер C++ (пока).
EDIT:
После предложения в комментариях, я до сих пор застрял. Вот вывод GDB я получаю:
(gdb) break main.cpp:55
Breakpoint 1 at 0x4017dc: file main.cpp, line 55.
(gdb) r
Starting program: /home/georg/code/redbook/glfwtest/glfwtest
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Breakpoint 1, LoadShaders() at main.cpp:56
56 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
(gdb) p vertexSource
$1 = (GLchar *) 0x8277e0 "#version 420 core\n\nin vec2 position;\n\nvoid main()\n{\n gl_Position = vec4(position, 0.0, 1.0);\n}"
(gdb) p fragmentSource
$2 = (GLchar *) 0x82a300 "#version 150 core\nout vec4 outColor;\nvoid main()\n{\n outColor = vec4(1.0, 1.0, 1.0, 1.0);\n}\377\177"
(gdb) p len
$3 = 92
(gdb)
, как вы можете видеть, что длина правильно хранится в len
, есть 92 символов в источнике. Тем не менее, как-то есть два дополнительных символа. Я проверил исходный файл даже с шестнадцатеричным редактором, эти два символа определенно не находятся в файле.
Возможно, вам не хватает '\ 0' в конце строк чтения? – BDL
'GLchar * vertexSource = new GLchar [len];' Вы забыли удалить их? Потому что это очень важно. Это не ваша проблема, но это все еще важно. –
@BDL: Я пропустил это, но кажется, что «glCompileShader()» не возражает, если отсутствует ограничитель строки, поскольку вершинный шейдер компилируется отлично. Я добавил его в любом случае, поэтому спасибо за этот намек. – georgjz