• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem ze zrozumienie kodu w OpenGL.

VPS Starter Arubacloud
0 głosów
247 wizyt
pytanie zadane 18 lipca 2020 w OpenGL, Unity przez tonn204 Mądrala (7,470 p.)

Cześć mam problem ze zrozumieniem kodu. Mianowicie skąd OpenGL wie, które liczby traktować jako punkty na osiach X i Y, a które jako kolory [patrz vertices]? Co się dzieje kiedy  w glVertexAttribPointer pierwszy argument ma wartość 1 i co to oznacza, bo w docs.gl pisze o jakimś index, ale nie rozumiem o jaki index chodzi. O co chodzi  w glVertexAttribPointer, gdy pierwszy argument utawiony jest na 1 i dlaczego ostatni ustawiony jest na (void*)(3 * sizeof(float) i co te argumenty oznaczają? Dzięki za odpowiedzi.

 

 

Plik główny:

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

#include <iostream>
#include <fstream>
#include <string>

static unsigned int CompileShader(unsigned int type, std::string source)
{
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); 
        char* message = (char*)_malloca(length * sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << "shader" << std::endl;
        std::cout << message << std::endl;
        glDeleteShader(id);

        return 0;

    }

    return id;
}

static unsigned int CreateShader(const std::string& vertexShader, const std::string fragmentShader)
{
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

std::string readFromFile(const char* pathToFile)
{
    std::string content;
    std::ifstream fileStream(pathToFile, std::ios::in);

    if (!fileStream.is_open()) {
        std::cerr << "Could not read file " << pathToFile << ". File does not exist." << std::endl;
        return "";
    }

    std::string line;
    while (std::getline(fileStream, line)) {
        content.append(line + "\n");
    }

    fileStream.close();
    std::cout << content << std::endl;
    return content;
}
int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    //glfwSwapInterval(1);           // Update a scene per "x" frames.

    if (glewInit() != GLEW_OK)
        std::cout << "Error" << std::endl;

    std::cout << glGetString(GL_VERSION) << std::endl;
    
    float vertices[] = {
        // positions            // Colors
        0.0f,  0.5f, 0.0f,      1.0f, 0.0f, 0.0f, // bottom right
       -0.5f, -0.5f, 0.0f,      0.0f, 1.0f, 0.0f, // bottom left
        0.5f, -0.5f, 0.0f,      0.0f, 0.0f, 1.0f  // top
    };

    unsigned int VBO;

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    std::string vertexShaderSource = readFromFile("vertexShader.shader");
    std::string fragmentShaderSource = readFromFile("fragmentShader.shader");

    unsigned int shaderProgram = CreateShader(vertexShaderSource, fragmentShaderSource);

    int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {

        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);

        glDrawArrays(GL_TRIANGLES, 0, 3);
        
        float timeValue = glfwGetTime();
        float greenValue = sin(timeValue) / 2.0f + 0.5f;

        glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

Vertex shader:

#version 330 core
layout(location = 0) in vec3 aPos;   // the position variable has attribute position 0
layout(location = 1) in vec3 aColor; // the color variable has attribute position 1

out vec3 ourColor; // output a color to the fragment shader

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor; // set ourColor to the input color we got from the vertex data
}

Fragment shader:

#version 330 core
out vec4 FragColor;
in vec3 ourColor;

void main()
{
    FragColor = vec4(ourColor, 1.0);
}

 

2 odpowiedzi

+1 głos
odpowiedź 19 lipca 2020 przez Patrycjerz Mędrzec (192,320 p.)
wybrane 19 lipca 2020 przez tonn204
 
Najlepsza
Funkcja `glVertexAttribPointer` definiuje, w jaki sposób dane atrybutów wierzchołków są przechowywane w buforze.

Jej pierwszym argumentem jest indeks, który umożliwia powiązanie definicji atrybutu ze zmienną wejściową shadera wierzchołków. Np. atrybut koordynatów wierzchołka ma indeks równy 0, zaś w kodzie shadera zmienna `aPos` ma taki indeks ustawiony w `layout(location = 0)`. Analogiczna sytuacja występuje w przypadku zmiennej `aColor`, która ma przypisany indeks o wartości 1.

Ostatni argument funkcji to początkowe przesunięcie. Aby zdefiniować atrybut, potrzebujesz wiedzieć, gdzie w pamięci bufora zaczyna się jego pierwsze wystąpienie. Pierwszy zestaw koordynatów wierzchołka znajduje się na początku bufora, zaś pierwszy zestaw wartości kolorów dopiero po tych trzech współrzędnych. Definiujesz to jako `(void*)(3 * sizeof(float))`, czyli potrójny rozmiar pojedynczego koordynatu. Moim zdaniem lepiej używać typedefu `GLfloat`, który bezpośrednio odpowiada `GL_FLOAT`, zamiast typu `float`, ale w przypadku kompilacji na x86 nie powinno to robić większej różnicy.
komentarz 19 lipca 2020 przez tonn204 Mądrala (7,470 p.)
Wielkie dzięki !
+1 głos
odpowiedź 19 lipca 2020 przez adrian17 Ekspert (349,420 p.)

Polecam ten poradnik:

https://learnopengl.com/Getting-started/Hello-Triangle

https://learnopengl.com/Getting-started/Shaders

pierwszy argument ma wartość 1 i co to oznacza, bo w docs.gl pisze o jakimś index, ale nie rozumiem o jaki index chodzi

Z pierwszego linku:

  • The first parameter specifies which vertex attribute we want to configure. Remember that we specified the location of the position vertex attribute in the vertex shader with layout (location = 0). This sets the location of the vertex attribute to 0 and since we want to pass data to this vertex attribute, we pass in 0.

dlaczego ostatni ustawiony jest na (void*)(3 * sizeof(float) 

A to wyjaśnia ta część z drugiego linku:

Podobne pytania

0 głosów
1 odpowiedź 259 wizyt
pytanie zadane 1 sierpnia 2020 w OpenGL, Unity przez tonn204 Mądrala (7,470 p.)
0 głosów
1 odpowiedź 112 wizyt
0 głosów
0 odpowiedzi 112 wizyt
pytanie zadane 14 lipca 2020 w OpenGL, Unity przez tonn204 Mądrala (7,470 p.)

93,008 zapytań

141,975 odpowiedzi

321,256 komentarzy

62,350 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...