Форум программистов, компьютерный форум, киберфорум
Наши страницы
OpenGL
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
XRuZzz
Антикодер
1683 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
1

Отрисовать 2й объект с другими индексами(2 объекта в одном VAO)

30.06.2019, 21:13. Просмотров 1268. Ответов 9

Всем привет!

Первый объект отрисовывается нормально.
Хочу добавить 2й объект со своими индексами.
Правильно ли я понимаю, что индексы нужно положить в EBO(IBO) где хранятся индексы первого объекта? То есть в том же самом VAO.
Как объяснить 2ому объекту, что ему нужно брать индексы из EBO(IBO), которые находятся сразу за индексами первого объекта?
Код делаю по урокам:
Полезные ссылки по Haskell
Кликните здесь для просмотра всего текста
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
...
 
main = bracketGLFW $ do
...
  maybeWindow <- GLFW.createWindow winWidth winHeight winTitle Nothing Nothing
  case maybeWindow of
      Nothing -> putStrLn "Failed"
      Just window -> do
        (Right [vobj1, vobj2]) в†ђ loadModels "media" "obj" ["plane0", "cube2easy"]
        let
            (vss1, fss1) = getVertexList vobj1 [] []
            (vss2, fss2) = getVertexList vobj2 [] []
            listV1 = vss1 ++ colors
            listV2 = vss2 ++ colors_cube
...
        -- Enable key callback
        keyRef <- newIORef DS.empty
        GLFW.setKeyCallback window (Just $ keyCallback keyRef)
        -- Enable mouse use
        mouseRef <- newIORef $ MouseInfo Nothing (0,(-90)) (V3 0 0 (-1))
        GLFW.setCursorInputMode window GLFW.CursorInputMode'Disabled
        GLFW.setCursorPosCallback window (Just $ cursorPosCallback mouseRef)
        -- FOV controls
        fovRef <- newIORef 45
        GLFW.setScrollCallback window (Just $ scrollCallback fovRef)
        -- calibrate the viewport
        GLFW.makeContextCurrent (Just window)
        (x,y) <- GLFW.getFramebufferSize window
        glViewport 0 0 (fromIntegral x) (fromIntegral y)
        glEnable GL_DEPTH_TEST
 
-- ready and use our program
        eErrP <- programFromSources vs fs1
        shaderProgram1 <- case eErrP of
            Left e -> putStrLn e >> return 0
            Right p -> return p
 
        eErrP <- programFromSources vs fs2
        shaderProgram2 <- case eErrP of
            Left e -> putStrLn e >> return 0
            Right p -> return p
 
        let
            -- verticesSize = fromIntegral $ sizeOf (0.0 :: GLfloat) * (length vertices)
            listV1Size = fromIntegral $ sizeOf (0.0 :: GLfloat) * (length listV1)
            listV2Size = fromIntegral $ sizeOf (0.0 :: GLfloat) * (length listV2)
        
        verticesP1 <- newArray listV1
        verticesP2 <- newArray listV2
 
        let indicesSize1 = fromIntegral $ sizeOf (0 :: GLuint) * (length fss1)
        indicesP1 <- newArray (fmap (\x -> x - 1) fss1)
        let indicesSize2 = fromIntegral $ sizeOf (0 :: GLuint) * (length fss2)
        indicesP2 <- newArray (fmap (\x -> x - 1) fss2)
...
        usingVertexArray vao1 $ do
          vboP1 <- malloc
          glGenBuffers 1 vboP1
          vbo1 <- peek vboP1
          glBindBuffer GL_ARRAY_BUFFER vbo1
          glBufferData GL_ARRAY_BUFFER listV1Size (castPtr verticesP1) GL_STATIC_DRAW
 
          eboP1 <- malloc
          glGenBuffers 1 eboP1
 
          ebo1 <- peek eboP1
          glBindBuffer GL_ELEMENT_ARRAY_BUFFER ebo1
          glBufferData GL_ELEMENT_ARRAY_BUFFER indicesSize1 (castPtr indicesP1) GL_STATIC_DRAW
--          glBufferData GL_ELEMENT_ARRAY_BUFFER indicesSize2 (castPtr indicesP2) GL_STATIC_DRAW    -- Если расскоментировать то кажется что отрисовка начинается с вершин первого объекта
 
          glVertexAttribPointer 0 3 GL_FLOAT GL_FALSE threeFloats nullPtr
          glEnableVertexAttribArray 0
 
          glVertexAttribPointer 1 3 GL_FLOAT GL_FALSE threeFloats sizeVertexsOffset
          glEnableVertexAttribArray 1
