Шейдеры GLSL не компилируются, даже если у них нет очевидных ошибок - PullRequest
0 голосов
/ 22 ноября 2018

Я пытался текстурировать созданный куб и не могу увидеть текстуры.Я могу только видеть пустой рендеринг куба.Я попытался не использовать текстуру и сделать ее одним цветом, но это тоже не сработало.Я посмотрел на код, чтобы увидеть, есть ли что-то не так с ним, однако я не вижу никаких проблем, но я думаю, что это потому, что я новичок в OpenGL, так что, возможно, кто-то еще может увидеть, что не так с кодом.

Это мой код текстуры в конструкторе vertex_array:

vertex_array::vertex_array(float* vertex_buffer, int num_of_floats, const std::string& texture_file)
{
    glGenVertexArrays(1, &va_ID);
    glBindVertexArray(va_ID);

    glGenBuffers(1, &vb_ID);
    glBindBuffer(GL_ARRAY_BUFFER, vb_ID);
    glBufferData(GL_ARRAY_BUFFER, num_of_floats * sizeof(float), vertex_buffer, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(0 * sizeof(float)));
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    int width, height, nrChanells;
    stbi_set_flip_vertically_on_load(true);
    unsigned char* data = stbi_load(texture_file.c_str(), &width, &height, &nrChanells, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else {std::cout << "failed to load texture" << std::endl;}
    stbi_image_free(data);

    glGenBuffers(1, &ib_ID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib_ID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_buffer), index_buffer, GL_STATIC_DRAW);
    glBindVertexArray(0);
}

Это мой шейдер:

#version 330 core

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texCoord;

out vec2 v_TexCoord;

uniform mat4 view;
uniform mat4 projection;

void main()
{
v_TexCoord = texCoord;
gl_Position = projection * view * position;
};

#version 330 core

layout(location = 0) out vec4 color;

in vec2 v_TexCoord;

uniform sampler2D u_Texture;

void main()
{
vec4 texColor = texture(u_Texture, v_TexCoord);
color = texColor;
//color = vec4(0.0, 0.7, 0.4, 1.0);
};

Это класс шейдера:

#include "shader.h"
#include <fstream>
#include <string>
#include <sstream>

shader::shader(const std::string& shader_file)
{
    std::ifstream file(shader_file);
    std::string line;
    std::stringstream shaders[2];
    std::string shader_type;

    while (getline(file, line))
    {
        if (line.find("#shader") != std::string::npos)
        {
            if (line.find("vertex") != std::string::npos)
                shader_type = "vertex";
            else if (line.find("fragment") != std::string::npos)
                shader_type = "fragment";
        }

        else
        {
            if (shader_type == "vertex")
            {
                shaders[0] << line << "\n";
                //std::cout << line << "\n";
            }
            else if (shader_type == "fragment")
            {
                shaders[1] << line << "\n";
                //std::cout << line << "\n";
            }
        }
    }

    s_ID = glCreateProgram();
    unsigned int vs_ID = glCreateShader(GL_VERTEX_SHADER);
    unsigned int fs_ID = glCreateShader(GL_FRAGMENT_SHADER);
    const char* vertex_shader = shaders[0].str().c_str();
    const char* fragment_shader = shaders[1].str().c_str(); 
    glShaderSource(vs_ID, 1, &vertex_shader, nullptr);
    glShaderSource(fs_ID, 1, &fragment_shader, nullptr);
    glCompileShader(vs_ID);
    glCompileShader(fs_ID);
    glAttachShader(s_ID, vs_ID);
    glAttachShader(s_ID, fs_ID);
    glLinkProgram(s_ID);
    glValidateProgram(s_ID);
    glDeleteShader(vs_ID);
    glDeleteShader(fs_ID);
}

void shader::bind()
{
    glUseProgram(s_ID);
}

void shader::unbind()
{
    glUseProgram(0);
}

и это мой основной код приложения:

vertex_array va_1(cube1, 40, "resources/blocks.png");
shader shader_1("src/shader1.shader");
va_1.bind();
shader_1.bind();

[Edit by Spektre]

после пика в GLSL шейдеров регистрирует проблему:

ERROR: 0:1: '' : syntax error: illegal extended ASCII character (0xdd)

, что означает неправильное кодирование где-то по пути

1 Ответ

0 голосов
/ 19 декабря 2018

Отсутствие цветов может означать проблемы с освещением / обычными или просто не скомпилированными / связанными шейдерами, что приводит к использованию фиксированной функции, которая по-разному использует места ввода, следовательно, нет цвета / текстуры и т. Д.

