Хобрук: Ваш путь к мастерству в программировании

Почему этот код OpenGL не дает ошибок, но ничего не выводит на экран

В предисловии я пишу свой OpenGL на D, используя Derelict. Однако он должен быть почти таким же, как OpenGL с C++, поскольку вызовы функций идентичны. Несмотря на это, я не понимаю, почему мой код ничего не выводит на экран, поскольку моя шейдерная программа не выдает ошибок. Извините за большой дамп кода, но я не могу изолировать проблему. Мой класс шейдера выглядит следующим образом:

module shader;
import std.stdio;
import std.string;
import derelict.sdl2.sdl;
import derelict.opengl3.gl3;

class Shader
{
    this(string file_name)
    {
        // Load OpenGL versions 1.0 and 1.1.
        DerelictGL3.load();
        // Load versions 1.2+ and all supported ARB and EXT extensions.
        DerelictGL3.reload();

        program = glCreateProgram();

        shaders[0] = create_shader(load_shader(file_name ~ ".vs"), GL_VERTEX_SHADER);
        shaders[1] = create_shader(load_shader(file_name ~ ".fs"), GL_FRAGMENT_SHADER);

        for (int i = 0; i < NUM_SHADERS; i++)
            glAttachShader(program, shaders[i]);

        glBindAttribLocation(program, 0, "position"); 

        glLinkProgram(program);

        check_shader_error(program, GL_LINK_STATUS, true, "Error linking shader!");

        glValidateProgram(program);

        check_shader_error(program, GL_VALIDATE_STATUS, true, "Error invalid shader!");
    }
    void bind()
    {
        glUseProgram(program);
    }
    string load_shader(string shader_name) {
        string output;
        auto f = File(shader_name);         // open file for reading,
        scope(exit) f.close();              //   and close the file when we're done.
                                            //   (optional)
        foreach (str; f.byLine)             // read every line in the file,
        {
            output ~= str;
            output ~= "\n";
        }

        ///writeln(output);
        return output;                      //   and return it
    }
    GLuint create_shader(string text, GLenum shader_type)
    {
        GLuint shader = glCreateShader(shader_type);

        GLchar* shader_source_strings[1];
        GLint shader_source_strings_lengths[1];

        shader_source_strings[0] = cast(char*)(text);
        shader_source_strings_lengths[0] = (cast(int)text.length);

        glShaderSource(shader, 1, shader_source_strings.ptr, shader_source_strings_lengths.ptr);
        glCompileShader(shader);

        check_shader_error(shader, GL_COMPILE_STATUS, false, "Error compiling shader!");

        return shader;
    }
    void check_shader_error(GLuint shader, GLuint flag, bool isProgram, string error_message)
    {
        GLint success = 0;
        GLchar[1024] error;

        if (isProgram)
            glGetProgramiv(shader, flag, &success);
        else
            glGetShaderiv(shader, flag, &success);

        if (success == GL_FALSE)
        {
            if(isProgram)
                glGetProgramInfoLog(shader, error.sizeof, null, error.ptr);
            else
                glGetProgramInfoLog(shader, error.sizeof, null, error.ptr);
            writeln(error_message ~ error ~ "\n");
        }
    }
private:
    static const int NUM_SHADERS = 2;
    GLuint program;
    GLuint shaders[NUM_SHADERS];
}

И мой класс Mesh:

module mesh;    
import std.stdio;
import derelict.opengl3.gl3;
import vertex;
class Mesh
{
    this(Vertex* vertices, int num_vertices)
    {

        // Load OpenGL versions 1.0 and 1.1.
        DerelictGL3.load();
        // Load versions 1.2+ and all supported ARB and EXT extensions.
        DerelictGL3.reload();

        draw_count = num_vertices;

        glGenVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);

        glGenBuffers(NUM_BUFFERS, vertex_array_buffers.ptr);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffers[POSITION_VB]);
        glBufferData(GL_ARRAY_BUFFER, num_vertices * vertices[0].sizeof, vertices, GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glVertexAttribPointer(cast(GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, cast(void*)0);

        glBindVertexArray(0);
    }
    void draw()
    {
        glBindVertexArray(vertex_array_object);

        glDrawArrays(GL_TRIANGLES, 0, draw_count);

        glBindVertexArray(0);
    }
private:
    enum 
    {
        POSITION_VB,
        NUM_BUFFERS
    };

    GLuint vertex_array_object;
    GLuint vertex_array_buffers[NUM_BUFFERS];
    int draw_count;
}
10.02.2015

  • Вы проверяете ошибку компиляции шейдера, но нигде не вызываете glError(). Вызов возвращает ошибку? 10.02.2015
  • Вы имеете в виду glGetError(), потому что я вызвал это, и он возвращает 0. 10.02.2015
  • Извините, да, я имел в виду glGetError(). 10.02.2015
  • Да, он возвращает 0, поэтому я не вижу, какая ошибка присутствует. 10.02.2015
  • Что еще у вас есть в основной программе? Вы glFlush делаете? 10.02.2015
  • Я не вызываю glFlush. Мой main просто инициализирует окно, сетку, классы шейдеров и вызывает shaper.bind() и mesh.draw() в цикле while во время работы контекста. 11.02.2015
  • Что я обычно делаю в этом контексте, так это начинаю с простого. Сделайте просто glClearColor(1.0, 1.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); и посмотрите, рисуется ли вообще что-нибудь. Если это так, попробуйте нарисовать один треугольник только с помощью сквозного вершинного шейдера и фрагментного шейдера, который просто выводит сплошной цвет. Если это сработает, то подставьте свои настоящие шейдеры и т.д. 11.02.2015
  • Это на самом деле то, что я делаю. Кажется, это не работает. Если это будет полезно, вот ссылка на проект на Github. 11.02.2015
  • Так что очистка цвета экрана тоже не работает? Я не знаю, как с этим справляется SDL, но, возможно, вам придется вызывать glViewport при изменении размера окна. 12.02.2015
  • О нет, я имею в виду, что очистка экрана работает, но добавление моих собственных шейдеров не работает. 12.02.2015

Ответы:


1

Я нашел ответ, у меня было несколько избыточных вызовов при загрузке библиотек OpenGL с помощью загрузчика функций, который я использовал (Derelict), и я неправильно представлял свой массив вершин. Я нашел помощь на форуме Digital Mars здесь.

13.02.2015
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

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

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..