...
          glBindBuffer GL_ARRAY_BUFFER vbo2
          glBufferData GL_ARRAY_BUFFER listV2Size (castPtr verticesP2) GL_STATIC_DRAW
 
          glVertexAttribPointer 2 3 GL_FLOAT GL_FALSE floatSize nullPtr
          glEnableVertexAttribArray 2
 
          glVertexAttribPointer 3 3 GL_FLOAT GL_FALSE threeFloats sizeVertexsOffset
          glEnableVertexAttribArray 3
 
        vaoP2 <- malloc
        glGenVertexArrays 1 vaoP2
        vao2 <- peek vaoP2
 
        loop window keyRef mouseRef fovRef vao1 vao2 shaderProgram1 shaderProgram2 0 defaultCamera

Когда я пытаюсь скопировать индексы 2го объекта в буфер, то кажется что отрисовка начинается с вершин первого объекта
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.06.2019, 21:13
Ответы с готовыми решениями:

WebGL перемещение объекта, изменение вершин в VAO
Всем добрый вечер. Можете подсказать, постараюсь как можно яснее описать свой вопрос. Я рисую...

Как отрисовать отдельный объект поверх других?
Здравствуйте. Пишу курсовую, первый опыт в OpenGL. Есть большая функция, которая рисует все...

Несколько vao в один vao
В общем, как объединить несколько уже существующих вао в один ? У них одинаковые атрибуты.

Можно ли отрисовать на 3D сцене ребра 3D объекта?
Как отобразить ребра 3D объекта, например куба. В WPF отрисовка происходит с помощью примитива -...

ShowModalDialog - не получается в виде параметров передать объект и в окне получателя его отрисовать
Есть элемент FORM ID= &quot;oForm&quot; First Name: INPUT id='ax' TYPE=&quot;text&quot; NAME=&quot;oFirstName&quot;...

9
Antikl
с++
509 / 358 / 173
Регистрация: 15.07.2015
Сообщений: 1,875
Завершенные тесты: 6
30.06.2019, 22:26 2
а если использовать один vao но два EBO(IBO) для каждого объекта ?
0
XRuZzz
Антикодер
1683 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
30.06.2019, 23:36  [ТС] 3
Цитата Сообщение от Antikl Посмотреть сообщение
а если использовать один vao но два EBO(IBO) для каждого объекта ?
Насколько я понял в одном VAO есть только один EBO(IBO), разве нет?
Если второй объект без EBO будет, то я смогу его отрисовать.
Может есть примерчег, в котором это проделывается(на любом языке, но чтобы ничего лишнего там не было)? Просто найти не могу.
Надеюсь понятно объясняю, а то я ещё тот объяснятель...
0
Antikl
с++
509 / 358 / 173
Регистрация: 15.07.2015
Сообщений: 1,875
Завершенные тесты: 6
01.07.2019, 00:36 4
Цитата Сообщение от XRuZzz Посмотреть сообщение
Насколько я понял в одном VAO есть только один EBO(IBO), разве нет?
да один vao один vbo или ebo
Цитата Сообщение от XRuZzz Посмотреть сообщение
Если второй объект без EBO будет, то я смогу его отрисовать.
создать один объект с vao и vbo, второй объект c vao2 ebo

так заюзать
C++
1
2
3
4
5
6
7
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
 
 
glBindVertexArray(sphereVAO);
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
1
01.07.2019, 00:36
XRuZzz
Антикодер
1683 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
01.07.2019, 01:28  [ТС] 5
С двумя VAO я уже умею, я как то подумал, что лучше запихать все объекты в один VAO. Ведь в VAO может быть много VBO...
0
_Develop
304 / 195 / 34
Регистрация: 24.01.2013
Сообщений: 571
01.07.2019, 13:05 6
Лучший ответ Сообщение было отмечено XRuZzz как решение

Решение

XRuZzz, последний параметр в функции glDrawElements() трактуется как смещение в байтах от начала индексного буфера.
Рисуй например так -
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, (void*)(indxStart * sizeof(GLuint)));
отступит от начала буфера indxStart индексов.

Или есть еще функция glDrawElementsBaseVertex() которая модифицирует сами индексы, добавляя определенное число.

