Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[GLFW GLAD] System Modeli

Ostatnio zmodyfikowano 2024-12-30 16:26
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[GLFW GLAD] System Modeli
» 2024-12-29 20:05:36
Witam. Zacząłem uczyć się OpenGL GLFW GLAD. Jestem na trzeciej lekcji https://learnopengl.com/Getting-started/Hello-Triangle. Nauczyłem się jak generować trójkąt, ale od razu wpadłem na pomysł, by ten trójkąt opakować w klasę. Nie do końca rozumiem jak działa VBO, EBO oraz VAO. Czy dobrze opakowałem trójkąt w klasę ?

C/C++
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

const char * vertex_shader_source = R"( #version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } )";

const char * fragment_shader_source = R"( #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } )";

GLFWwindow * window;
unsigned int vertex_shader;
unsigned int fragment_shader;
unsigned int shader_program;

class Model {
public:
   
unsigned int VAO; // VERTEX ARRAY OBJECTS (VAO stores information about how data in VBO and EBO is used)
   
unsigned int VBO; // VERTEX BUFFER OBJECTS (VERTEXES)
   
unsigned int EBO; // ELEMENT BUFFER OBJECTS (INDICES)
   
unsigned int program;
   
   
Model() {
       
    }
   
   
~Model() {
       
glDeleteVertexArrays( 1, & VAO );
       
glDeleteBuffers( 1, & VBO );
       
glDeleteBuffers( 1, & EBO );
   
}
   
   
void Load() {
       
       
float vertices[ ] = {
           
0.5f, 0.5f, 0.0f,
           
0.5f, - 0.5f, 0.0f,
           
- 0.5f, - 0.5f, 0.0f,
           
- 0.5f, 0.5f, 0.0f
       
};
       
       
unsigned int indices[ ] = {
           
0, 1, 3, // first Triangle
           
1, 2, 3 // second Triangle
       
};
       
       
glGenVertexArrays( 1, & VAO ); // VAO
       
glGenBuffers( 1, & VBO ); // ...
       
glGenBuffers( 1, & EBO ); // ...
       
glBindVertexArray( VAO ); // VAO
       
        // VBO - VERTEXES
       
glBindBuffer( GL_ARRAY_BUFFER, VBO );
       
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
       
       
// EBO - INDICES
       
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, EBO );
       
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
       
       
//
       
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ),( void * ) 0 );
       
glEnableVertexAttribArray( 0 );
       
       
glBindBuffer( GL_ARRAY_BUFFER, 0 );
       
       
glBindVertexArray( 0 );
       
       
// load the program
       
program = shader_program;
   
}
   
   
void draw() {
       
glUseProgram( shader_program );
       
glBindVertexArray( VAO );
       
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
   
}
   
}
;

void window_set_size( int width, int height ) {
   
glViewport( 0, 0, width, height );
}

