GLFW GLSL OPENGL ВОПРОСЫ - PullRequest
       75

GLFW GLSL OPENGL ВОПРОСЫ

0 голосов
/ 10 ноября 2019

это одна из нескольких попыток создания простого рендерера OpenGL с использованием GLFW. Я проверил проверки ошибок с помощью GL_INFO_LOG_LENGTH и прочее, и я в основном использую все версии ARB в моем коде, но для удобства чтения я вынул его. у меня есть только один код, который, кажется, работает на полпути правильно, но для меня синтаксис этого является самым грязным из всех. и мне просто интересно, что я пропускаю или делаю глупости, или я не знаю ..

также я не уверен насчет версии в файлах шейдеров. они описывают версию openGL или версию GLSL ??

, и я попробовал

layout(location=0) in vec4 position;

вместо

in layout(location=0) vec4 position;

это, казалось, не имело значения! есть ли разница ?? это что-то нелегальное ??

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


main.h

#include <GL/glew.h>
#include <GLFW/glfw3.h>

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

int WIDTH = 800;
int HEIGHT = 640;
const char* WINDOW_TITLE = "Window Title";

/*  Attributes:  Position, Normal, Color  0,1,2 0,3,4  */

GLfloat vertex_array[] =
{
+0.0f,  +0.0f,  -1.0f,  +1.0f,  /*  Vertex 0, Attribute: Position   */
+1.0f,  +0.0f,  +0.0f,  +1.0f,  /*  Vertex 0, Attribute: Color      */

+1.0f,  +1.0f,  -1.0f,  +1.0f,  /*  Vertex 1, Attribute: Position   */
+0.0f,  +1.0f,  +0.0f,  +1.0f,  /*  Vertex 1, Attribute: Color      */

-1.0f,  +1.0f,  -1.0f,  +1.0f,  /*  Vertex 2, Attribute: Position   */
+0.0f,  +0.0f,  +1.0f,  +1.0f,  /*  Vertex 2, Attribute: Color      */

-1.0f,  -1.0f,  -1.0f,  +1.0f,  /*  Vertex 3, Attribute: Position   */
+0.0f,  +0.0f,  +0.0f,  +1.0f,  /*  Vertex 3, Attribute: Color      */

+1.0f,  -1.0f,  -1.0f,  +1.0f   /*  Vertex 4, Attribute: Position   */
+0.0f,  +0.0f,  +0.0f,  +1.0f,  /*  Vertex 4, Attribute: Color      */
};

const char* vertex_shader_code =
"#version 410 core\n"
"in layout(location=0) vec4 position;\n"
"in layout(location=1) vec4 color;\n"
"out vec4 Color;\n"
"void main()\n"
"{\n"
"gl_Position = position;\n"
"Color = color;\n"
"}";

const char* fragment_shader_code =
"#version 410 core\n"
"in vec4 Color;\n"
"out vec4 color_out;\n"
"void main()\n"
"{\n"
"color_out = vec4(Color);\n"
"}";

unsigned int number_of_lines = 0;

char *vertex_shader_file_path = "/Users/sam/Documents/Xcode/GLSL_test 7/GLSL_test/vert.glsl";

char *fragment_shader_file_path = "/Users/sam/Documents/Xcode/GLSL_test 7/GLSL_test/frag.glsl";

void init(void);
extern void draw_graphics(void);

main.c

char** line_read(char* file_name, unsigned int* number_of_lines)
{
#if 0
printf("debug: read_lines()\n");
#endif

size_t number_of_lines_default = 1;

FILE *input_file = NULL;
input_file = fopen(file_name, "r");
if (input_file == NULL)
{
    fprintf(stderr, "Failed to open input file for reading!\n");
    exit(1);
}

char** lines = NULL;
#if 0
lines = (char**)malloc(sizeof(char*) * number_of_lines_default);        /*  malloc version  */
#endif

#if 1
lines = (char**)calloc(number_of_lines_default ,sizeof(char*));         /*  calloc version  */
#endif

int i = 0;
while(1)
{
    if(i == number_of_lines_default)
    {
        char** lines_new = NULL;
        lines_new = (char**)realloc(lines, number_of_lines_default * 2 * sizeof(char*) );
        if(lines_new == NULL)
        {
            fprintf(stderr, "Failed to realloc more lines!\n");
            exit(1);
        }
        lines = lines_new;
        number_of_lines_default *= 2;
    }

    size_t line_length_default = 1;
#if 0
    lines[i] = malloc(line_length_default * sizeof(char));
#endif

#if 1
    lines[i] = calloc(line_length_default, sizeof(char));
#endif
    if(lines[i] == NULL)
    {
        fprintf(stderr, "Failed to alloc lines!\n");
        exit(1);
    }
    if(getline(&lines[i], &line_length_default, input_file) == EOF)
    {
        break;
    }

    i++;
}
*number_of_lines = i;
fclose(input_file);
return lines;
};

void draw_graphics(void)
{
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glViewport(0, 0, WIDTH, HEIGHT);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
};

