TestAPI.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibGL/GL/gl.h>
  7. #include <LibGL/GLContext.h>
  8. #include <LibTest/TestCase.h>
  9. static NonnullOwnPtr<GL::GLContext> create_testing_context()
  10. {
  11. auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, { 1, 1 }));
  12. auto context = MUST(GL::create_context(*bitmap));
  13. GL::make_context_current(context);
  14. return context;
  15. }
  16. TEST_CASE(0001_gl_gen_textures_does_not_return_the_same_texture_name_twice_unless_deleted)
  17. {
  18. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGenTextures.xhtml
  19. // "Texture names returned by a call to glGenTextures are not returned by subsequent calls, unless they are first deleted with glDeleteTextures."
  20. auto context = create_testing_context();
  21. GLuint texture1 = 0;
  22. GLuint texture2 = 0;
  23. glGenTextures(1, &texture1);
  24. // glDeleteTextures previously did not check that the texture name was allocated by glGenTextures before adding it to the free texture name list.
  25. // This means that if you delete a texture twice in a row, the name will appear twice in the free texture list, making glGenTextures return the
  26. // same texture name twice in a row.
  27. glDeleteTextures(1, &texture1);
  28. glDeleteTextures(1, &texture1);
  29. texture1 = 0;
  30. glGenTextures(1, &texture1);
  31. glGenTextures(1, &texture2);
  32. EXPECT_NE(texture1, texture2);
  33. }
  34. TEST_CASE(0002_gl_cull_face_does_not_accept_left_and_right)
  35. {
  36. auto context = create_testing_context();
  37. // glCullFace only accepts GL_FRONT, GL_BACK and GL_FRONT_AND_BACK. We checked if the mode was valid by performing cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK.
  38. // However, this range also contains GL_LEFT and GL_RIGHT, which we would accept when we should return a GL_INVALID_ENUM error.
  39. glCullFace(GL_LEFT);
  40. EXPECT_EQ(glGetError(), static_cast<GLenum>(GL_INVALID_ENUM));
  41. glCullFace(GL_RIGHT);
  42. EXPECT_EQ(glGetError(), static_cast<GLenum>(GL_INVALID_ENUM));
  43. }
  44. TEST_CASE(0003_gl_bind_buffer_names_must_be_allocated)
  45. {
  46. auto context = create_testing_context();
  47. glBindBuffer(GL_ARRAY_BUFFER, 123);
  48. EXPECT_EQ(glGetError(), static_cast<GLenum>(GL_INVALID_VALUE));
  49. }
  50. TEST_CASE(0004_gl_color_clear_value)
  51. {
  52. auto context = create_testing_context();
  53. Array<GLdouble, 4> clear_color;
  54. glGetDoublev(GL_COLOR_CLEAR_VALUE, clear_color.data());
  55. EXPECT_EQ(clear_color[0], 0.);
  56. EXPECT_EQ(clear_color[1], 0.);
  57. EXPECT_EQ(clear_color[2], 0.);
  58. EXPECT_EQ(clear_color[3], 0.);
  59. glClearColor(.1f, .2f, .3f, .4f);
  60. glGetDoublev(GL_COLOR_CLEAR_VALUE, clear_color.data());
  61. EXPECT_APPROXIMATE(clear_color[0], .1);
  62. EXPECT_APPROXIMATE(clear_color[1], .2);
  63. EXPECT_APPROXIMATE(clear_color[2], .3);
  64. EXPECT_APPROXIMATE(clear_color[3], .4);
  65. }
  66. TEST_CASE(0005_gl_depth_clear_value)
  67. {
  68. auto context = create_testing_context();
  69. GLdouble clear_depth;
  70. glGetDoublev(GL_DEPTH_CLEAR_VALUE, &clear_depth);
  71. EXPECT_EQ(clear_depth, 1.);
  72. glClearDepth(.1f);
  73. glGetDoublev(GL_DEPTH_CLEAR_VALUE, &clear_depth);
  74. EXPECT_APPROXIMATE(clear_depth, .1);
  75. }
  76. TEST_CASE(0006_gl_stencil_clear_value)
  77. {
  78. auto context = create_testing_context();
  79. GLint clear_stencil;
  80. glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil);
  81. EXPECT_EQ(clear_stencil, 0);
  82. glClearStencil(255);
  83. glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil);
  84. EXPECT_EQ(clear_stencil, 255);
  85. }