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