int main(int argc, char **argv)
{

glfwInit();

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

GLFWwindow* window = NULL;
window = glfwCreateWindow(WIDTH, HEIGHT, WINDOW_TITLE, NULL, NULL);
if(window == NULL)
{
    fprintf(stderr, "failed to initialize a GLFW window");
}
glfwMakeContextCurrent(window);

glfwGetFramebufferSize(window, &WIDTH, &HEIGHT);

/*  GLEW  */

glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit() )
{
    printf("Error: failed to init GLEW!\n");

    return -1;
}

/*  VERSION  */

#if 0
/* get version info */
const GLubyte* renderer = glGetString(GL_RENDERER);     /*  get renderer string */
const GLubyte* version = glGetString(GL_VERSION);       /*  version as a string */
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported: %s\n\n", version);
#endif

/*  VERTEX BUFFER  */

#if 1
GLuint vertex_buffer_ID = 0;
glGenBuffers(1, &vertex_buffer_ID);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_ID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_array), vertex_array, GL_STATIC_DRAW);
/*  Position  */
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, 0);
/*  Color  */
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (char*)(sizeof(float) * 4));

/*  ELEMENT ARRAY / INDEX BUFFER  */

/*only use element or index!*/
GLuint element_array[] = {3,1,2, 0,3,4};
GLuint index_buffer_ID = 0;
glGenBuffers(1, &index_buffer_ID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_ID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_array), element_array, GL_STATIC_DRAW);

/*  SHADER - SETUP  */

GLuint vert_shader_ID = glCreateShader(GL_VERTEX_SHADER);
GLuint frag_shader_ID = glCreateShader(GL_FRAGMENT_SHADER);

/*  const GLchar* adapter[1];  */

/*  VERTEX SHADER  */

#if 0
adapter[0] = vertex_shader_code;
glShaderSource(vert_shader_ID, 1, adapter, 0);
#endif

const char **vertex_shader_code_1 = NULL;
vertex_shader_code_1 = (const char**)line_read(vertex_shader_file_path, &number_of_lines);
glShaderSource(vert_shader_ID, 1, vertex_shader_code_1, 0);

glCompileShader(vert_shader_ID);

/*  FRAGMENT SHADER  */

#if 0
adapter[0] = fragment_shader_code;
glShaderSource(frag_shader_ID, 1, adapter, 0);
#endif

const char **fragment_shader_code_1 = NULL;
fragment_shader_code_1 = (const char**)line_read(fragment_shader_file_path, &number_of_lines);
glShaderSource(frag_shader_ID, 1, fragment_shader_code_1, 0);

glCompileShader(frag_shader_ID);

/*  SHADER PROGRAM  */

GLuint program_ID = glCreateProgram();
glAttachShader(program_ID, vert_shader_ID);
glAttachShader(program_ID, frag_shader_ID);

glBindAttribLocation(program_ID, 0, "postion");

glLinkProgram(program_ID);

/*  PROGRAM VALIDATION  */

glValidateProgram(program_ID);

glUseProgram(program_ID);
#endif

glViewport(0, 0, WIDTH, HEIGHT);
glfwSwapInterval(1);

while (!glfwWindowShouldClose(window))
{
    glClearColor(0.0f, 1.0f, 1.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    draw_graphics();

    glfwSwapBuffers(window);
    glfwPollEvents();
}

glDeleteProgram(program_ID);
glDeleteShader(frag_shader_ID);
glDeleteShader(vert_shader_ID);
glDeleteBuffers(1, &vertex_buffer_ID);
glDeleteVertexArrays(1, &index_buffer_ID);


glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

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

#version 410 core\r\n

in layout(location=0) vec4 position;
in layout(location=1) vec4 color;

out vec4 Color;

void main()
{
    gl_Position = position;
    Color = color;
}

фрагментный шейдер

#version 410 core\r\n

out vec4 color_out;
in vec4 Color;

void main()
{
    color_out = vec4(Color);
}

1 Ответ

1 голос
/ 10 ноября 2019

Если вы используете профиль совместимости Контекст OpenGL

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

, тогда ваш код будет работать. Обратите внимание, что Прямая совместимость не имеет значения для OpenGL версии 3.3 и более поздних.

Но поскольку вы используете контекст OpenGL основного профиля,

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

вам нужно создать Vertex Array Object . Обратите внимание, что объект Vertex Array (0) по умолчанию недопустим в профиле cor.
См. Также Спецификация вершин .

Создание и связывание именованного объекта Vertex Array перед спецификациеймассив общих данных атрибутов вершин (см. объект буфера вершин ) и индексные буферы (что указано в VAO) для решения проблемы:

/* VERTEX ARRAY OBJECT */

GLuint vertex_arrray_ID = 0;
glGenVertexArrays(1, & vertex_arrray_ID);
glBindVertexArray(vertex_arrray_ID);

/*  VERTEX BUFFER  */

// [...]

/*  ELEMENT ARRAY / INDEX BUFFER  */

// [...]

Примечание:

В соответствии с OpenGL Shading Language 4.60 Спецификация - 4.4. Спецификаторы макета (стр. 62), квалификатор макета должен находиться перед классификатором интерфейса:

[...] они могут появляться с отдельной переменной, объявленной с квалификатором интерфейса:

layout-qualifier interface-qualifier declaration ;
...