Хотя обычно индексы считаются "легкими" данными. Можно иметь один большой VBO с геометрией сцены
и много индексных буферов (и VAO к ним).
Или даже формировать индексный буфер динамически на каждом кадре новый.
1
XRuZzz
Антикодер
1683 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
01.07.2019, 23:06  [ТС] 7
В принципе получилось, если использовать одну операцию копирования в буфер индексов. А если 2 до вроде бы последняя операция копирования переписывает первые индексы.
Ещё не научился добавлять данные в буфер...
0
_Develop
304 / 195 / 34
Регистрация: 24.01.2013
Сообщений: 571
02.07.2019, 00:24 8
Дописывать данные в буфер плохая практика.
Нужно сразу создавать буфер с запасом места, тогда можно перезаписывать данные либо с помощью glBufferSubData,
либо через glMapBuffer.
Или вообще старый буфер удалять а на его месте создавать новый нужного размера.
1
XRuZzz
Антикодер
1683 / 786 / 46
Регистрация: 15.09.2012
Сообщений: 2,898
03.07.2019, 18:17  [ТС] 9
А если у меня два прямоугольника в одном VBO. Мне обязательно располагать данные в VBO таким образом, чтобы обойтись одним вызовом glVertexAttribPointer для вершин и одним вызовом glVertexAttribPointer для цветов?
(то есть по одному вызову glVertexAttribPointer для каждой шейдерной переменной)
Haskell
1
2
3
4
5
glVertexAttribPointer 0 3 GL_FLOAT GL_FALSE (правильный период) (правильное смещение)
glEnableVertexAttribArray 0
 
glVertexAttribPointer 1 3 GL_FLOAT GL_FALSE (правильный период) (правильное смещение)
glEnableVertexAttribArray 1
Я же не могу расположить данные таким образом:
[(4 вершины подряд объекта 1), (4 цвета подряд объекта 1), (4 вершины подряд объекта 2), (4 цвета подряд объекта 2)]
glVertexAttribPointer же не позволит их разметить?
0
_Develop
304 / 195 / 34
Регистрация: 24.01.2013
Сообщений: 571
03.07.2019, 21:16 10
У тебя все равно два индексных буфера а значит и два VAO.
Для каждого VAO вызови по одному разу glVertexAttribPointer и все, каждый VAO запомнит свой адрес в буфере VBO.

А так как ты хочешь то нужно делать структуру для каждой вершины (положение, цает и т.д.) и записывать в VBO.
Тогда в буфере период будет всегда одинаков и данные упорядочены. Можно будет один раз вызвать glVertexAttribPointer .
То есть все равно 1 раз на каждый VAO но с одинаковой точкой привязки.

Добавлено через 1 час 26 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
struct vertex { 
  float positX, positY, positZ;
  float colorR, colorG, colorB; 
};
 
vertex vData[] = {
//  X   Y   Z    R G B
// 1-й квадрат - красный
    -1, -1, 0,   1,0,0,              // индекс вершины - 0
     0, -1, 0,   1,0,0,              // 1
     0,  0,  0,   1,0,0,             // 2
    -1,  0,  0,   1,0,0,            // 3
// 2-й квадрат - синий
     0, 0,  1,   0,0,1,             // 4
     1, 0,  1,   0,0,1,             // 5
     1, 1,  1,   0,0,1,             // 6
     0, 1,  1,   0,0,1              // 7
}
 
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 8*sizeof(vertex), vData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
 
GLuint iData1[] = { 0, 1, 2, 3};
glGenBuffers(1, &ibo1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo1);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4*sizeof(GLuint), iData1, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
GLuint iData2[] = { 4, 5, 6, 7};
glGenBuffers(1, &ibo2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo2);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4*sizeof(GLuint), iData2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*) 0); 
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)12); 
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo1);
glBindVertexArray(0);
 
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*) 0); 
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)12); 
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo2);
glBindVertexArray(0);
 
.................................
 
// рисуем 1-й квадрат
glBindVertexArray(vao1);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, (void*)0);
glBindVertexArray(0);
 
// рисуем 2-й квадрат
glBindVertexArray(vao2);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, (void*)0);
glBindVertexArray(0);
Добавлено через 9 минут
Или, как писал в начале, можно индексы запихнуть в один буфер, тогда будет и VAO один.
C++
1
2
3
4
5
6
glBindVertexArray(vao);
// рисуем 1-й квадрат
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, (void*)0);
// рисуем 2-й квадрат
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, (void*) (sizeof(GLuint)*4) );
glBindVertexArray(0);
или вообще отрисовать оба одной командой
glDrawElements(GL_QUADS, 8, GL_UNSIGNED_INT, (void*)0);
1
03.07.2019, 21:16
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.07.2019, 21:16

В экземпляре объекта не задана ссылка на объект при динамическом создании объекта
Выдается ошибка NullReferenceException в private void button2_Click(object sender,...

Сохранение в БД объекта связанного с другими объектами
Класс Game public class Game { public int GameId { get; set; } public...

написать программу движущийся графический объект с двумя способоми с использованием статического объекта и с использованием динамического объекта
Движение закрашенного прямоугольника по треугольному контуру с изменением цвета при изменении...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.