glBindAttribLocation что дальше?

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

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

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

// vert
in vec3 vPosition;

void main()
{
    gl_Position = vec4(vPosition,1.0);
}


// Frag
out vec4 color;
void main()
{
    color = vec4(1.0,0.0,0.0,1.0);
}

Я не понимаю, что мне нужно делать после вызова glBindAttribLocation

glBindAttribLocation(p,0,"vPosition");
glUseProgram(p);

Теперь, как я могу передать вершины треугольника в шейдер?

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

#include <GLFW/glfw3.h>

#include <stdlib.h>
#include <stdio.h>

#include "src/textfile.h"

GLuint v,f,p;


void printLog(GLuint obj)
{
    int infologLength = 0;
    int maxLength;

    if(glIsShader(obj))
        glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
    else
        glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&maxLength);

    char infoLog[maxLength];

    if (glIsShader(obj))
        glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog);
    else
        glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog);

    if (infologLength > 0)
        printf("%s\n",infoLog);
}

static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

void setShaders() {

    char *vs = NULL,*fs = NULL;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);

    vs = textFileRead("toon.vert");
    fs = textFileRead("toon.frag");

    const char * ff = fs;
    const char * vv = vs;

    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);

    free(vs);free(fs);

    glCompileShader(v);
    glCompileShader(f);

    p = glCreateProgram();
    glAttachShader(p,f);
    glAttachShader(p,v);

    glLinkProgram(p);
    //glUseProgram(p);
}

int main(void)
{
    GLFWwindow* window;

    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        exit(EXIT_FAILURE);

    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);

    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    glfwSetKeyCallback(window, key_callback);

    while (!glfwWindowShouldClose(window))
    {
        int height, width;
        float ratio;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;
        glViewport(0, 0, width, height);
        setShaders();


        glBindAttribLocation(p,0,"vPosition");
        glUseProgram(p);
        /* Now What */


        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);

    glfwTerminate();
    exit(EXIT_SUCCESS);
}

2 ответа

Решение

Вы "передаете вершины в шейдеры", вызывая отрисовку, чаще всего glDrawArrays().

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

Итак, посмотрите в glVertexAttribPointer (), чтобы описать ваш массив вершин, glEnableAttributeArray (), чтобы разрешить отправку вашего массива вершин при следующем вызове отрисовки, и затем glDrawArrays(), чтобы начать вечеринку.

Вам не нужно вызывать glBindAttribLocation, вместо этого используйте glGetAttribLocation.

1 Определите переменную атрибута в вашем файле cpp

GLint vPosition

2 Связать шейдерные переменные

const char* attribute_name = "vPosition"; 
attribute_coord2d = glGetAttribLocation(p, attribute_name);

3 в файле вершинного шейдера, определите vPosition как переменную атрибута и используйте ее.

attribute vec3 vPosition;

void main()
{
    gl_Position = vec4(vPosition,1.0);
}
Другие вопросы по тегам