在LWJGL 3中使用VAOs和VBOs渲染四边形时出现问题。

huangapple go评论102阅读模式
英文:

Problem with rendering a quad in LWJGL 3 using VAOs and VBOs

问题

以下是您提供的代码的翻译部分:

  1. public class RawModel {
  2. private int vaoID;
  3. private int vertexCount;
  4. public RawModel(int vaoID, int vertexCount) {
  5. this.vaoID = vaoID;
  6. this.vertexCount = vertexCount;
  7. }
  8. public int getVaoID() {
  9. return vaoID;
  10. }
  11. public int getVertexCount() {
  12. return vertexCount;
  13. }
  14. }
  15. public class Loader {
  16. private List<Integer> vaos = new ArrayList<Integer>();
  17. private List<Integer> vbos = new ArrayList<Integer>();
  18. public RawModel loadToVAO(float[] positions) {
  19. int vaoID = createVAO();
  20. storeDataInAttributeList(0, positions);
  21. unbindVAO();
  22. return new RawModel(vaoID, positions.length/3);
  23. }
  24. private int createVAO() {
  25. int vaoID = GL30.glGenVertexArrays();
  26. vaos.add(vaoID);
  27. GL30.glBindVertexArray(vaoID);
  28. return vaoID;
  29. }
  30. private void storeDataInAttributeList(int attributeNumber, float[] data) {
  31. int vboID = GL15.glGenBuffers();
  32. vbos.add(vboID);
  33. GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
  34. FloatBuffer buffer = storeDataInFloatBuffer(data);
  35. GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
  36. GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
  37. GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
  38. }
  39. private void unbindVAO() {
  40. GL30.glBindVertexArray(0);
  41. }
  42. private FloatBuffer storeDataInFloatBuffer(float[] data) {
  43. FloatBuffer buffer = MemoryUtil.memAllocFloat(data.length);
  44. buffer.put(data);
  45. buffer.flip();
  46. return buffer;
  47. }
  48. public void cleanUp() {
  49. for (int vao : vaos) {
  50. GL30.glDeleteVertexArrays(vao);
  51. }
  52. for (int vbo : vbos) {
  53. GL15.glDeleteBuffers(vbo);
  54. }
  55. }
  56. }
  57. public class Renderer {
  58. public void prepare() {
  59. GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
  60. GL11.glClearColor(1f, 0f, 1f, 1f);
  61. }
  62. public void render(RawModel model) {
  63. GL30.glBindVertexArray(model.getVaoID());
  64. GL20.glEnableVertexAttribArray(0);
  65. GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
  66. GL20.glDisableVertexAttribArray(0);
  67. GL30.glBindVertexArray(0);
  68. }
  69. }
  70. public class Window {
  71. private int width, height;
  72. private String title;
  73. private long window;
  74. public Window(int width, int height, String title) {
  75. this.width = width;
  76. this.height = height;
  77. this.title = title;
  78. }
  79. public void create() {
  80. GLFWErrorCallback.createPrint(System.err).set();
  81. if (!glfwInit())
  82. throw new IllegalStateException("Unable to initialize GLFW");
  83. glfwDefaultWindowHints();
  84. glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
  85. glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
  86. window = glfwCreateWindow(width, height, "Flappy Bird", NULL, NULL);
  87. if (window == NULL)
  88. throw new RuntimeException("Failed to create the GLFW window");
  89. try (MemoryStack stack = stackPush()) {
  90. IntBuffer pWidth = stack.mallocInt(1);
  91. IntBuffer pHeight = stack.mallocInt(1);
  92. glfwGetWindowSize(window, pWidth, pHeight);
  93. GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
  94. glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
  95. }
  96. glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
  97. if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
  98. glfwSetWindowShouldClose(window, true);
  99. });
  100. glfwMakeContextCurrent(window);
  101. glfwSwapInterval(1);
  102. glfwShowWindow(window);
  103. }
  104. public long getWindowNum() {
  105. return window;
  106. }
  107. }
  108. public class Main {
  109. private Window window;
  110. Loader loader = new Loader();
  111. Renderer renderer = new Renderer();
  112. float[] vertices = {
  113. -0.5f, 0.5f, 0f,
  114. -0.5f, -0.5f, 0f,
  115. 0.5f, -0.5f, 0f,
  116. 0.5f, -0.5f, 0f,
  117. 0.5f, 0.5f, 0f,
  118. -0.5f, 0.5f, 0f
  119. };
  120. RawModel model;
  121. public void run() {
  122. setup();
  123. loop();
  124. loader.cleanUp();
  125. glfwFreeCallbacks(window.getWindowNum());
  126. glfwDestroyWindow(window.getWindowNum());
  127. glfwTerminate();
  128. glfwSetErrorCallback(null).free();
  129. }
  130. private void loop() {
  131. while (!glfwWindowShouldClose(window.getWindowNum())) {
  132. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  133. renderer.render(model);
  134. glfwSwapBuffers(window.getWindowNum());
  135. glfwPollEvents();
  136. }
  137. }
  138. public void setup() {
  139. window = new Window(900, 300, "Flappy Bird");
  140. window.create();
  141. GL.createCapabilities();
  142. GLFW.glfwMakeContextCurrent(window.getWindowNum());
  143. model = loader.loadToVAO(vertices);
  144. renderer.prepare();
  145. GL11.glViewport(0, 0, 900, 300);
  146. }
  147. public static void main(String[] args) {
  148. new Main().run();
  149. }
  150. }
