Не удается правильно настроить атрибуты вершин в Opengl 2.x - PullRequest
0 голосов
/ 15 декабря 2018

Проблема: Я не могу заставить треугольник появляться.Я не могу правильно установить атрибуты вершины, используя OpenGL 2.0

Результат выполнения кода: Красное окно 600 * 800 без треугольника.

Цель: я пытаюсь:

  • связать позицию с массивом атрибутов 0, float x 2 (для начала)
  • связать цвет с массивом атрибутов1, int x 3
  • индексированные вершины.

Java-код:

package prot20;

import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glDrawElements;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL11.glGetString;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glOrtho;
import static org.lwjgl.opengl.GL11.glViewport;
import static org.lwjgl.opengl.GL20.glUseProgram;
import static org.lwjgl.system.MemoryUtil.NULL;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;

import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.opengl.GLCapabilities;

public class prot20_2 {
    private long window;
    private int width = 800;
    private int height = 600;

    public static void main(String[] args) {
        new prot20_2();
    }

    public prot20_2() {

        if (!glfwInit()) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }

        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        long monitor = glfwGetPrimaryMonitor();

        window = glfwCreateWindow(width, height, "Window20", NULL, NULL);
        if (window == NULL) {
            throw new AssertionError("Failed to create window");
        }

        glfwMakeContextCurrent(window);
        glfwSwapInterval(0);
        glfwShowWindow(window);

        GLCapabilities c = GL.createCapabilities();

        System.out.println(c.OpenGL20);
        System.out.println(glGetString(GL11.GL_VERSION));

        int program = util.createProgram(prot20_2.getSimpleVertexShaderCode(), prot20_2.getSimpleFragmentShaderCode());


        float[] vertices = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f };
        int[] color = { 0, 128, 128, 128, 0, 128, 128, 128, 0 };
        int[] indices = { 0, 1, 2 };

        FloatBuffer vb = this.toBuffer(vertices);
        IntBuffer ib = this.toBuffer(indices);
        IntBuffer cb = this.toBuffer(color);

        int vbo = glGenBuffers();
        int ibo = glGenBuffers();
        int cbo = glGenBuffers();

        // Position
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vb, GL_STATIC_DRAW);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
        glBindAttribLocation(program, 0, "position");
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        // Color
        glBindBuffer(GL_ARRAY_BUFFER, cbo);
        glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(0, 3, GL_INT, false, 0, 0);
        glBindAttribLocation(program, 1, "color");
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        // indices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib, GL_STATIC_DRAW);
        glEnableClientState(GL_INDEX_ARRAY);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        glUseProgram(program);

        while (glfwWindowShouldClose(this.window) == false) {
            glClearColor(1, 0, 0, 1);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glViewport(0, 0, width, height);
            glMatrixMode(GL_PROJECTION);

            float aspect = (float) width / height;
            glLoadIdentity();
            glOrtho(-aspect, aspect, -1, 1, -1, 1);

            // glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

            glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0L);

            glfwSwapBuffers(this.window);
            glfwPollEvents();

        }
        glDeleteBuffers(vbo);

    }

    private FloatBuffer toBuffer(float[] f) {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(f.length);
        buffer.put(f);
        buffer.flip();
        return buffer;
    }

    private IntBuffer toBuffer(int[] i) {
        IntBuffer buffer = BufferUtils.createIntBuffer(i.length);
        buffer.put(i);
        buffer.flip();
        return buffer;
    }
    public static String getSimpleFragmentShaderCode() {
        StringBuilder sb = new StringBuilder();
        sb.append("uniform vec3 color;\n");
        sb.append("void main(void) {\n");
        sb.append("  gl_FragColor = vec4(color.rgb, 1.0);");
        sb.append("}\n");
        return sb.toString();
    }

    public static String getSimpleVertexShaderCode() {
        StringBuilder sb = new StringBuilder();
        sb.append("uniform vec2 position;\n");
        sb.append("void main(void) {\n");
        sb.append("  gl_Position = vec4(position.xy,0.0,0.0);\n");
        sb.append("}\n");
        return sb.toString();
    }
}

Я искал документацию и примеры, но либо нахожу тривиальнымпримеры без атрибутов, цвета, индексов или шейдеров, или я нахожу сложный код, используя opengl 3+.Мне трудно найти хороший пример покрытия: opengl 2.1, включая шейдер, индекс, атрибут, цвет и текстуру.

1 Ответ

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

Если вы хотите нарисовать треугольник с цветом, связанным с каждой координатой вершины, то вам нужен вершинный шейдер с 2 атрибутами.Один для координаты вершины и один для цвета.Атрибут цвета должен быть передан из Вершинный шейдер в Фрагментный шейдер с помощью переменной varying.
Примечание, attribute и varying устарели, нодолжны быть использованы в GLSL версии 1.10, которая соответствует OpenGL версии 2.0.В «модере» OpenGL используются классификаторы типа (GLSL) in и out:

Вершинный шейдер

#version 110

attribute vec2 in_pos;
attribute vec3 in_col;  

varying vec3 v_volor;

void main()
{
    v_color = in_col;
    gl_Position = vec4(in_pos.xy, 0.0, 1.0);
}

Фрагмент шейдера

varying vec3 v_color;

void main()
{
    gl_FragColor = vec4(v_color.rgb, 1.0);
}

После того, как программа связана, вы должны получить индексы атрибутов in_pos и in_col по glGetAttribLocation:

int attr_pos = glGetAttribLocation(program, "in_pos");
int attr_col = glGetAttribLocation(program, "in_col");

Если вы хотите установить индексы атрибутов на glBindAttribLocation, то это должно быть сделано до того, как программа будет связана с glLinkProgram, потому чтоэто информация, которая обрабатывается в процессе связывания.

Цветовые каналы в OpenGL Shading Language (GLSL) должны находиться в диапазоне [0,0, 1,0], где RGB(0,0, 0,0, 0,0) полностью черный, а RGB (1,0, 1,0, 1,0) белый.Таким образом, атрибуты цвета должны быть значениями с плавающей запятой:

float[] vertices = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f };
float[] color    = { 0, 0.5f, 0.5f, 0.5f, 0, 0.5f, 0.5f, 0.5f, 0 };
int[]   indices  = { 0, 1, 2 };

FloatBuffer vb = this.toBuffer(vertices);
FloatBuffer cb = this.toBuffer(color);
IntBuffer   ib = this.toBuffer(indices);

Создать буферы массива и буфер индекса:

int vbo = glGenBuffers();
int cbo = glGenBuffers();
int ibo = glGenBuffers();

// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vb, GL_STATIC_DRAW);

// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);

// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Указать массивы данных общих атрибутов вершины:

// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(attr_pos);
glVertexAttribPointer(attr_pos, 2, GL_FLOAT, false, 0, 0);

// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glEnableVertexAttribArray(attr_col);
glVertexAttribPointer(attr_col, 3, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

Для рисования объекта программный объект должен быть установлен по glUseProgram, а буфер элемента должен быть привязан:

glUseProgram(program);

while (glfwWindowShouldClose(this.window) == false) {

    // ....

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0L);

    // .....
}

Примечание, исправленоатрибуты -функции (glVertexPointer, ...), возможности клиента (glEnableClientState / glDisableClientState) и стек с фиксированной матрицей функций (glMatrixMode, glLoadIdentity, ...) не действуют, когда шейдериспользуется такая программа.

Если вы хотите использовать матричные преобразования, то вы должны использовать Унифицированные переменные типа mat4 и установить собственные матрицы проекции, вида и модели -например, Matrix4f библиотека.

...