openGL - рендеринг нескольких объектов с использованием разных шейдеров - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь нарисовать несколько оранжевых треугольников и наложить на них несколько черных линий (чтобы получился красивый куб). Я использую два шейдера для визуализации разных цветов:

оранжевый шейдер фрагмента ( фрагмент.glsl ), который я использую для рисования треугольников:

#version 120

void main() {
    gl_FragColor = vec4(0.8,0.4,0.1,1.0);
}

и черный шейдер, который я использую для рисования линий ( frag_lines.glsl ):

#version 120

void main() {
    gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}

Код, который я использую для генерации вращающегося куба (оранжевые треугольники + черные линии), выглядит следующим образом:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "matrix.h"
#include "shader.h"
#include "util.h"

int main(void) {
    if (!glfwInit()) {
        return -1;
    }

    GLFWwindow *window = glfwCreateWindow(800, 800, "HelloGL", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glEnable(GL_DEPTH_TEST);

    if (glewInit() != GLEW_OK) {
        glfwTerminate();
        return -1;
    }

    GLuint program = load_program("shaders/vertex.glsl", "shaders/fragment.glsl");
    GLuint program_lines = load_program("shaders/vertex.glsl", "shaders/fragment_lines.glsl");
    GLuint position = glGetAttribLocation(program, "position");
    GLuint position_lines = glGetAttribLocation(program_lines, "position");
    GLuint matrix = glGetUniformLocation(program, "matrix");
    GLuint matrix_lines = glGetUniformLocation(program_lines, "matrix");


    float data[] = {
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
    };

    GLuint buffer = gen_buffer(sizeof(data), data);
    GLuint buffer_lines = gen_buffer(sizeof(data), data);

    while (!glfwWindowShouldClose(window)) {

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        float mat[16];
        mat_identity(mat);
        mat_translate(mat, 0, -0.5, 0);
        mat_rotate(mat, 0.1, 0.3, 1, glfwGetTime());
        mat_ortho(mat, -2, 2, -2, 2, -2, 2);


        glUniformMatrix4fv(matrix, 1, GL_FALSE, mat);
        glUniformMatrix4fv(matrix_lines, 1, GL_FALSE, mat);

        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glEnableVertexAttribArray(position);
        glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, buffer_lines);
        glEnableVertexAttribArray(position_lines);
        glVertexAttribPointer(position_lines, 3, GL_FLOAT, GL_FALSE, 0, 0);


        glUseProgram(program);
        glDrawArrays(GL_TRIANGLES, 0, 12*3);

        glUseProgram(program_lines);
        glDrawArrays(GL_LINES, 0, 12*3);

        glDisableVertexAttribArray(position);
        glDisableVertexAttribArray(position_lines);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

Однако, когда я запускаю этот код, я вижу только черные линии на экране. Если я поменяю порядок

glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 12*3);

glUseProgram(program_lines);
glDrawArrays(GL_LINES, 0, 12*3);

Тогда я вижу только оранжевые треугольники и никаких признаков черных линий.

Как настроить это так, чтобы были видны как грани куба (оранжевые треугольники), так и соответствующие ребра (черные линии)?

пс .:

Я использую Ubuntu 18.04.

Я знаю, что для повышения эффективности следует удалить дубликаты, но это простой пример.

Я знаю, что координаты линий немного глупы, они должны быть достаточно хороши, чтобы пример работал.

Код матрицы можно найти в https://github.com/fogleman/HelloGL

1 Ответ

0 голосов
/ 17 сентября 2018

Создайте две функции отрисовки, такие как

DrawCube()
{
 glUniformMatrix4fv(matrix, 1, GL_FALSE, mat);
 glBindBuffer(GL_ARRAY_BUFFER, buffer);
 glEnableVertexAttribArray(position);
 glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

 glUseProgram(program);
 glDrawArrays(GL_TRIANGLES, 0, 12*3);

 glUseProgram(0);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Проблема с вашим кодом заключается в том, что вы смешиваете шейдерные состояния для двух отрисовок.Тот же отдельный и напишите код для DrawLines () , и они в функции рендеринга просто вызывают их обоих.

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