Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Правильная отрисовка объекта

Правильная отрисовка объекта

Поделиться
kertis138Пользовательwww22 июня 201721:41#0
Здравствуйте!

Собственно решил попробовать написать обертку для рендеринга простых геометрических объектов по вершинам.
Написал все это и появилось несколько вопросов.

Вот сам код, который, как я подозреваю, не совсем корректен (хотя рисует простые фигуры нормально):

class PoligonMesh2D
{
public:
  enum BufferFlag
  {
    STATIC = GL_STATIC_DRAW,
    DYNAMIC = GL_DYNAMIC_DRAW,
    STREAM = GL_STREAM_DRAW
  };

public:
  PoligonMesh2D(GLfloat* vertexArray, unsigned size)
  {
    _pVertexArray = vertexArray;
    _pSize = size;
    //Правильное место для инициализации VBO/VBA?
    glGenVertexArrays(1, &_pVAOId);
    glGenBuffers(1, &_pVBOId);
  }

  ~PoligonMesh2D()
  {
    freeBuffer();
  }

  void initBuffer(BufferFlag flag = STATIC) const
  {
    glBindVertexArray(_pVAOId);
    glBindBuffer(GL_ARRAY_BUFFER, _pVBOId);
    glBufferData(GL_ARRAY_BUFFER, _pSize * sizeof(GLfloat), _pVertexArray, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (_pSize/3) * sizeof(GLfloat), static_cast<GLvoid*>(nullptr));
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
  }

  void freeBuffer() const
  {
    glDeleteVertexArrays(1, &_pVAOId);
    glDeleteBuffers(1, &_pVBOId);
  }

  void render() const
  {
    glBindVertexArray(_pVAOId);
    glDrawArrays(GL_TRIANGLES, 0, _pSize/3);
    glBindVertexArray(0);
  }

  //Если на разные части модели будут разные шейдеры
  void render(unsigned indBegin, unsigned size) const
  {
    glBindVertexArray(_pVAOId);
    glDrawArrays(GL_TRIANGLES, indBegin, size);
    glBindVertexArray(0);
  }

private:
  GLfloat* _pVertexArray;
  int _pSize = 0;

  GLuint _pVAOId;
  GLuint _pVBOId;
};


И тогда, имея функцию инициализации + рендеринга:

const int N = 3 * 3;
GLfloat vertices[N] = {
  -0.5f, -0.5f, 0.0f,
  0.5f, -0.5f, 0.0f,
  0.0f,  0.5f, 0.0f
};

void init()
{
  ourShader = new Shader("basic.vs","basic.frag");

  mesh = new PoligonMesh2D(vertices, N);
  mesh->initBuffer();
}

void render()
{
  glClearColor(0.8f, 1.0f, 0.6f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT);

  ourShader->use();
  mesh->render();

 //ИЛИ надо все делать тут?
 //mesh->initBuffer();
 //mesh->render();
 //mesh->freeBuffer();

  glFlush();
}

1) Вот у меня есть много объектов. Тогда я с самого начала выделяю под них место VBO, VBA - это верно? Или надо это делать только непосредственно перед рендерингом?
Какой тут порядок? Получается, что в активной памяти должны быть только те объекты, которые я собираюсь рендерить, а не все..

2) Как лучше хранить вершины? Если просто массивом, как у меня, то получается много одинаковых вершин. Видел решение через Element Buffer Object (EBO), но тогда нужен редактор, который выдаст такой формат + хранение вершин в файле.
Подскажите, где я не прав? (А то я подозреваю, что много где:) )

Правка: 22 июня 2017 21:45

kertis138Пользовательwww28 июня 201721:45#1
Некоторое время разбирался с этими буферами....
Вроде везде в начале создаются буферы под каждый меш, а затем эти буферы все время используются и отрисовываются. То есть они на протяжении загруженной сцены держат данные меша в видеопамяти, так?
А если нужно будет поменять данные, то придется перезаписывать буфера. Но это редкость, так как физика изменяет в основном матрицы трансформации, которые каждый кадр передаются в шейдер, верно?

Правка: 28 июня 2017 21:59

IvashkaПользовательwww28 июня 201722:09#2
Я недавно работаю с VBO но делаю так: Определяю входящие в рендер обьекты, собираю их в VАO после сборки рендерю, пока рендерю каждый обьект отдельно, но это пока разбираюсь с шейдерами, а вообще есть glDrawElements.
Вершины координаты текстур храню в одном флаконе и использую т.н. IBO (бинжу индексы вертексов), для обьектов подходит отлично если на одну вершину приходится одна текстурная координата. Недавно делал текст вот для текста это неудобно т.к. на одну точку приходятся 2 координаты текстуры это если делать текст лентой, пришлось переделывать и создавать по четыре точки на каждый символ.
kertis138Пользовательwww28 июня 201723:49#3
Ivashka
Когда мы копируем данные в буфер, они помещаются в видеопамять. И получается, что данные хранятся и в видеопамяти и в основной памяти программы, так? Это необходимо или можно в основной памяти не хранить данные о вершинах?
IvashkaПользовательwww29 июня 20171:49#4
kertis138
Ну по идее так, если у вас буфер не меняется пока приложение работает то нет причин хранить данные в оперативке.
kertis138Пользовательwww29 июня 201720:27#5
Ivashka
С этим вопросом разобрался. Спасибо)
IvashkaПользовательwww29 июня 201721:06#6
kertis138
Не стоит благодарности

/ Форум / Программирование игр / 2D графика и изометрия

2001—2017 © GameDev.ru — Разработка игр