void events()
{
   
if( glfwGetKey( window, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
       
 glfwSetWindowShouldClose( window, true );
   
}

void loadShaders() {
   
vertex_shader = glCreateShader( GL_VERTEX_SHADER );
   
glShaderSource( vertex_shader, 1, & vertex_shader_source, NULL );
   
glCompileShader( vertex_shader );
   
   
fragment_shader = glCreateShader( GL_FRAGMENT_SHADER );
   
glShaderSource( fragment_shader, 1, & fragment_shader_source, NULL );
   
glCompileShader( fragment_shader );
}

void deleteShaders() {
   
glDeleteShader( vertex_shader );
   
glDeleteShader( fragment_shader );
}

void loadPrograms() {
   
shader_program = glCreateProgram();
   
glAttachShader( shader_program, vertex_shader );
   
glAttachShader( shader_program, fragment_shader );
   
glLinkProgram( shader_program );
}

void deletePrograms() {
   
glDeleteProgram( shader_program );
}

int main()
{
   
// initialize glfw
   
glfwInit();
   
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
   
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
   
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
   
   
// create window
   
window = glfwCreateWindow( 800, 600, "LearnOpenGL", NULL, NULL );
   
if( window == NULL )
   
{
       
std::cout << "Failed to create GLFW window" << std::endl;
       
glfwTerminate();
       
return - 1;
   
}
   
   
// set the context
   
glfwMakeContextCurrent( window );
   
   
// initialize glad
   
if( !gladLoadGLLoader(( GLADloadproc ) glfwGetProcAddress ) )
   
{
       
std::cout << "Failed to initialize GLAD" << std::endl;
       
return - 1;
   
}
   
   
loadShaders();
   
loadPrograms();
   
deleteShaders();
   
   
Model * model = new Model();
   
model->Load();
   
   
// main loop
   
while( !glfwWindowShouldClose( window ) )
   
{
       
       
events();
       
       
// render
       
glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
       
glClear( GL_COLOR_BUFFER_BIT );
       
       
model->draw();
       
       
glfwSwapBuffers( window );
       
glfwPollEvents();
   
}
   
   
// CLEAR THE MEMORY
   
delete model;
   
deletePrograms();
   
   
glfwTerminate();
   
return 0;
}
P-182000
DejaVu
» 2024-12-30 09:26:08
ChatGPT 4o:
Przejrzałem kod użytkownika z forum cpp0x.pl, który opakował rysowanie trójkąta w klasę `Model` z użyciem OpenGL, GLFW i GLAD. Ogólnie podejście jest poprawne, ale zauważyłem kilka kwestii, które warto poprawić:

1. **Konstruktor klasy `Model`:**
   Obecnie konstruktor jest pusty. Warto przenieść do niego inicjalizację VAO, VBO i EBO oraz kompilację shaderów, aby obiekt był gotowy do użycia zaraz po utworzeniu.

   ```cpp
   Model() {
       // Inicjalizacja VAO, VBO, EBO
       glGenVertexArrays(1, &VAO);
       glGenBuffers(1, &VBO);
       glGenBuffers(1, &EBO);

       // Kompilacja shaderów
       loadShaders();
       loadPrograms();
   }
   ```

2. **Metoda `Load`:**
   Nazwa sugeruje ładowanie danych, ale w rzeczywistości inicjalizuje bufory i ustawia atrybuty wierzchołków. Można rozważyć zmianę nazwy na bardziej opisową, np. `initializeBuffers()`.

   ```cpp
   void initializeBuffers() {
       // Kod inicjalizujący bufory
   }
   ```

3. **Zarządzanie shaderami:**
   Kompilacja shaderów odbywa się poza klasą `Model`. Warto przenieść tę funkcjonalność do klasy, aby była bardziej samodzielna.

   ```cpp
   class Model {
   private:
       unsigned int vertex_shader;
       unsigned int fragment_shader;
       unsigned int shader_program;

       void loadShaders() {
           // Kod kompilujący shadery
       }

       void loadPrograms() {
           // Kod linkujący program shaderów
       }

   public:
       // Reszta kodu
   };
   ```

4. **Czyszczenie zasobów:**
   W destruktorze usuwane są VAO, VBO i EBO. Należy również usunąć program shaderów, aby uniknąć wycieków pamięci.

   ```cpp
   ~Model() {
       glDeleteVertexArrays(1, &VAO);
       glDeleteBuffers(1, &VBO);
       glDeleteBuffers(1, &EBO);
       glDeleteProgram(shader_program);
   }
   ```

5. **Użycie `glBindBuffer`:**
   Po ustawieniu wskaźnika atrybutu wierzchołka (`glVertexAttribPointer`) wywoływane jest `glBindBuffer(GL_ARRAY_BUFFER, 0)`. W kontekście użycia EBO w VAO, nie jest to konieczne i może prowadzić do nieoczekiwanych zachowań.

   ```cpp
   // Po glVertexAttribPointer
   // glBindBuffer(GL_ARRAY_BUFFER, 0); // Niepotrzebne
   ```

6. **Obsługa błędów:**
   Brakuje sprawdzania błędów podczas kompilacji shaderów i linkowania programu. Dodanie odpowiednich mechanizmów diagnostycznych ułatwi debugowanie.

   ```cpp
   void checkCompileErrors(unsigned int shader, std::string type) {
       // Kod sprawdzający błędy kompilacji i linkowania
   }
   ```

7. **Korzystanie z nowoczesnych funkcji C++:**
   Rozważ użycie kontenerów standardowych, takich jak `std::vector`, do przechowywania danych wierzchołków i indeksów, co zwiększy czytelność i bezpieczeństwo kodu.

   ```cpp
   std::vector<float> vertices = {
       // Wierzchołki
   };

   std::vector<unsigned int> indices = {
       // Indeksy
   };
   ```

Podsumowując, kod jest na dobrej drodze, ale wprowadzenie powyższych poprawek zwiększy jego czytelność, bezpieczeństwo i zgodność z dobrymi praktykami programistycznymi.
P-182001
tBane
Temat założony przez niniejszego użytkownika
» 2024-12-30 13:18:56
Ok. Poprawiłem kod i teraz wygląda tak:

C/C++
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

const char * vertex_shader_source = R"( #version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } )";

const char * fragment_shader_source = R"( #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } )";

GLFWwindow * window;
unsigned int vertex_shader;
unsigned int fragment_shader;
unsigned int shader_program;

class Model {
public:
   
unsigned int VAO; // VERTEX ARRAY OBJECTS (VAO stores information about how data in VBO and EBO is used)
   
unsigned int VBO; // VERTEX BUFFER OBJECTS (VERTEXES)
   
unsigned int EBO; // ELEMENT BUFFER OBJECTS (INDICES)
   
unsigned int program;
   
   
Model() {
       
glGenVertexArrays( 1, & VAO ); // VAO
       
glGenBuffers( 1, & VBO ); // ...
       
glGenBuffers( 1, & EBO ); // ...
       
glBindVertexArray( VAO ); // VAO
   
}
   
   
~Model() {
       
glDeleteVertexArrays( 1, & VAO );
       
glDeleteBuffers( 1, & VBO );
       
glDeleteBuffers( 1, & EBO );
   
}
   
   
void Load() {
       
       
float vertices[ ] = {
           
0.5f, 0.5f, 0.0f,
           
0.5f, - 0.5f, 0.0f,
           
- 0.5f, - 0.5f, 0.0f,
           
- 0.5f, 0.5f, 0.0f
       
};
       
       
unsigned int indices[ ] = {
           
0, 1, 3, // first Triangle
           
1, 2, 3 // second Triangle
       
};
       
       
// VBO - VERTEXES
       
glBindBuffer( GL_ARRAY_BUFFER, VBO );
       
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
       
       
// EBO - INDICES
       
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, EBO );
       
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
       
       
//
       
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ),( void * ) 0 );
       
glEnableVertexAttribArray( 0 );
       
       
glBindVertexArray( 0 );
       
       
// load the program
       
program = shader_program;
   
}
   
   
void draw() {
       
glUseProgram( program );
       
glBindVertexArray( VAO );
       
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
   
}
   
}
;

