glBindAttribLocation下一步是什么?

时间:2014-06-04 04:18:25

标签: c++ opengl glfw

我很难找到不需要glew或过剩的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);

现在如何将三角形的顶点传递到着色器?

更多代码,我正在调用我自己的库来读取文件,因此如果有人试图运行它,textread将无效

#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 个答案:

答案 0 :(得分:3)

你将顶点传递到着色器&#34;通过进行绘制调用,通常是glDrawArrays()。

当glDrawArrays()命中时,当前绑定的顶点数组被发送到GPU-land。顶点将由当前绑定的程序(您似乎已经计算出来)处理,并且每个顶点属性将根据着色器变量的属性索引是否与顶点属性匹配而流入顶点着色器变量&#39 ; s glVertexAttribPointer()&#34; index&#34;参数(你似乎正在计算出来)。

所以,查看glVertexAttribPointer()来描述你的顶点数组,glEnableAttributeArray()使你的数组​​顶点能够在下一次绘制调用时发送,然后glDrawArrays()来启动聚会。

答案 1 :(得分:1)

您无需调用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);
}