英文:

(This is the second time I am asking this question. Last time I got one answer that didn't solve it (the answer there referred a bit of code that was left accidentally from one of my attempts at fixing this). I also changed the question itself slightly - I changed the order of code to put the part where I believe the mistake higher is and added that I am using macOS, which might be the reason that it doesn't work).

So, I just started learning LWJGL 3 and I used a mixture of a couple of tutorials and example code to make something that should render a rectangle to a magenta screen using VAOs and VBOs. There are no errors but the rectangle doesn't appear on screen (all I can see is a magenta screen). I tried using the old LWJGL pipeline (glBegin() and glEnd()) and it does work so I tried changing random things in the rendering code and the loading to VAOs and VBOs. I also tried to bind the VBO too but it didn't change anything. I also tried debugging and it seems like there is a VAO and a VBO that is created.

Can someone take a look at my code and see if something looks wrong? Here it is (sorry if its a bit messy. Like I said, I don't think the problem is in the Main or Window class but I have no idea about LWJGL so I wanted to put it here anyways. If you have time, please also look at them. Otherwise I would really appreciate it if you could look at the Loader and Renderer classes):

(Btw, I am using macOS, and I do have -XstartOnFirstThread on).

The Raw Model class:

  1. package engine.io;
  2. public class RawModel {
  3. private int vaoID;
  4. private int vertexCount;
  5. public RawModel(int vaoID, int vertexCount) {
  6. this.vaoID = vaoID;
  7. this.vertexCount = vertexCount;
  8. }
  9. public int getVaoID() {
  10. return vaoID;
  11. }
  12. public int getVertexCount() {
  13. return vertexCount;
  14. }
  15. }

The loader class:

  1. package engine.io;
  2. import java.nio.FloatBuffer;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import org.lwjgl.BufferUtils;
  6. import org.lwjgl.opengl.GL11;
  7. import org.lwjgl.opengl.GL15;
  8. import org.lwjgl.opengl.GL20;
  9. import org.lwjgl.opengl.GL30;
  10. import org.lwjgl.system.MemoryUtil;
  11. public class Loader {
  12. private List&lt;Integer&gt; vaos = new ArrayList&lt;Integer&gt;();
  13. private List&lt;Integer&gt; vbos = new ArrayList&lt;Integer&gt;();
  14. public RawModel loadToVAO(float[] positions) {
  15. int vaoID = createVAO();
  16. storeDataInAttributeList(0, positions);
  17. unbindVAO();
  18. return new RawModel(vaoID, positions.length/3);
  19. }
  20. private int createVAO() {
  21. int vaoID = GL30.glGenVertexArrays();
  22. vaos.add(vaoID);
  23. GL30.glBindVertexArray(vaoID);
  24. return vaoID;
  25. }
  26. private void storeDataInAttributeList(int attributeNumber, float[] data) {
  27. int vboID = GL15.glGenBuffers();
  28. vbos.add(vboID);
  29. GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
  30. FloatBuffer buffer = storeDataInFloatBuffer(data);
  31. GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
  32. GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
  33. GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
  34. }
  35. private void unbindVAO() {
  36. GL30.glBindVertexArray(0);
  37. }
  38. private FloatBuffer storeDataInFloatBuffer(float[] data) {
  39. FloatBuffer buffer = MemoryUtil.memAllocFloat(data.length);
  40. buffer.put(data);
  41. buffer.flip();
  42. return buffer;
  43. }
  44. public void cleanUp() {
  45. for (int vao : vaos) {
  46. GL30.glDeleteVertexArrays(vao);
  47. }
  48. for (int vbo : vbos) {
  49. GL15.glDeleteBuffers(vbo);
  50. }
  51. }
  52. }

The renderer class:

  1. package engine.io;
  2. import org.lwjgl.opengl.GL11;
  3. import org.lwjgl.opengl.GL15;
  4. import org.lwjgl.opengl.GL20;
  5. import org.lwjgl.opengl.GL30;
  6. public class Renderer {
  7. public void prepare() {
  8. GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
  9. GL11.glClearColor(1f, 0f, 1f, 1f);
  10. }
  11. public void render(RawModel model) {
  12. GL30.glBindVertexArray(model.getVaoID());
  13. GL20.glEnableVertexAttribArray(0);
  14. GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
  15. GL20.glDisableVertexAttribArray(0);
  16. GL30.glBindVertexArray(0);
  17. }
  18. }

Here is the Main class:

  1. import org.lwjgl.*;
  2. import org.lwjgl.glfw.*;
  3. import org.lwjgl.opengl.*;
  4. import org.lwjgl.system.*;
  5. import engine.io.Loader;
  6. import engine.io.RawModel;
  7. import engine.io.Renderer;
  8. import engine.io.Window;
  9. import java.nio.*;
  10. import static org.lwjgl.glfw.Callbacks.*;
  11. import static org.lwjgl.glfw.GLFW.*;
  12. import static org.lwjgl.opengl.GL11.*;
  13. import static org.lwjgl.system.MemoryStack.*;
  14. import static org.lwjgl.system.MemoryUtil.*;
  15. public class Main {
  16. private Window window;
  17. Loader loader = new Loader();
  18. Renderer renderer = new Renderer();
  19. float[] vertices = {
  20. // Left bottom triangle
  21. -0.5f, 0.5f, 0f,
  22. -0.5f, -0.5f, 0f,
  23. 0.5f, -0.5f, 0f,
  24. // Right top triangle
  25. 0.5f, -0.5f, 0f,
  26. 0.5f, 0.5f, 0f,
  27. -0.5f, 0.5f, 0f
  28. };
  29. RawModel model;
  30. public void run() {
  31. setup();
  32. loop();
  33. loader.cleanUp();
  34. glfwFreeCallbacks(window.getWindowNum());
  35. glfwDestroyWindow(window.getWindowNum());
  36. glfwTerminate();
  37. glfwSetErrorCallback(null).free();
  38. }
  39. private void loop() {
  40. while ( !glfwWindowShouldClose(window.getWindowNum()) ) {
  41. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
  42. renderer.render(model);
  43. glfwSwapBuffers(window.getWindowNum()); // swap the color buffers
  44. glfwPollEvents();
  45. }
  46. }
  47. public void setup() {
  48. window = new Window(900, 300, &quot;Flappy Bird&quot;);
  49. window.create();
  50. GL.createCapabilities();
  51. GLFW.glfwMakeContextCurrent(window.getWindowNum());
  52. model = loader.loadToVAO(vertices);
  53. renderer.prepare();
  54. GL11.glViewport(0, 0, 900, 300);
  55. }
  56. public static void main(String[] args) {
  57. new Main().run();
  58. }
  59. }

Here is the window class:

  1. package engine.io;
  2. import static org.lwjgl.glfw.GLFW.*;
  3. import static org.lwjgl.opengl.GL11.*;
  4. import static org.lwjgl.system.MemoryStack.stackPush;
  5. import static org.lwjgl.system.MemoryUtil.*;
  6. import java.nio.IntBuffer;
  7. //import static org.lwjgl.glfw.GLFW.*;
  8. import org.lwjgl.glfw.GLFW;
  9. import org.lwjgl.glfw.GLFWErrorCallback;
  10. import org.lwjgl.glfw.GLFWVidMode;
  11. import org.lwjgl.system.MemoryStack;
  12. public class Window {
  13. private int width, height;
  14. private String title;
  15. private long window;
  16. public Window(int width, int height, String title) {
  17. this.width = width;
  18. this.height = height;
  19. this.title = title;
  20. }
  21. public void create() {
  22. GLFWErrorCallback.createPrint(System.err).set();
  23. if (!glfwInit())
  24. throw new IllegalStateException(&quot;Unable to initialize GLFW&quot;);
  25. // Configure GLFW
  26. glfwDefaultWindowHints(); // optional, the current window hints are already the default
  27. glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
  28. glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
  29. // Create the window
  30. window = glfwCreateWindow(width, height, &quot;Flappy Bird&quot;, NULL, NULL);
  31. if (window == NULL)
  32. throw new RuntimeException(&quot;Failed to create the GLFW window&quot;);
  33. // Get the thread stack and push a new frame
  34. try (MemoryStack stack = stackPush()) {
  35. IntBuffer pWidth = stack.mallocInt(1); // int*
  36. IntBuffer pHeight = stack.mallocInt(1); // int*
  37. // Get the window size passed to glfwCreateWindow
  38. glfwGetWindowSize(window, pWidth, pHeight);
  39. // Get the resolution of the primary monitor
  40. GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
  41. // Center the window
  42. glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
  43. } // the stack frame is popped automatically
  44. // Setup a key callback. It will be called every time a key is pressed, repeated
  45. // or released.
  46. glfwSetKeyCallback(window, (window, key, scancode, action, mods) -&gt; {
  47. if (key == GLFW_KEY_ESCAPE &amp;&amp; action == GLFW_RELEASE)
  48. glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
  49. });
  50. // Make the OpenGL context current
  51. glfwMakeContextCurrent(window);
  52. // Enable v-sync
  53. glfwSwapInterval(1);
  54. // Make the window visible
  55. glfwShowWindow(window);
  56. }
  57. public long getWindowNum() {
  58. return window;
  59. }
  60. }

答案1

得分: 2

由于您使用的是MacOS,我建议您设置一个3.2核心配置OpenGL上下文。请参阅在OS X上进行OpenGL开发

  1. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  2. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  3. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
  4. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  5. // 创建窗口
  6. window = glfwCreateWindow(width, height, "Flappy Bird", NULL, NULL);
英文:

Since you are on MacOS, I recommend to set up a 3.2 core profile OpenGL Context. See OpenGL Development on OS X:

  1. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  2. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  3. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
  4. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  5. // Create the window
  6. window = glfwCreateWindow(width, height, &quot;Flappy Bird&quot;, NULL, NULL);

huangapple
  • 本文由 发表于 2020年8月23日 17:40:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63545503.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定