void window_set_size( int width, int height ) {
   
glViewport( 0, 0, width, height );
}

void events()
{
   
if( glfwGetKey( window, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
       
 glfwSetWindowShouldClose( window, true );
   
}

void loadShaders() {
   
vertex_shader = glCreateShader( GL_VERTEX_SHADER );
   
glShaderSource( vertex_shader, 1, & vertex_shader_source, NULL );
   
glCompileShader( vertex_shader );
   
   
fragment_shader = glCreateShader( GL_FRAGMENT_SHADER );
   
glShaderSource( fragment_shader, 1, & fragment_shader_source, NULL );
   
glCompileShader( fragment_shader );
}

void deleteShaders() {
   
glDeleteShader( vertex_shader );
   
glDeleteShader( fragment_shader );
}

void loadPrograms() {
   
shader_program = glCreateProgram();
   
glAttachShader( shader_program, vertex_shader );
   
glAttachShader( shader_program, fragment_shader );
   
glLinkProgram( shader_program );
}

void deletePrograms() {
   
glDeleteProgram( shader_program );
}

int main()
{
   
// initialize glfw
   
glfwInit();
   
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
   
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
   
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
   
   
// create window
   
window = glfwCreateWindow( 800, 600, "LearnOpenGL", NULL, NULL );
   
if( window == NULL )
   
{
       
std::cout << "Failed to create GLFW window" << std::endl;
       
glfwTerminate();
       
return - 1;
   
}
   
   
// set the context
   
glfwMakeContextCurrent( window );
   
   
// initialize glad
   
if( !gladLoadGLLoader(( GLADloadproc ) glfwGetProcAddress ) )
   
{
       
std::cout << "Failed to initialize GLAD" << std::endl;
       
return - 1;
   
}
   
   
loadShaders();
   
loadPrograms();
   
   
Model * model = new Model();
   
model->Load();
   
   
// main loop
   
while( !glfwWindowShouldClose( window ) )
   
{
       
       
events();
       
       
// render
       
glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
       
glClear( GL_COLOR_BUFFER_BIT );
       
       
model->draw();
       
       
glfwSwapBuffers( window );
       
glfwPollEvents();
   
}
   
   
// CLEAR THE MEMORY
   
delete model;
   
deletePrograms();
   
deleteShaders();
   
   
glfwTerminate();
   
return 0;
}
P-182002
« 1 »
  Strona 1 z 1