Прежде всего, проверьте GLSL логи, как это абсолютно необходимо.Даже небольшая ошибка, такая как отсутствие ; или неправильный символ, может помешать вам компилировать, и без проверки вы просто не знаете, что работает или нет.Посмотрите здесь:

После того, как вы это сделали, похоже, у вас возникли проблемы с кодировкой шейдеров:

ERROR: 0:1: '' : syntax error: illegal extended ASCII character (0xdd)

Есть ещепричины, которые могут вызвать это:

  1. ошибка в файле шейдера

    Если вы редактируете свой шейдер с помощью инструментов UNICODE или с помощью национальной клавиатуры или копируете вставку изWEB полученный файл может содержать «специальные» символы или даже весь файл может быть закодирован как UNICODE ( UTF8, UTF16 ).Это неправильно, так как драйвер gfx GLSL компилятор не может обработать такое.

    Поэтому проверьте файлы в шестнадцатеричном представлении (или напишите небольшой скрипт, который проверяет наличие кодов, отличных от ASCII, выше 127).

    кодировку UTF легко обнаружить здесь - это шестнадцатеричное представление UTF8 начала файла SVG:

    EF BB BF 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E | <?xml version
    

    Здесь другой SVG, но UTF16 на этот раз:

    FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00 | ˙ţ< ? x m l   v 
    

    Как видно из начальных 2-х байтов, это магическое число UTF , определяющее кодировку UTF UTF8 символ может быть 1 или более байтов.В UTF16 каждый символ имеет 2 байта.Это легко обнаружить.Но если ваш файл имеет только не ASCII символ (code>127), может быть очень трудно обнаружить и написать скрипт, который обнаружит его, будет более надежным.

    Однако сообщение об ошибке подсказываетваши проблемы в первой строке, поэтому вам не нужно искать весь файл, чтобы определить его ... Если вы используете Total Commander , нажмите [F3] в вашем файле шейдера, а затем нажмите [3], чтобы увидеть шестнадцатеричное представлениеили используйте любой другой инструмент просмотра в шестнадцатеричном формате.

  2. ошибка при загрузке файла в вашу программу

    Я не знаю, какой компилятор /IDE / платформа у вас есть, но если ваш компилятор поддерживает UNICODE, возможно, вы загружаете свой файл шейдера в некоторую строковую переменную, которая обеспечивает UNICODE.В этом случае вы не найдете ошибки в # 1 , но компилятор по-прежнему выбрасывает недопустимый символ.

    Чтобы подтвердить это после загрузки шейдера в строку, сохраните его в некотором файле ипроверьте правильность его кодирования (выполните для него # 1 ).

    Если регистр просто прекратите использовать строковую переменную, которая делает это, и вместо этого используйте массив 8-битных типов данных.Осторожно, если вы хотите использовать char, вы должны быть уверены, что это char, а не UNICODE Wide char !!!Не спрашивайте меня, как искать документацию к вашему компилятору / IDE.

    После того, как это будет решено (сохраненный файл стандартный ASCII текст), компиляция GLSL должна продолжитьсябез ошибок ...

  3. применение ASCII и кода шейдера внутри кода cpp

    Некоторые программы не используют файлы шейдеров.Вместо этого они хранят исходный код в виде константных строк в исходном коде приложения.Этот способ подвержен тем же проблемам, что и # 2 .Чтобы решить эту проблему, некоторые компиляторы вводят макрос, который сообщает компилятору, что строка является ASCII, а не UNICODE, и должна обрабатывать ее как таковую.Я не знаю, как называются макросы, но я видел их здесь, в SE / SO, в разных вопросах, связанных с GLSL.IIRC это было что-то вроде:

    const char *txt=TEXT('bla bla vla');
    

    но я не уверен, действительно ли это было просто TEXT или Text или что-то немного другое.Поэтому поищите в QA s ваш код ошибки или выполните ASCII или посмотрите в документации по вашему компилятору / IDE такие вещи.

Также распространеноПроблема новичков в том, что они создают целое приложение и только потом начинают его компилировать.ЭТО НЕ ПРАВИЛЬНО.Потому что после этого они проводят отладку вечности ...

Они должны создавать приложения постепенно.Так что начните с малого и при работе переходите к следующему шагу.Таким образом, если ошибка показывает свое 99% времени в только что добавленном новом коде, следовательно, нет необходимости в сложном поиске ...

Новый GL API, однако, препятствует этому подходу, так как вам необходим действительный контекст GL,VBO / VAO, загрузчик / генератор мешей, представление, шейдеры, совместимый драйвер gfx, прежде чем материал даже начнет что-то показывать.Это огромное количество возможных проблем одновременно.Вот почему я советую начинать со старого API, а затем по частям удалять новый ... Или вместо этого использовать какой-нибудь рабочий стартовый шаблон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...