문제

I try to code an OpenGL project with Qt (v5.1.1) on OS X 10.9, in the manner of the modern pipeline implementation. The program is supposed to be a multi-agent based system or particle system. However I lack in understanding how to draw something out of another class.

In cinder there were some simple drawThisAndThat() command you could call. I read the 6th edition of the 'OpenGL Superbible'. From this and several tutorials all examples seem to cover just programs where all modifications are made out of the class that initializes OpenGL.

I would like to instantiate some objects moving on a grid and draw pixel to display their position. I know I have to call void glVertexAttrib4fv(GLuint index, const GLfloat * vi); but this is not sufficient.

  • Do I need to call glEnableVertexAttribArray(1); and glDrawArrays(GL_POINTS, 0, 3); as well and what else?
  • Am I right, to instantiate the class controlling the particles after instantiating OpenGL and bevor the main loop?
  • How do I manage that the particle draws himself while erasing the position he was drawn bevor?

The program is based on this code.

도움이 되었습니까?

해결책

To answer your questions completely I would have to write a wall of text, I will try to only point out the most important aspects. I hope this will help you enough to use your knowledge and probably further reading to get it to work.

all modifications are made out of the class that initializes OpenGL

You can encapsulate update(time) and draw() methods for your Objects which you then call in your main loop.

Do I need to call glEnableVertexAttribArray(1); and glDrawArrays(GL_POINTS, 0, 3); as well and what else?

I would put all particles into one vertex array to avoid rebinding of different vertex arrays after each particle. Then you would have to use glBindVertexArray(vaid); and glDrawArrays(GL_POINTS, 0, vertexCount); in your draw() call. Be careful with vertexCount, it's not the number of floats (as your question implies) but the number of vertices, which should be 1 in your example or the number of particles in my suggested approach (If I'm correct in assuming that the 3 stands for "x, y, and z of my vertex").

And since you only have particles glDrawElements(...); would probably already fit your needs.

Am I right, to instantiate the class controlling the particles after instantiating OpenGL and bevor the main loop?

Probably your instantiation order is correct that way. You definitely should do all instantiations before calling the main loop in your case.

How do I manage that the particle draws himself while erasing the position he was drawn bevor?

If understand your last question correctly: Simply by changing the elements in your buffer objects (glBufferData(...);). Since you will clear the screen and swap buffers after each loop this will make them move. Just update their position with an update(time) call, e.g. pos = pos + dir * time;, put the new positions into a buffer and push that buffer with glBufferData(...) to the vertex array. Remember to bind the vertex array before pushing the buffer.


Some additional things I'd like to point out.

glEnableVertexAttribArray(1); is to enable a vertex attribute in your shader program to be able to pass data to that attribute. You should create a shader program

  id = glCreateProgram()
  // ... create and attach shaders here
  // then bind attribute locations, e.g. positionMC
  glBindAttribLocation(id, 0, "positionMC"); 
  glLinkProgram(id);

And after initializing the vertex array with glGenVertexArrays(); you should enable all attributes your vertex array needs in your shader program. In this example positionMC would be at location 0, so you would call something like

  glUseProgram(pid);
  glBindVertexArray(vaid);
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(...);

This has only to be done once, since OpenGL stores the state for every particular vertex array. By rebinding a vertex array you will restore that state.

In the main loop all you have to do now is calling your update and draw methods, e.g.:

  handleInputs();
  update(deltaTime);
  glClear(...);
  draw();
  swapBuffers();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top