mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
LibGL: Generate the API wrappers
We now generate all LibGL API wrappers from a single API method definition list stored in `GLAPI.json`. Since a significant portion of the OpenGL API methods are relatively consistent variants, we take advantage of this to generate a lot of these variants at once. The autogenerated methods check for the non-nullness of the current `GLContext`, and only perform an action if a `GLContext` is present. This prevents a crash in ports like GLTron, who assume you can still call the OpenGL API without an active context. This increases our API wrapper method count from 211 to 356. Fixes #15814.
This commit is contained in:
parent
8c094699db
commit
2da1c1c10e
Notes:
sideshowbarker
2024-07-17 02:57:29 +09:00
Author: https://github.com/gmta Commit: https://github.com/SerenityOS/serenity/commit/2da1c1c10e Pull-request: https://github.com/SerenityOS/serenity/pull/16543 Issue: https://github.com/SerenityOS/serenity/issues/15814 Reviewed-by: https://github.com/FalseHonesty Reviewed-by: https://github.com/sunverwerth ✅
9 changed files with 1787 additions and 1404 deletions
14
Meta/CMake/libgl_generators.cmake
Normal file
14
Meta/CMake/libgl_generators.cmake
Normal file
|
@ -0,0 +1,14 @@
|
|||
function (generate_libgl_implementation)
|
||||
set(LIBGL_INPUT_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
invoke_generator(
|
||||
"GLAPI.cpp"
|
||||
Lagom::GenerateGLAPIWrapper
|
||||
"${LIBGL_INPUT_FOLDER}/GLAPI.json"
|
||||
"GL/glapi.h"
|
||||
"GLAPI.cpp"
|
||||
arguments -j "${LIBGL_INPUT_FOLDER}/GLAPI.json"
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/GL/glapi.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/LibGL/GL/")
|
||||
endfunction()
|
|
@ -1,5 +1,6 @@
|
|||
add_subdirectory(IPCCompiler)
|
||||
add_subdirectory(LibEDID)
|
||||
add_subdirectory(LibGL)
|
||||
add_subdirectory(LibLocale)
|
||||
add_subdirectory(LibTimeZone)
|
||||
add_subdirectory(LibUnicode)
|
||||
|
|
1
Meta/Lagom/Tools/CodeGenerators/LibGL/CMakeLists.txt
Normal file
1
Meta/Lagom/Tools/CodeGenerators/LibGL/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
|||
lagom_tool(GenerateGLAPIWrapper SOURCES GenerateGLAPIWrapper.cpp LIBS LibMain)
|
570
Meta/Lagom/Tools/CodeGenerators/LibGL/GenerateGLAPIWrapper.cpp
Normal file
570
Meta/Lagom/Tools/CodeGenerators/LibGL/GenerateGLAPIWrapper.cpp
Normal file
|
@ -0,0 +1,570 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/SourceGenerator.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibMain/Main.h>
|
||||
|
||||
struct ArgumentDefinition {
|
||||
Optional<DeprecatedString> name;
|
||||
Optional<DeprecatedString> cpp_type;
|
||||
DeprecatedString expression;
|
||||
Optional<DeprecatedString> cast_to;
|
||||
};
|
||||
|
||||
struct FunctionDefinition {
|
||||
DeprecatedString name;
|
||||
DeprecatedString return_type;
|
||||
Vector<ArgumentDefinition> arguments;
|
||||
DeprecatedString implementation;
|
||||
bool unimplemented;
|
||||
DeprecatedString variant_gl_type;
|
||||
};
|
||||
|
||||
struct VariantType {
|
||||
DeprecatedString encoded_type;
|
||||
Optional<DeprecatedString> implementation;
|
||||
bool unimplemented;
|
||||
};
|
||||
|
||||
struct Variants {
|
||||
Vector<DeprecatedString> api_suffixes { "" };
|
||||
Vector<u32> argument_counts { NumericLimits<u32>::max() };
|
||||
Vector<DeprecatedString> argument_defaults { "" };
|
||||
bool convert_range { false };
|
||||
Vector<VariantType> types {
|
||||
{
|
||||
.encoded_type = "",
|
||||
.implementation = Optional<DeprecatedString> {},
|
||||
.unimplemented = false,
|
||||
}
|
||||
};
|
||||
DeprecatedString pointer_argument { "" };
|
||||
};
|
||||
|
||||
struct EncodedTypeEntry {
|
||||
StringView encoded_type;
|
||||
StringView cpp_type;
|
||||
StringView gl_type;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
constexpr static Array<EncodedTypeEntry, 9> type_definitions = {
|
||||
EncodedTypeEntry { "b"sv, "GLbyte"sv, "GL_BYTE"sv },
|
||||
EncodedTypeEntry { "d"sv, "GLdouble"sv, "GL_DOUBLE"sv },
|
||||
EncodedTypeEntry { "f"sv, "GLfloat"sv, "GL_FLOAT"sv },
|
||||
EncodedTypeEntry { "i"sv, "GLint"sv, "GL_INT"sv },
|
||||
EncodedTypeEntry { "s"sv, "GLshort"sv, "GL_SHORT"sv },
|
||||
EncodedTypeEntry { "ub"sv, "GLubyte"sv, "GL_UNSIGNED_BYTE"sv },
|
||||
EncodedTypeEntry { "ui"sv, "GLuint"sv, "GL_UNSIGNED_INT"sv },
|
||||
EncodedTypeEntry { "us"sv, "GLushort"sv, "GL_UNSIGNED_SHORT"sv },
|
||||
EncodedTypeEntry { "x"sv, "GLfixed"sv, "GL_INT"sv },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
struct EncodedType {
|
||||
EncodedTypeEntry type_entry;
|
||||
DeprecatedString cpp_type;
|
||||
DeprecatedString function_name_suffix;
|
||||
bool is_pointer;
|
||||
bool is_const_pointer;
|
||||
};
|
||||
|
||||
Vector<DeprecatedString> get_name_list(JsonValue const& name_definition)
|
||||
{
|
||||
if (name_definition.is_null())
|
||||
return {};
|
||||
|
||||
Vector<DeprecatedString, 1> names;
|
||||
if (name_definition.is_string()) {
|
||||
names.append(name_definition.as_string());
|
||||
} else if (name_definition.is_array()) {
|
||||
name_definition.as_array().for_each([&names](auto& value) {
|
||||
VERIFY(value.is_string());
|
||||
names.append(value.as_string());
|
||||
});
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
Optional<EncodedType> get_encoded_type(DeprecatedString encoded_type)
|
||||
{
|
||||
bool is_const_pointer = !encoded_type.ends_with('!');
|
||||
if (!is_const_pointer)
|
||||
encoded_type = encoded_type.substring_view(0, encoded_type.length() - 1);
|
||||
DeprecatedString function_name_suffix = encoded_type;
|
||||
|
||||
bool is_pointer = encoded_type.ends_with('v');
|
||||
if (is_pointer)
|
||||
encoded_type = encoded_type.substring_view(0, encoded_type.length() - 1);
|
||||
|
||||
VERIFY(is_const_pointer || is_pointer);
|
||||
|
||||
Optional<EncodedTypeEntry> type_definition;
|
||||
for (size_t i = 0; i < type_definitions.size(); ++i) {
|
||||
if (type_definitions[i].encoded_type == encoded_type) {
|
||||
type_definition = type_definitions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type_definition.has_value())
|
||||
return {};
|
||||
|
||||
return EncodedType {
|
||||
.type_entry = type_definition.value(),
|
||||
.cpp_type = DeprecatedString::formatted(
|
||||
"{}{}{}",
|
||||
type_definition->cpp_type,
|
||||
is_pointer && is_const_pointer ? " const" : "",
|
||||
is_pointer ? "*" : ""),
|
||||
.function_name_suffix = function_name_suffix,
|
||||
.is_pointer = is_pointer,
|
||||
.is_const_pointer = is_const_pointer,
|
||||
};
|
||||
}
|
||||
|
||||
DeprecatedString wrap_expression_in_range_conversion(DeprecatedString source_type, DeprecatedString target_type, DeprecatedString expression)
|
||||
{
|
||||
VERIFY(target_type == "GLfloat" || target_type == "GLdouble");
|
||||
|
||||
// No range conversion required
|
||||
if (source_type == target_type || source_type == "GLdouble")
|
||||
return expression;
|
||||
|
||||
if (source_type == "GLbyte")
|
||||
return DeprecatedString::formatted("({} + 128.) / 127.5 - 1.", expression);
|
||||
else if (source_type == "GLfloat")
|
||||
return DeprecatedString::formatted("static_cast<GLdouble>({})", expression);
|
||||
else if (source_type == "GLint")
|
||||
return DeprecatedString::formatted("({} + 2147483648.) / 2147483647.5 - 1.", expression);
|
||||
else if (source_type == "GLshort")
|
||||
return DeprecatedString::formatted("({} + 32768.) / 32767.5 - 1.", expression);
|
||||
else if (source_type == "GLubyte")
|
||||
return DeprecatedString::formatted("{} / 255.", expression);
|
||||
else if (source_type == "GLuint")
|
||||
return DeprecatedString::formatted("{} / 4294967296.", expression);
|
||||
else if (source_type == "GLushort")
|
||||
return DeprecatedString::formatted("{} / 65536.", expression);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Variants read_variants_settings(JsonObject const& variants_obj)
|
||||
{
|
||||
Variants variants;
|
||||
|
||||
if (variants_obj.has("argument_counts"sv)) {
|
||||
variants.argument_counts.clear_with_capacity();
|
||||
variants_obj.get("argument_counts"sv).as_array().for_each([&](auto const& argument_count_value) {
|
||||
variants.argument_counts.append(argument_count_value.to_u32());
|
||||
});
|
||||
}
|
||||
if (variants_obj.has("argument_defaults"sv)) {
|
||||
variants.argument_defaults.clear_with_capacity();
|
||||
variants_obj.get("argument_defaults"sv).as_array().for_each([&](auto const& argument_default_value) {
|
||||
variants.argument_defaults.append(argument_default_value.as_string());
|
||||
});
|
||||
}
|
||||
if (variants_obj.has("convert_range"sv)) {
|
||||
variants.convert_range = variants_obj.get("convert_range"sv).to_bool();
|
||||
}
|
||||
if (variants_obj.has("api_suffixes"sv)) {
|
||||
variants.api_suffixes.clear_with_capacity();
|
||||
variants_obj.get("api_suffixes"sv).as_array().for_each([&](auto const& suffix_value) {
|
||||
variants.api_suffixes.append(suffix_value.as_string());
|
||||
});
|
||||
}
|
||||
if (variants_obj.has("pointer_argument"sv)) {
|
||||
variants.pointer_argument = variants_obj.get("pointer_argument"sv).as_string();
|
||||
}
|
||||
if (variants_obj.has("types"sv)) {
|
||||
variants.types.clear_with_capacity();
|
||||
variants_obj.get("types"sv).as_object().for_each_member([&](auto const& key, auto const& type_value) {
|
||||
auto const& type = type_value.as_object();
|
||||
variants.types.append(VariantType {
|
||||
.encoded_type = key,
|
||||
.implementation = type.has("implementation"sv) ? type.get("implementation"sv).as_string() : Optional<DeprecatedString> {},
|
||||
.unimplemented = type.get("unimplemented"sv).to_bool(false),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return variants;
|
||||
}
|
||||
|
||||
Vector<ArgumentDefinition> copy_arguments_for_variant(Vector<ArgumentDefinition> arguments, Variants variants,
|
||||
u32 argument_count, EncodedType encoded_type)
|
||||
{
|
||||
Vector<ArgumentDefinition> variant_arguments = arguments;
|
||||
auto base_cpp_type = encoded_type.type_entry.cpp_type;
|
||||
|
||||
size_t variadic_index = 0;
|
||||
for (size_t i = 0; i < variant_arguments.size(); ++i) {
|
||||
// Skip arguments with a fixed type
|
||||
if (variant_arguments[i].cpp_type.has_value())
|
||||
continue;
|
||||
|
||||
variant_arguments[i].cpp_type = encoded_type.cpp_type;
|
||||
auto cast_to = variant_arguments[i].cast_to;
|
||||
|
||||
// Pointer argument
|
||||
if (encoded_type.is_pointer) {
|
||||
variant_arguments[i].name = (variadic_index == 0) ? variants.pointer_argument : Optional<DeprecatedString> {};
|
||||
|
||||
if (variadic_index >= argument_count) {
|
||||
// If this variable argument is past the argument count, fall back to the defaults
|
||||
variant_arguments[i].expression = variants.argument_defaults[variadic_index];
|
||||
variant_arguments[i].cast_to = Optional<DeprecatedString> {};
|
||||
|
||||
} else if (argument_count == 1 && variants.argument_counts.size() == 1) {
|
||||
// Otherwise, if the pointer is the only variadic argument, pass it through unchanged
|
||||
variant_arguments[i].cast_to = Optional<DeprecatedString> {};
|
||||
|
||||
} else {
|
||||
// Otherwise, index into the pointer argument
|
||||
auto indexed_expression = DeprecatedString::formatted("{}[{}]", variants.pointer_argument, variadic_index);
|
||||
if (variants.convert_range && cast_to.has_value())
|
||||
indexed_expression = wrap_expression_in_range_conversion(base_cpp_type, cast_to.value(), indexed_expression);
|
||||
variant_arguments[i].expression = indexed_expression;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Regular argument
|
||||
if (variadic_index >= argument_count) {
|
||||
// If the variable argument is past the argument count, fall back to the defaults
|
||||
variant_arguments[i].name = Optional<DeprecatedString> {};
|
||||
variant_arguments[i].expression = variants.argument_defaults[variadic_index];
|
||||
variant_arguments[i].cast_to = Optional<DeprecatedString> {};
|
||||
|
||||
} else if (variants.convert_range && cast_to.has_value()) {
|
||||
// Otherwise, if we need to convert the input values, wrap the expression in a range conversion
|
||||
variant_arguments[i].expression = wrap_expression_in_range_conversion(
|
||||
base_cpp_type,
|
||||
cast_to.value(),
|
||||
variant_arguments[i].expression);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if we can skip casting to the target type
|
||||
if (cast_to == base_cpp_type || (variants.convert_range && cast_to == "GLdouble"))
|
||||
variant_arguments[i].cast_to = Optional<DeprecatedString> {};
|
||||
|
||||
variadic_index++;
|
||||
}
|
||||
|
||||
return variant_arguments;
|
||||
}
|
||||
|
||||
Vector<FunctionDefinition> create_function_definitions(DeprecatedString function_name, JsonObject const& function_definition)
|
||||
{
|
||||
// A single function definition can expand to multiple generated functions by way of:
|
||||
// - differing API suffices (ARB, EXT, etc.);
|
||||
// - differing argument counts;
|
||||
// - differing argument types.
|
||||
// These can all be combined.
|
||||
|
||||
// Parse base argument definitions first; these may later be modified by variants
|
||||
Vector<ArgumentDefinition> argument_definitions;
|
||||
JsonArray const& arguments = function_definition.has("arguments"sv)
|
||||
? function_definition.get("arguments"sv).as_array()
|
||||
: JsonArray {};
|
||||
arguments.for_each([&argument_definitions](auto const& argument_value) {
|
||||
VERIFY(argument_value.is_object());
|
||||
auto const& argument = argument_value.as_object();
|
||||
|
||||
auto type = argument.has("type"sv) ? argument.get("type"sv).as_string() : Optional<DeprecatedString> {};
|
||||
auto argument_names = get_name_list(argument.get("name"sv));
|
||||
auto expression = argument.get("expression"sv).as_string_or("@argument_name@");
|
||||
auto cast_to = argument.has("cast_to"sv) ? argument.get("cast_to"sv).as_string() : Optional<DeprecatedString> {};
|
||||
|
||||
// Add an empty dummy name when all we have is an expression
|
||||
if (argument_names.is_empty() && !expression.is_empty())
|
||||
argument_names.append("");
|
||||
|
||||
for (auto const& argument_name : argument_names) {
|
||||
argument_definitions.append({ .name = argument_name.is_empty() ? Optional<DeprecatedString> {} : argument_name,
|
||||
.cpp_type = type,
|
||||
.expression = expression,
|
||||
.cast_to = cast_to });
|
||||
}
|
||||
});
|
||||
|
||||
// Create functions for each name and/or variant
|
||||
Vector<FunctionDefinition> functions;
|
||||
|
||||
auto return_type = function_definition.get("return_type"sv).as_string_or("void"sv);
|
||||
auto function_implementation = function_definition.get("implementation"sv).as_string_or(function_name.to_snakecase());
|
||||
auto function_unimplemented = function_definition.get("unimplemented"sv).to_bool(false);
|
||||
|
||||
if (!function_definition.has("variants"sv)) {
|
||||
functions.append({
|
||||
.name = function_name,
|
||||
.return_type = return_type,
|
||||
.arguments = argument_definitions,
|
||||
.implementation = function_implementation,
|
||||
.unimplemented = function_unimplemented,
|
||||
.variant_gl_type = "",
|
||||
});
|
||||
return functions;
|
||||
}
|
||||
|
||||
// Read variants settings for this function
|
||||
auto variants_obj = function_definition.get("variants"sv).as_object();
|
||||
auto variants = read_variants_settings(variants_obj);
|
||||
|
||||
for (auto argument_count : variants.argument_counts) {
|
||||
for (auto const& variant_type : variants.types) {
|
||||
auto encoded_type = get_encoded_type(variant_type.encoded_type);
|
||||
auto variant_arguments = encoded_type.has_value()
|
||||
? copy_arguments_for_variant(argument_definitions, variants, argument_count, encoded_type.value())
|
||||
: argument_definitions;
|
||||
auto variant_type_implementation = variant_type.implementation.has_value()
|
||||
? variant_type.implementation.value()
|
||||
: function_implementation;
|
||||
|
||||
for (auto const& api_suffix : variants.api_suffixes) {
|
||||
functions.append({
|
||||
.name = DeprecatedString::formatted(
|
||||
"{}{}{}{}",
|
||||
function_name,
|
||||
variants.argument_counts.size() > 1 ? DeprecatedString::formatted("{}", argument_count) : "",
|
||||
encoded_type.has_value() && variants.types.size() > 1 ? encoded_type->function_name_suffix : "",
|
||||
api_suffix),
|
||||
.return_type = return_type,
|
||||
.arguments = variant_arguments,
|
||||
.implementation = variant_type_implementation,
|
||||
.unimplemented = variant_type.unimplemented || function_unimplemented,
|
||||
.variant_gl_type = encoded_type.has_value() ? encoded_type->type_entry.gl_type : ""sv,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
ErrorOr<void> generate_header_file(JsonObject& api_data, Core::Stream::File& file)
|
||||
{
|
||||
StringBuilder builder;
|
||||
SourceGenerator generator { builder };
|
||||
|
||||
generator.appendln("#pragma once");
|
||||
generator.append("\n");
|
||||
generator.appendln("#include <LibGL/GL/glplatform.h>");
|
||||
generator.append("\n");
|
||||
generator.appendln("#ifdef __cplusplus");
|
||||
generator.appendln("extern \"C\" {");
|
||||
generator.appendln("#endif");
|
||||
generator.append("\n");
|
||||
|
||||
api_data.for_each_member([&](auto& function_name, auto& value) {
|
||||
VERIFY(value.is_object());
|
||||
auto const& function = value.as_object();
|
||||
auto function_definitions = create_function_definitions(function_name, function);
|
||||
|
||||
for (auto const& function_definition : function_definitions) {
|
||||
auto function_generator = generator.fork();
|
||||
|
||||
function_generator.set("name", function_definition.name);
|
||||
function_generator.set("return_type", function_definition.return_type);
|
||||
|
||||
function_generator.append("GLAPI @return_type@ gl@name@(");
|
||||
|
||||
bool first = true;
|
||||
for (auto const& argument_definition : function_definition.arguments) {
|
||||
if (!argument_definition.name.has_value() || !argument_definition.cpp_type.has_value())
|
||||
continue;
|
||||
|
||||
auto argument_generator = function_generator.fork();
|
||||
argument_generator.set("argument_type", argument_definition.cpp_type.value());
|
||||
argument_generator.set("argument_name", argument_definition.name.value());
|
||||
|
||||
if (!first)
|
||||
argument_generator.append(", ");
|
||||
first = false;
|
||||
argument_generator.append("@argument_type@ @argument_name@");
|
||||
}
|
||||
|
||||
function_generator.appendln(");");
|
||||
}
|
||||
});
|
||||
|
||||
generator.appendln("#ifdef __cplusplus");
|
||||
generator.appendln("}");
|
||||
generator.appendln("#endif");
|
||||
|
||||
TRY(file.write(generator.as_string_view().bytes()));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> generate_implementation_file(JsonObject& api_data, Core::Stream::File& file)
|
||||
{
|
||||
StringBuilder builder;
|
||||
SourceGenerator generator { builder };
|
||||
|
||||
generator.appendln("#include <LibGL/GL/glapi.h>");
|
||||
generator.appendln("#include <LibGL/GLContext.h>");
|
||||
generator.append("\n");
|
||||
generator.appendln("extern GL::GLContext* g_gl_context;");
|
||||
generator.append("\n");
|
||||
|
||||
api_data.for_each_member([&](auto& function_name, auto& value) {
|
||||
VERIFY(value.is_object());
|
||||
JsonObject const& function = value.as_object();
|
||||
auto function_definitions = create_function_definitions(function_name, function);
|
||||
|
||||
for (auto const& function_definition : function_definitions) {
|
||||
auto function_generator = generator.fork();
|
||||
auto return_type = function_definition.return_type;
|
||||
|
||||
function_generator.set("name"sv, function_definition.name);
|
||||
function_generator.set("return_type"sv, return_type);
|
||||
function_generator.set("implementation"sv, function_definition.implementation);
|
||||
function_generator.set("variant_gl_type"sv, function_definition.variant_gl_type);
|
||||
|
||||
function_generator.append("@return_type@ gl@name@(");
|
||||
|
||||
bool first = true;
|
||||
for (auto const& argument_definition : function_definition.arguments) {
|
||||
if (!argument_definition.name.has_value() || !argument_definition.cpp_type.has_value())
|
||||
continue;
|
||||
|
||||
auto argument_generator = function_generator.fork();
|
||||
argument_generator.set("argument_type", argument_definition.cpp_type.value());
|
||||
argument_generator.set("argument_name", argument_definition.name.value());
|
||||
|
||||
if (!first)
|
||||
argument_generator.append(", ");
|
||||
first = false;
|
||||
argument_generator.append("@argument_type@ @argument_name@");
|
||||
}
|
||||
function_generator.appendln(")");
|
||||
function_generator.appendln("{");
|
||||
|
||||
if (function_definition.unimplemented) {
|
||||
function_generator.append(" dbgln(\"gl@name@(");
|
||||
|
||||
first = true;
|
||||
for (auto const& argument_definition : function_definition.arguments) {
|
||||
if (!argument_definition.name.has_value())
|
||||
continue;
|
||||
if (!first)
|
||||
function_generator.append(", ");
|
||||
first = false;
|
||||
if (argument_definition.cpp_type.value().ends_with('*'))
|
||||
function_generator.append("{:p}");
|
||||
else if (argument_definition.cpp_type.value() == "GLenum")
|
||||
function_generator.append("{:#x}");
|
||||
else
|
||||
function_generator.append("{}");
|
||||
}
|
||||
|
||||
function_generator.append("): unimplemented\"");
|
||||
|
||||
for (auto const& argument_definition : function_definition.arguments) {
|
||||
if (!argument_definition.name.has_value())
|
||||
continue;
|
||||
|
||||
function_generator.append(", ");
|
||||
function_generator.append(argument_definition.name.value());
|
||||
}
|
||||
|
||||
function_generator.appendln(");");
|
||||
function_generator.appendln(" TODO();");
|
||||
} else {
|
||||
function_generator.appendln(" if (!g_gl_context)");
|
||||
if (return_type.ends_with('*'))
|
||||
function_generator.appendln(" return nullptr;");
|
||||
else if (return_type == "GLboolean"sv)
|
||||
function_generator.appendln(" return GL_FALSE;");
|
||||
else if (return_type == "GLenum"sv)
|
||||
function_generator.appendln(" return GL_INVALID_OPERATION;");
|
||||
else if (return_type == "GLuint"sv)
|
||||
function_generator.appendln(" return 0;");
|
||||
else if (return_type == "void"sv)
|
||||
function_generator.appendln(" return;");
|
||||
else
|
||||
VERIFY_NOT_REACHED();
|
||||
function_generator.append(" ");
|
||||
if (return_type != "void"sv)
|
||||
function_generator.append("return ");
|
||||
function_generator.append("g_gl_context->gl_@implementation@(");
|
||||
|
||||
first = true;
|
||||
for (auto const& argument_definition : function_definition.arguments) {
|
||||
auto argument_generator = function_generator.fork();
|
||||
|
||||
auto cast_to = argument_definition.cast_to;
|
||||
argument_generator.set("argument_name", argument_definition.name.value_or(""));
|
||||
argument_generator.set("cast_to", cast_to.value_or(""));
|
||||
|
||||
if (!first)
|
||||
argument_generator.append(", ");
|
||||
first = false;
|
||||
|
||||
if (cast_to.has_value())
|
||||
argument_generator.append("static_cast<@cast_to@>(");
|
||||
argument_generator.append(argument_definition.expression);
|
||||
if (cast_to.has_value())
|
||||
argument_generator.append(")");
|
||||
}
|
||||
|
||||
function_generator.appendln(");");
|
||||
}
|
||||
|
||||
function_generator.appendln("}");
|
||||
function_generator.append("\n");
|
||||
}
|
||||
});
|
||||
|
||||
TRY(file.write(generator.as_string_view().bytes()));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<JsonValue> read_entire_file_as_json(StringView filename)
|
||||
{
|
||||
auto file = TRY(Core::Stream::File::open(filename, Core::Stream::OpenMode::Read));
|
||||
auto json_size = TRY(file->size());
|
||||
auto json_data = TRY(ByteBuffer::create_uninitialized(json_size));
|
||||
TRY(file->read_entire_buffer(json_data.bytes()));
|
||||
return JsonValue::from_string(json_data);
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
StringView generated_implementation_path;
|
||||
StringView api_json_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(generated_header_path, "Path to the OpenGL API header file to generate", "generated-header-path", 'h', "generated-header-path");
|
||||
args_parser.add_option(generated_implementation_path, "Path to the OpenGL API implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
|
||||
args_parser.add_option(api_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
auto json = TRY(read_entire_file_as_json(api_json_path));
|
||||
VERIFY(json.is_object());
|
||||
auto api_data = json.as_object();
|
||||
|
||||
auto generated_header_file = TRY(Core::Stream::File::open(generated_header_path, Core::Stream::OpenMode::Write));
|
||||
auto generated_implementation_file = TRY(Core::Stream::File::open(generated_implementation_path, Core::Stream::OpenMode::Write));
|
||||
|
||||
TRY(generate_header_file(api_data, *generated_header_file));
|
||||
TRY(generate_implementation_file(api_data, *generated_implementation_file));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
include(libgl_generators)
|
||||
|
||||
set(SOURCES
|
||||
Buffer/Buffer.cpp
|
||||
Buffer.cpp
|
||||
ClipPlane.cpp
|
||||
ContextParameter.cpp
|
||||
GLAPI.cpp
|
||||
GLContext.cpp
|
||||
Image.cpp
|
||||
Lighting.cpp
|
||||
|
@ -19,5 +20,10 @@ set(SOURCES
|
|||
Vertex.cpp
|
||||
)
|
||||
|
||||
generate_libgl_implementation()
|
||||
|
||||
set(GENERATED_SOURCES
|
||||
GLAPI.cpp)
|
||||
|
||||
serenity_lib(LibGL gl)
|
||||
target_link_libraries(LibGL PRIVATE LibCore LibGfx LibGLSL LibGPU)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
|
||||
* Copyright (c) 2021, Stephan Unverwerth <s.unverwerth@serenityos.org>
|
||||
* Copyright (c) 2021, Jelle Raaijmakers <jelle@gmta.nl>
|
||||
* Copyright (c) 2021-2022, Jelle Raaijmakers <jelle@gmta.nl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGL/GL/glapi.h>
|
||||
#include <LibGL/GL/glplatform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -610,231 +611,6 @@ extern "C" {
|
|||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_SHADER_SOURCE_LENGTH 0x8B88
|
||||
|
||||
GLAPI void glBegin(GLenum mode);
|
||||
GLAPI void glClear(GLbitfield mask);
|
||||
GLAPI void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
GLAPI void glClearDepth(GLdouble depth);
|
||||
GLAPI void glClearDepthf(GLfloat depth);
|
||||
GLAPI void glClearStencil(GLint s);
|
||||
GLAPI void glColor3d(GLdouble r, GLdouble g, GLdouble b);
|
||||
GLAPI void glColor3dv(GLdouble const* v);
|
||||
GLAPI void glColor3f(GLfloat r, GLfloat g, GLfloat b);
|
||||
GLAPI void glColor3fv(GLfloat const* v);
|
||||
GLAPI void glColor3ub(GLubyte r, GLubyte g, GLubyte b);
|
||||
GLAPI void glColor3ubv(GLubyte const* v);
|
||||
GLAPI void glColor4b(GLbyte r, GLbyte g, GLbyte b, GLbyte a);
|
||||
GLAPI void glColor4dv(GLdouble const* v);
|
||||
GLAPI void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
GLAPI void glColor4fv(GLfloat const* v);
|
||||
GLAPI void glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
|
||||
GLAPI void glColor4ubv(GLubyte const* v);
|
||||
GLAPI void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
GLAPI void glColorMaterial(GLenum face, GLenum mode);
|
||||
GLAPI void glDeleteTextures(GLsizei n, GLuint const* textures);
|
||||
GLAPI void glEnd();
|
||||
GLAPI void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);
|
||||
GLAPI void glGenTextures(GLsizei n, GLuint* textures);
|
||||
GLAPI GLenum glGetError();
|
||||
GLAPI GLubyte const* glGetString(GLenum name);
|
||||
GLAPI void glLoadIdentity();
|
||||
GLAPI void glLoadMatrixd(GLdouble const* matrix);
|
||||
GLAPI void glLoadMatrixf(GLfloat const* matrix);
|
||||
GLAPI void glMatrixMode(GLenum mode);
|
||||
GLAPI void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);
|
||||
GLAPI void glPushMatrix();
|
||||
GLAPI void glPopMatrix();
|
||||
GLAPI void glMultMatrixd(GLdouble const* matrix);
|
||||
GLAPI void glMultMatrixf(GLfloat const* matrix);
|
||||
GLAPI void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||
GLAPI void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
GLAPI void glScaled(GLdouble x, GLdouble y, GLdouble z);
|
||||
GLAPI void glScalef(GLfloat x, GLfloat y, GLfloat z);
|
||||
GLAPI void glTranslated(GLdouble x, GLdouble y, GLdouble z);
|
||||
GLAPI void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
|
||||
GLAPI void glVertex2d(GLdouble x, GLdouble y);
|
||||
GLAPI void glVertex2dv(GLdouble const* v);
|
||||
GLAPI void glVertex2f(GLfloat x, GLfloat y);
|
||||
GLAPI void glVertex2fv(GLfloat const* v);
|
||||
GLAPI void glVertex2i(GLint x, GLint y);
|
||||
GLAPI void glVertex2iv(GLint const* v);
|
||||
GLAPI void glVertex2s(GLshort x, GLshort y);
|
||||
GLAPI void glVertex2sv(GLshort const* v);
|
||||
GLAPI void glVertex3d(GLdouble x, GLdouble y, GLdouble z);
|
||||
GLAPI void glVertex3dv(GLdouble const* v);
|
||||
GLAPI void glVertex3f(GLfloat x, GLfloat y, GLfloat z);
|
||||
GLAPI void glVertex3fv(GLfloat const* v);
|
||||
GLAPI void glVertex3i(GLint x, GLint y, GLint z);
|
||||
GLAPI void glVertex3iv(GLint const* v);
|
||||
GLAPI void glVertex3s(GLshort x, GLshort y, GLshort z);
|
||||
GLAPI void glVertex3sv(GLshort const* v);
|
||||
GLAPI void glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
GLAPI void glVertex4dv(GLdouble const* v);
|
||||
GLAPI void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
GLAPI void glVertex4fv(GLfloat const* v);
|
||||
GLAPI void glVertex4i(GLint x, GLint y, GLint z, GLint w);
|
||||
GLAPI void glVertex4iv(GLint const* v);
|
||||
GLAPI void glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
GLAPI void glVertex4sv(GLshort const* v);
|
||||
GLAPI void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI void glEnable(GLenum cap);
|
||||
GLAPI void glDisable(GLenum cap);
|
||||
GLAPI GLboolean glIsEnabled(GLenum cap);
|
||||
GLAPI void glCullFace(GLenum mode);
|
||||
GLAPI void glFrontFace(GLenum mode);
|
||||
GLAPI GLuint glGenLists(GLsizei range);
|
||||
GLAPI void glCallList(GLuint list);
|
||||
GLAPI void glCallLists(GLsizei n, GLenum type, void const* lists);
|
||||
GLAPI void glDeleteLists(GLuint list, GLsizei range);
|
||||
GLAPI void glListBase(GLuint base);
|
||||
GLAPI void glEndList(void);
|
||||
GLAPI void glNewList(GLuint list, GLenum mode);
|
||||
GLAPI GLboolean glIsList(GLuint list);
|
||||
GLAPI void glFlush();
|
||||
GLAPI void glFinish();
|
||||
GLAPI void glBlendFunc(GLenum sfactor, GLenum dfactor);
|
||||
GLAPI void glShadeModel(GLenum mode);
|
||||
GLAPI void glAlphaFunc(GLenum func, GLclampf ref);
|
||||
GLAPI void glHint(GLenum target, GLenum mode);
|
||||
GLAPI void glReadBuffer(GLenum mode);
|
||||
GLAPI void glDrawBuffer(GLenum buffer);
|
||||
GLAPI void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
|
||||
GLAPI void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, GLvoid const* data);
|
||||
GLAPI void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid const* data);
|
||||
GLAPI void glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLvoid const* data);
|
||||
GLAPI void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid const* data);
|
||||
GLAPI void glTexCoord1f(GLfloat s);
|
||||
GLAPI void glTexCoord1fv(GLfloat const* v);
|
||||
GLAPI void glTexCoord2d(GLdouble s, GLdouble t);
|
||||
GLAPI void glTexCoord2dv(GLdouble const* v);
|
||||
GLAPI void glTexCoord2f(GLfloat s, GLfloat t);
|
||||
GLAPI void glTexCoord2fv(GLfloat const* v);
|
||||
GLAPI void glTexCoord2i(GLint s, GLint t);
|
||||
GLAPI void glTexCoord3f(GLfloat s, GLfloat t, GLfloat r);
|
||||
GLAPI void glTexCoord3fv(GLfloat const* v);
|
||||
GLAPI void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
GLAPI void glTexCoord4fv(GLfloat const* v);
|
||||
GLAPI void glMultiTexCoord1f(GLenum target, GLfloat s);
|
||||
GLAPI void glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t);
|
||||
GLAPI void glMultiTexCoord2fvARB(GLenum target, GLfloat const* v);
|
||||
GLAPI void glMultiTexCoord2fv(GLenum target, GLfloat const* v);
|
||||
GLAPI void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t);
|
||||
GLAPI void glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r);
|
||||
GLAPI void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
GLAPI void glTexParameteri(GLenum target, GLenum pname, GLint param);
|
||||
GLAPI void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
|
||||
GLAPI void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
|
||||
GLAPI void glTexEnvi(GLenum target, GLenum pname, GLint param);
|
||||
GLAPI void glBindTexture(GLenum target, GLuint texture);
|
||||
GLAPI GLboolean glIsTexture(GLuint texture);
|
||||
GLAPI void glActiveTextureARB(GLenum texture);
|
||||
GLAPI void glActiveTexture(GLenum texture);
|
||||
GLAPI void glGetBooleanv(GLenum pname, GLboolean* data);
|
||||
GLAPI void glGetDoublev(GLenum pname, GLdouble* params);
|
||||
GLAPI void glGetFloatv(GLenum pname, GLfloat* params);
|
||||
GLAPI void glGetIntegerv(GLenum pname, GLint* data);
|
||||
GLAPI void glGetLightfv(GLenum light, GLenum pname, GLfloat* params);
|
||||
GLAPI void glGetLightiv(GLenum light, GLenum pname, GLint* params);
|
||||
GLAPI void glGetMaterialfv(GLenum face, GLenum pname, GLfloat* params);
|
||||
GLAPI void glGetMaterialiv(GLenum face, GLenum pname, GLint* params);
|
||||
GLAPI void glDepthMask(GLboolean flag);
|
||||
GLAPI void glEnableClientState(GLenum cap);
|
||||
GLAPI void glDisableClientState(GLenum cap);
|
||||
GLAPI void glClientActiveTextureARB(GLenum target);
|
||||
GLAPI void glClientActiveTexture(GLenum target);
|
||||
GLAPI void glVertexPointer(GLint size, GLenum type, GLsizei stride, void const* pointer);
|
||||
GLAPI void glColorPointer(GLint size, GLenum type, GLsizei stride, void const* pointer);
|
||||
GLAPI void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, void const* pointer);
|
||||
GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
GLAPI void glDrawElements(GLenum mode, GLsizei count, GLenum type, void const* indices);
|
||||
GLAPI void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, void const* data);
|
||||
GLAPI void glDepthRange(GLdouble nearVal, GLdouble farVal);
|
||||
GLAPI void glDepthFunc(GLenum func);
|
||||
GLAPI void glPolygonMode(GLenum face, GLenum mode);
|
||||
GLAPI void glPolygonOffset(GLfloat factor, GLfloat units);
|
||||
GLAPI void glFogfv(GLenum mode, GLfloat const* params);
|
||||
GLAPI void glFogf(GLenum pname, GLfloat param);
|
||||
GLAPI void glFogi(GLenum pname, GLint param);
|
||||
GLAPI void glPixelStorei(GLenum pname, GLint param);
|
||||
GLAPI void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI void glLightf(GLenum light, GLenum pname, GLfloat param);
|
||||
GLAPI void glLightfv(GLenum light, GLenum pname, GLfloat const* params);
|
||||
GLAPI void glLighti(GLenum light, GLenum pname, GLint param);
|
||||
GLAPI void glLightiv(GLenum light, GLenum pname, GLint const* params);
|
||||
GLAPI void glLightModelf(GLenum pname, GLfloat param);
|
||||
GLAPI void glLightModelfv(GLenum pname, GLfloat const* params);
|
||||
GLAPI void glLightModeli(GLenum pname, GLint param);
|
||||
GLAPI void glLightModeliv(GLenum pname, GLint const* params);
|
||||
GLAPI void glStencilFunc(GLenum func, GLint ref, GLuint mask);
|
||||
GLAPI void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
GLAPI void glStencilMask(GLuint mask);
|
||||
GLAPI void glStencilMaskSeparate(GLenum face, GLuint mask);
|
||||
GLAPI void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||
GLAPI void glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||
GLAPI void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz);
|
||||
GLAPI void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
GLAPI void glNormal3fv(GLfloat const* v);
|
||||
GLAPI void glNormalPointer(GLenum type, GLsizei stride, void const* pointer);
|
||||
GLAPI void glRasterPos2d(GLdouble x, GLdouble y);
|
||||
GLAPI void glRasterPos2f(GLfloat x, GLfloat y);
|
||||
GLAPI void glRasterPos2i(GLint x, GLint y);
|
||||
GLAPI void glRasterPos2s(GLshort x, GLshort y);
|
||||
GLAPI void glMaterialf(GLenum face, GLenum pname, GLfloat param);
|
||||
GLAPI void glMaterialfv(GLenum face, GLenum pname, GLfloat const* params);
|
||||
GLAPI void glMateriali(GLenum face, GLenum pname, GLint param);
|
||||
GLAPI void glMaterialiv(GLenum face, GLenum pname, GLint const* params);
|
||||
GLAPI void glLineWidth(GLfloat width);
|
||||
GLAPI void glPushAttrib(GLbitfield mask);
|
||||
GLAPI void glPopAttrib();
|
||||
GLAPI void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap);
|
||||
GLAPI void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
GLAPI void glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, GLdouble const* points);
|
||||
GLAPI void glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, GLfloat const* points);
|
||||
GLAPI void glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble const* points);
|
||||
GLAPI void glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat const* points);
|
||||
GLAPI void glMapGrid1d(GLint un, GLdouble u1, GLdouble u2);
|
||||
GLAPI void glMapGrid1f(GLint un, GLfloat u1, GLfloat u2);
|
||||
GLAPI void glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
|
||||
GLAPI void glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
|
||||
GLAPI void glEvalCoord1d(GLdouble u);
|
||||
GLAPI void glEvalCoord1f(GLfloat u);
|
||||
GLAPI void glEvalCoord2d(GLdouble u, GLdouble v);
|
||||
GLAPI void glEvalCoord2f(GLfloat u, GLfloat v);
|
||||
GLAPI void glEvalMesh1(GLenum mode, GLint i1, GLint i2);
|
||||
GLAPI void glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
|
||||
GLAPI void glEvalPoint1(GLint i);
|
||||
GLAPI void glEvalPoint2(GLint i, GLint j);
|
||||
GLAPI void glTexGend(GLenum coord, GLenum pname, GLdouble param);
|
||||
GLAPI void glTexGenf(GLenum coord, GLenum pname, GLfloat param);
|
||||
GLAPI void glTexGenfv(GLenum coord, GLenum pname, GLfloat const* params);
|
||||
GLAPI void glTexGeni(GLenum coord, GLenum pname, GLint param);
|
||||
GLAPI void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
||||
GLAPI void glRecti(GLint x1, GLint y1, GLint x2, GLint y2);
|
||||
GLAPI void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
|
||||
GLAPI void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
GLAPI void glPointSize(GLfloat size);
|
||||
GLAPI void glClipPlane(GLenum plane, GLdouble const* equation);
|
||||
GLAPI void glGetClipPlane(GLenum plane, GLdouble* equation);
|
||||
GLAPI void glArrayElement(GLint i);
|
||||
GLAPI void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI void glBindBuffer(GLenum target, GLuint buffer);
|
||||
GLAPI void glBufferData(GLenum target, GLsizeiptr size, void const* data, GLenum usage);
|
||||
GLAPI void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void const* data);
|
||||
GLAPI void glDeleteBuffers(GLsizei n, GLuint const* buffers);
|
||||
GLAPI void glGenBuffers(GLsizei n, GLuint* buffers);
|
||||
|
||||
GLAPI GLuint glCreateShader(GLenum shader_type);
|
||||
GLAPI void glDeleteShader(GLuint shader);
|
||||
GLAPI void glShaderSource(GLuint shader, GLsizei count, GLchar const** string, GLint const* length);
|
||||
GLAPI void glCompileShader(GLuint shader);
|
||||
GLAPI void glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
|
||||
|
||||
GLAPI GLuint glCreateProgram();
|
||||
GLAPI void glDeleteProgram(GLuint program);
|
||||
GLAPI void glAttachShader(GLuint program, GLuint shader);
|
||||
GLAPI void glLinkProgram(GLuint program);
|
||||
GLAPI void glUseProgram(GLuint program);
|
||||
GLAPI void glGetProgramiv(GLuint program, GLenum pname, GLint* params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
1162
Userland/Libraries/LibGL/GLAPI.json
Normal file
1162
Userland/Libraries/LibGL/GLAPI.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -574,6 +574,36 @@ private:
|
|||
RefPtr<Buffer> m_element_array_buffer;
|
||||
};
|
||||
|
||||
// Transposes input matrices (column-major) to our Matrix (row-major).
|
||||
template<typename I>
|
||||
constexpr FloatMatrix4x4 transpose_input_matrix(I const* matrix)
|
||||
{
|
||||
Array<float, 16> elements;
|
||||
for (size_t i = 0; i < 16; ++i)
|
||||
elements[i] = static_cast<float>(matrix[i]);
|
||||
// clang-format off
|
||||
return {
|
||||
elements[0], elements[4], elements[8], elements[12],
|
||||
elements[1], elements[5], elements[9], elements[13],
|
||||
elements[2], elements[6], elements[10], elements[14],
|
||||
elements[3], elements[7], elements[11], elements[15],
|
||||
};
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr FloatMatrix4x4 transpose_input_matrix(float const* matrix)
|
||||
{
|
||||
// clang-format off
|
||||
return {
|
||||
matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15],
|
||||
};
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
ErrorOr<NonnullOwnPtr<GLContext>> create_context(Gfx::Bitmap&);
|
||||
void make_context_current(GLContext*);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue