Giter Site home page Giter Site logo

bindbc-opengl's Introduction

BindBC-OpenGL

This project provides dynamic bindings to the OpenGL library. It supports OpenGL versions up to and including 4.6, along with numerous extensions (if an extension you need is not yet supported, please submit a PR or open an issue). BindBC-OpenGL is compatible with @nogc and nothrow and can be compiled with BetterC compatibility. This package is intended as a replacement of DerelictGL3, which does not provide the same level of compatibility.

NOTE: BindBC-OpenGL does not support static binding due to the nature of the OpenGL API.

NOTE: This documentation describes how to use BindBC-OpenGL. As the maintainer of this library, I do not provide instructions on using the OpenGL library. However, since this is a direct binding to the OpenGL API, existing OpenGL documentation and tutorials can be adapted to D with few modifications (those being minor differences in the language, such as array declaration syntax). The tutorial at learnopengl.com is a particularly good introduction to OpenGL for those who have little or no experience with the API. For documentation, I prefer the layout of docs.gl over that of the Khronos site.

Add BindBC-OpenGL to your project

By default, BindBC-OpenGL is configured to compile with BetterC compatibility disabled and with support only for up to OpenGL 2.1 core. To use BindBC-OpenGL in this default mode, simply add the package as a dependency in your dub.json or dub.sdl recipe.

Example: dub.json

"dependencies": {
	"bindbc-opengl": "~>1.1.0"
}

Example: dub.sdl

dependency "bindbc-opengl" version="~>1.1.0"

Enable BetterC support

If you are using BetterC, add the dynamicBC sub-configuration to your package recipe.

Example: dub.json

"subConfigurations": {
	"bindbc-opengl": "dynamicBC"
},

Example: dub.sdl

subConfiguration "bindbc-opengl" "dynamicBC"

Enable support for OpenGL 3.0 and higher

Support for OpenGL versions can be configured at compile time by adding the appropriate version to a versions directive in your package configuration file (or on the command line if you are building with a tool other than dub).

BindBC-OpenGL supports a D version identifier for each OpenGL version. The following table lists each identifier and the OpenGL versions they enable.

OpenGL versions Version identifier
1.0–2.1 Default
1.0–3.0 GL_30
1.0–3.1 GL_31
1.0–3.2 GL_32
1.0–3.3 GL_33
1.0–4.0 GL_40
1.0–4.1 GL_41
1.0–4.2 GL_42
1.0–4.3 GL_43
1.0–4.4 GL_44
1.0–4.5 GL_45
1.0–4.6 GL_46

Note

If you use versions higher than OpenGL 4.1, then your application will not work on macOS; due to OpenGL being deprecated on macOS.

Adding one of these version identifiers to your package recipe will do two things:

  • symbols for the core types and functions in the supported OpenGL versions will be declared and available in user code
  • the loadOpenGL function will attempt to load all OpenGL versions for which support is enabled and which is supported by the OpenGL context at run time.

To load all functions and enable all constants from "classic" OpenGL versions, including those that have been deprecated, set the version identifier GL_AllowDeprecated in your build system. Note that doing so means you may need to take special steps to configure your OpenGL context to ensure the deprecated functions are made available by the driver. Check the documentation of the API you are using for OpenGL context creation.

The following examples are configured to load the core functions from all OpenGL versions up to OpenGL 4.1:

dub.json

"dependencies": {
	"bindbc-opengl": "~>1.1.0"
}
"versions": [
	"GL_41"
],

dub.sdl

dependency "bindbc-opengl" version="~>1.1.0"
versions "GL_41"

With this configuration, client code can make use of all core OpenGL types and functions up to OpenGL 4.1. At run time, if the context supports OpenGL 4.1 or higher, the loader will attempt to load up to OpenGL 4.1. If the highest OpenGL version the context supports is lower than 4.1, the loader will attempt to load up to that version.

To enable the loading of deprecated functions in the same configuration:

dub.json

"dependencies": {
	"bindbc-opengl": "~>1.1.0"
}
"versions": [
	"GL_41", "GL_AllowDeprecated"
],

dub.sdl

dependency "bindbc-opengl" version="~>1.1.0"
versions "GL_41" "GL_AllowDeprecated"

With this, all OpenGL functions, both core and deprecated, will be loaded if the context has been configured appropriately and they are supported by the driver. Some deprecated features were removed from the specification in later versions of OpenGL.

GL_AllowDeprecated by itself enables support for deprecated functions and constants from OpenGL versions 1.0 - 2.1. When GL_AllowDeprecated is specified in conjunction with GL_30 or higher, support for deprecated constants from OpenGL version 3.0 will be enabled.

Enable support for extensions

Extension support is enabled on an as-needed basis. All supported ARB/KHR extensions can be enabled by adding the GL_ARB version identifier to your dub.json or dub.sdl. Supported NV (Nvidia) extensions are enabled via GL_NV.

For example, the following enables support for all core OpenGL functions up to and including GL 4.1, as well as all ARB/KHR extensions:

dub.json

"dependencies": {
	"bindbc-opengl": "~>1.1.0"
}
"versions": [
	"GL_41",
	"GL_ARB"
],

dub.sdl

dependency "bindbc-opengl" version="~>1.1.0"
versions "GL_41" "GL_ARB"

Extensions which were promoted to the core OpenGL API are loaded automatically along with the OpenGL version APIs to which they belong.

Specific extensions can be enabled using the extension's OpenGL name string as a version identifier. The name string for each extension is listed below. They the form of GL_ prefixed to the extension name.

Version added to core OpenGL extension Version identifier
N/A ARB_bindless_texture GL_ARB_bindless_texture
N/A ARB_cl_event GL_ARB_cl_event
N/A ARB_compute_variable_group_size GL_ARB_compute_variable_group_size
N/A ARB_debug_output GL_ARB_debug_output
N/A ARB_framebuffer_sRGB GL_ARB_framebuffer_sRGB
N/A ARB_geometry_shader4 GL_ARB_geometry_shader4
N/A ARB_gl_spirv GL_ARB_gl_spirv
N/A ARB_gpu_shader_int64 GL_ARB_gpu_shader_int64
N/A ARB_indirect_parameters GL_ARB_indirect_parameters
N/A ARB_instanced_arrays GL_ARB_instanced_arrays
N/A ARB_pipeline_statistics_query GL_ARB_pipeline_statistics_query
N/A ARB_robustness_isolation GL_ARB_robustness_isolation
N/A ARB_sample_shading GL_ARB_sample_shading
N/A ARB_texture_buffer_object GL_ARB_texture_buffer_object
N/A ARB_texture_compression_bptc GL_ARB_texture_compression_bptc
N/A ARB_texture_cube_map_array GL_ARB_texture_cube_map_array
N/A ARB_texture_gather GL_ARB_texture_gather
N/A ARB_transform_feedback_overflow_query GL_ARB_transform_feedback_overflow_query
N/A ARB_sparse_texture GL_ARB_sparse_texture
N/A ARB_sparse_texture2 GL_ARB_sparse_texture2
N/A ARB_sparse_texture_clamp GL_ARB_sparse_texture_clamp
3.0 ARB_depth_buffer_float GL_ARB_depth_buffer_float
3.0 ARB_half_float_vertex GL_ARB_half_float_vertex
3.0 ARB_texture_compression_rgtc GL_ARB_texture_compression_rgtc
3.0 ARB_texture_rg GL_ARB_texture_rg
3.0 ARB_framebuffer_object GL_ARB_framebuffer_object
3.0 ARB_map_buffer_range GL_ARB_map_buffer_range
3.0 ARB_vertex_array_object GL_ARB_vertex_array_object
3.1 ARB_copy_buffer GL_ARB_copy_buffer
3.1 ARB_uniform_buffer_object GL_ARB_uniform_buffer_object
3.2 ARB_depth_clamp GL_ARB_depth_clamp
3.2 ARB_provoking_vertex GL_ARB_provoking_vertex
3.2 ARB_seamless_cube_map GL_ARB_seamless_cube_map
3.2 ARB_draw_elements_base_vertex GL_ARB_draw_elements_base_vertex
3.2 ARB_sync GL_ARB_sync
3.2 ARB_texture_multisample GL_ARB_texture_multisample
3.3 ARB_occlusion_query2 GL_ARB_occlusion_query2
3.3 ARB_texture_rgb10_a2ui GL_ARB_texture_rgb10_a2ui
3.3 ARB_texture_swizzle GL_ARB_texture_swizzle
3.3 ARB_blend_func_extended GL_ARB_blend_func_extended
3.3 ARB_sampler_objects GL_ARB_sampler_objects
3.3 ARB_timer_query GL_ARB_timer_query
3.3 ARB_vertex_type_2_10_10_10_rev GL_ARB_vertex_type_2_10_10_10_rev
4.0 ARB_gpu_shader5 GL_ARB_gpu_shader5
4.0 ARB_draw_indirect GL_ARB_draw_indirect
4.0 ARB_gpu_shader_fp64 GL_ARB_gpu_shader_fp64
4.0 ARB_shader_subroutine GL_ARB_shader_subroutine
4.0 ARB_tessellation_shader GL_ARB_tessellation_shader
4.0 ARB_transform_feedback2 GL_ARB_transform_feedback2
4.0 ARB_transform_feedback3 GL_ARB_transform_feedback3
4.1 ARB_ES2_compatibility GL_ARB_ES2_compatibility
4.1 ARB_get_program_binary GL_ARB_get_program_binary
4.1 ARB_separate_shader_objects GL_ARB_separate_shader_objects
4.1 ARB_vertex_attrib_64bit GL_ARB_vertex_attrib_64bit
4.1 ARB_viewport_array GL_ARB_viewport_array
4.2 ARB_base_instance GL_ARB_base_instance
4.2 ARB_compressed_texture_pixel_storage GL_ARB_compressed_texture_pixel_storage
4.2 ARB_internalformat_query GL_ARB_internalformat_query
4.2 ARB_map_buffer_alignment GL_ARB_map_buffer_alignment
4.2 ARB_shader_image_load_store GL_ARB_shader_image_load_store
4.2 ARB_texture_storage GL_ARB_texture_storage
4.2 ARB_transform_feedback_instanced GL_ARB_transform_feedback_instanced
4.3 ARB_clear_buffer_object GL_ARB_clear_buffer_object
4.3 ARB_compute_shader GL_ARB_compute_shader
4.3 ARB_copy_image GL_ARB_copy_image
4.3 ARB_ES3_compatibility GL_ARB_ES3_compatibility
4.3 ARB_explicit_uniform_location GL_ARB_explicit_uniform_location
4.3 ARB_framebuffer_no_attachments GL_ARB_framebuffer_no_attachments
4.3 ARB_internalformat_query2 GL_ARB_internalformat_query2
4.3 ARB_invalidate_subdata GL_ARB_invalidate_subdata
4.3 ARB_multi_draw_indirect GL_ARB_multi_draw_indirect
4.3 ARB_program_interface_query GL_ARB_program_interface_query
4.3 ARB_shader_storage_buffer_object GL_ARB_shader_storage_buffer_object
4.3 ARB_stencil_texturing GL_ARB_stencil_texturing
4.3 ARB_texture_buffer_range GL_ARB_texture_buffer_range
4.3 ARB_texture_storage_multisample GL_ARB_texture_storage_multisample
4.3 ARB_texture_view GL_ARB_texture_view
4.3 ARB_vertex_attrib_binding GL_ARB_vertex_attrib_binding
4.3 KHR_debug GL_KHR_debug
4.4 ARB_buffer_storage GL_ARB_buffer_storage
4.4 ARB_clear_texture GL_ARB_clear_texture
4.4 ARB_enhanced_layouts GL_ARB_enhanced_layouts
4.4 ARB_multi_bind GL_ARB_multi_bind
4.4 ARB_query_buffer_object GL_ARB_query_buffer_object
4.4 ARB_texture_mirror_clamp_to_edge GL_ARB_texture_mirror_clamp_to_edge
4.5 ARB_clip_control GL_ARB_clip_control
4.5 ARB_conditional_render_inverted GL_ARB_conditional_render_inverted
4.5 ARB_cull_distance GL_ARB_cull_distance
4.5 ARB_direct_state_access GL_ARB_direct_state_access
4.5 ARB_ES3_1_compatibility GL_ARB_ES3_1_compatibility
4.5 ARB_get_texture_sub_image GL_ARB_get_texture_sub_image
4.5 ARB_texture_barrier GL_ARB_texture_barrier
4.5 KHR_context_flush_control GL_KHR_context_flush_control
4.5 KHR_robustness GL_KHR_robustness
4.6 ARB_polygon_offset_clamp GL_ARB_polygon_offset_clamp
4.6 ARB_texture_filter_anisotropic GL_ARB_texture_filter_anisotropic
N/A KHR_blend_equation_advanced GL_KHR_blend_equation_advanced
N/A NV_shader_buffer_load GL_NV_shader_buffer_load
N/A NV_vertex_buffer_unified_memory GL_NV_vertex_buffer_unified_memory
N/A NV_command_list GL_NV_command_list

For example, the following configurations enable support for OpenGL 4.1 and the extensions ARB_base_instance and ARB_compressed_texture_pixel_storage, both of which were promoted to core in OpenGL 4.2:

dub.json

"dependencies": {
	"bindbc-opengl": "~>1.1.0"
}
"versions": [
	"GL_41",
	"GL_ARB_base_instance",
	"GL_ARB_compressed_texture_pixel_storage"
],

dub.sdl

dependency "bindbc-opengl" version="~>1.1.0"
versions "GL_41" "GL_ARB_base_instance" "GL_ARB_compressed_texture_pixel_storage"

The loadOpenGL function (described in the next section) will attempt to load all extensions configured in this manner. No errors will be reported on failure. To determine if an extension was loaded, use the has* property for each extension, like so:

import bindbc.opengl;

// Create the OpenGL context and load OpenGl
...
// Check for required extensions
if(hasARBBaseInstance){
	// configure renderer for GL_ARB_base_instance support
}
if(hasARBCompressedTexturePixelStorage){
	// configure renderer for GL_ARB_compressed_texture_pixel_storage support
}

If you have a need for an extension that is not currently supported then please submit a pull request.

Loading OpenGL

The loadOpenGL function is used to load all supported OpenGL functions and extensions. In order for this function to succeed, an OpenGL context must be created before it is called. The return value of loadOpenGL can be used to determine which version of OpenGL actually loaded.

For example, assume you've configured BindBC-OpenGL to support up to OpenGL 4.1, but you've designed your renderer to work with both 4.1 and 3.3. You can create a 4.1 or 3.3 context in one part of your code, then load OpenGL in another part, and configure your renderer based upon the return value.

import bindbc.opengl;

// Create OpenGL context
...
// Load supported OpenGL version + supported extensions
GLSupport retVal = loadOpenGL();
if(retVal == GLSupport.gl41){
	// configure renderer for OpenGL 4.1
}else if(retVal == GLSupport.gl33){
	// configure renderer for OpenGL 3.3
}else{
	// Error
}

Note

loadOpenGL returns the highest version that was loaded. On some systems, deprecated OpenGL functions (e.g. from OpenGL 1.2) may be missing, so if you rely on these you should check that they were loaded using versionLoadedStatus:

if((versionLoadedStatus(GLSupport.gl12) & GLLoadStatus.loaded) == 0){
  //OpenGL 1.2 functions were not loaded!
}

On error, loadOpenGL will return one of the following:

  • GLSupport.noLibrary - the OpenGL shared library failed to load
  • GLSupport.badLibrary - one of the context-independent symbols (OpenGL 1.0 & 1.1) in the OpenGL shared library failed to load.
  • GLSupport.noContext - an OpenGL context was not created before calling the function. When asserts are enabled, calling loadOpenGL before a context is created will trigger an assertion failure instead.

The following functions are provided for convenience:

  • isOpenGLLoaded - returns true if any version of OpenGL has been successfully loaded and false otherwise.
  • openGLContextVersion - returns a GLSupport member corresponding to the version supported by the OpenGL context against which the library was loaded.
  • loadedOpenGLVersion - returns a GLSupport member corresponding to the version of OpenGL currently loaded (identical to the return value of loadOpenGL).

Note that when working with multiple contexts, it may be necessary to call loadOpenGL on every context switch. On Windows in particular, a context switch may cause context-dependent functions, i.e., core functions above 1.1 and all extensions, to become invalid in some circumstances.

The error reporting API in bindbc.loader can be used to facilitate logging error messages.

// Import the dependent package
import bindbc.opengl;

/*
 Import the sharedlib module for error handling. Assigning an alias ensures the function names do not conflict with
 other public APIs. This isn't strictly necessary, but the API names are common enough that they could appear in other
 packages.
*/
import loader = bindbc.loader.sharedlib;

// Create the OpenGL context before calling this function.
bool loadLib(){
	/*
	Compare the return value of loadGL with the global `glSupport` constant to determine if the version of GLFW
	configured at compile time is the version that was loaded.
	*/
	auto ret = loadOpenGL();
	if(ret != glSupport){
		// Log the error info
		foreach(info; loader.errors){
			/*
			A hypothetical logging function. Note that `info.error` and `info.message` are `const(char)*`, not
			`string`.
			*/
			logError(info.error, info.message);
		}
		
		// Optionally construct a user-friendly error message for the user
		string msg;
		if(ret == GLSupport.noLibrary){
			msg = "This application requires OpenGL.";
		}else if(ret == GLSupport.badLibrary){
			msg = "The version of OpenGL on your system is too low. Please upgrade."
		}else{
			// GLSupport.noContext
			msg = "This program has encountered a graphics configuration error. Please report it to the developers."
		}
		// A hypothetical message box function
		showMessageBox(msg);
		return false;
	}
	return true;
}

bindbc-opengl's People

Contributors

andrejmitrovic avatar aodq avatar balnian avatar dayllenger avatar dkorpel avatar grimmaple avatar icerisede avatar ichordev avatar jordan4ibanez avatar lunathefoxgirl avatar mdparker avatar mrcsnm avatar rikkimax avatar s-ludwig avatar tsbockman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bindbc-opengl's Issues

proc address prototype

else version(Posix) {
    enum getCurrentContextName = "glXGetCurrentContext";
    enum getProcAddressName = "glxGetProcAddress";
}

should be glXGetProcAddress or you get a bad lbrary error!

Dont segfault if XDG_SESSION_TYPE is unset.

However if XDG_SESSION_TYPE is unset then this causes a Segmentation Fault.

GDB trace of inochi-creator (unbranded/unsupported) 0.7.4.1

GNU gdb (GDB) Fedora 12.1-2.fc36
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) env LIBGL_ALWAYS_SOFTWARE=yes
Undefined command: "env".  Try "help".
(gdb) set environment LIBGL_ALWAYS_SOFTWARE=yes
(gdb) file inochi-creator
Reading symbols from inochi-creator...
Reading symbols from /usr/lib/debug/usr/bin/inochi-creator-0.7.4.1-1.fc36.x86_64.debug...
(gdb) run
Starting program: /usr/bin/inochi-creator
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff6570640 (LWP 1253348)]
[New Thread 0x7ffff1768640 (LWP 1253349)]
Missing separate debuginfo for /lib64/libGLX_mesa.so.0
Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/5f/377ac39fe57db67f0fefd2f89db20b2d00c113.debug
[New Thread 0x7ffff1215640 (LWP 1253350)]
[New Thread 0x7ffff0a14640 (LWP 1253351)]
[New Thread 0x7fffdffff640 (LWP 1253352)]
[New Thread 0x7fffdf7fe640 (LWP 1253353)]
[New Thread 0x7fffdeffd640 (LWP 1253354)]
[New Thread 0x7fffde7fc640 (LWP 1253355)]
[New Thread 0x7fffddffb640 (LWP 1253356)]
[New Thread 0x7fffdd7fa640 (LWP 1253357)]
[New Thread 0x7fffdcff9640 (LWP 1253358)]
[New Thread 0x7fffbbfff640 (LWP 1253359)]
[New Thread 0x7fffbb7fe640 (LWP 1253360)]
[New Thread 0x7fffbaffd640 (LWP 1253361)]
[New Thread 0x7fffba7fc640 (LWP 1253362)]
[New Thread 0x7fffb9ffb640 (LWP 1253363)]
[New Thread 0x7fffb97fa640 (LWP 1253364)]
[New Thread 0x7fffb8ff9640 (LWP 1253365)]
[New Thread 0x7fff9bfff640 (LWP 1253366)]
[New Thread 0x7fff93fff640 (LWP 1253367)]
[New Thread 0x7fff9b7fe640 (LWP 1253368)]
[New Thread 0x7fff9affd640 (LWP 1253369)]
[New Thread 0x7fff9a7fc640 (LWP 1253370)]
[New Thread 0x7fff99ffb640 (LWP 1253371)]
[New Thread 0x7fff997fa640 (LWP 1253372)]
[New Thread 0x7fff98ff9640 (LWP 1253373)]
[New Thread 0x7fff937fe640 (LWP 1253374)]
[New Thread 0x7fff92ffd640 (LWP 1253375)]
[New Thread 0x7fff927fc640 (LWP 1253376)]
[New Thread 0x7fff91ffb640 (LWP 1253377)]
[New Thread 0x7fff917fa640 (LWP 1253378)]
[New Thread 0x7fff90ff9640 (LWP 1253379)]
[New Thread 0x7fff5bfff640 (LWP 1253380)]
[New Thread 0x7fff5b7fe640 (LWP 1253381)]
[New Thread 0x7fff5affd640 (LWP 1253382)]

Thread 1 "inochi-creator" received signal SIGSEGV, Segmentation fault.
__strcmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:284
284		VMOVU	(%rdi), %ymm0
(gdb) where
#0  __strcmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:284
#1  0x0000000000636878 in _D6bindbc6opengl7context17getContextVersionFNbNiSQBv6loader9sharedlib9SharedLibZEQDbQCx6config9GLSupport (lib=...) at deps/bindbc-opengl/source/bindbc/opengl/context.d:88
#2  0x0000000000636c8f in _D6bindbc6opengl2gl10loadOpenGLFNbNiPxaZEQBnQBj6config9GLSupport (libName=0x66f787 "libGL.so.1") at deps/bindbc-opengl/source/bindbc/opengl/gl.d:80
#3  0x0000000000636c2d in _D6bindbc6opengl2gl10loadOpenGLFNbNiZEQBkQBg6config9GLSupport () at deps/bindbc-opengl/source/bindbc/opengl/gl.d:57
#4  0x00000000004c4fa0 in _D7creator4core13incOpenWindowFZv () at source/creator/core/package.d:263
#5  0x0000000000533af7 in _Dmain (args=...) at source/app.d:66
(gdb)

Undefined identifiers

I am trying to compile this glfw example which uses bindbc-opengl. When I compile the example I get these errors.

src/app.d(55,9): Error: undefined identifier `glBindVertexArray`
src/app.d(135,5): Error: undefined identifier `glGenVertexArrays`
src/app.d(136,5): Error: undefined identifier `glBindVertexArray`
/usr/bin/dmd failed with exit code 1.

Is the example wrong? Or am I doing something wrong? Or is this a bindbc-opengl issue?

Abandoned?

Will this library be updated or is it abandoned? I want to use it for a project though I am concerned that if I do find a bug it won't get fixed due to development stalling.

OpenGL ES?

Is there any tag for OpenGL ES support, I get errors when creating shaders when using the GL_33 version for OpenGL ES.

Note: The device im trying to use it on supports OpenGL ES 2 (but ES 2 supports the GL 3.3 features I use afaik, that being vbos, vaos and shaders)

Early return on missing deprecated functionality

This code here:

    with (GLSupport)
    static foreach(ver; [ gl12, gl13, gl14, gl15, gl20, gl21, gl30, gl31,
        gl32, gl33, gl40, gl41, gl42, gl43, gl44, gl45, gl46 ])
    {
        static if(ver <= glSupport)
        {
            // lib.loadGL30(contextVersion)
            if(mixin("lib.loadGL" ~ (cast(int)ver).stringof ~ "(contextVersion)"))
                loadedVersion = ver;
            else
                goto LoadARB;
        }
    }

Contains an early return that forces the loadedVersion to always be gl11. It happens on Intel UHD integrated video card because Intel graphics driver seems to be missing some of the deprecated functionality (I only tested 1.2, might have more missing stuff along the line). It seems to be incorrect to blindly assume 2.0 onwards stuff is missing if 1.2 functionality fails to load.

I'm not sure what to do in such a situation though. It is erroneous to assume that 2.0 can't be loaded because 1.2 deprecated failed to load. However, it can also lead to issues if errors are blindly ignored.

It feels to me the best options is to get some sort of supports function, which can be used to test if certain version of opengl successfully loaded

Segfault Crash in WSLg starting from 1.0.1 (not present in 1.0.0)

When using bindbc-opengl 1.0.1 or 1.0.2 in WSL (using WSLg), calling loadOpenGL causes the program to crash without a stacktrace.
Reverting back to 1.0.0 prevents this issue.

Sample Code to Reproduce

import std.stdio;

import bindbc.glfw;
import bindbc.opengl;

void main()
{
    prepareGLFW();

    assert(glfwInit(), "Failed to init GLFW");
    scope (exit) glfwTerminate();

    GLFWwindow* window = glfwCreateWindow(800, 600, "Test", null, null);
    assert(window, "Failed to create a GLFW window");

    glfwMakeContextCurrent(window);

    prepareOpenGL();

    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

private void prepareGLFW()
{
    auto result = loadGLFW();

    if (result != glfwSupport)
    {
        writeln("Result: ", result);
        writeLoadErrors();

        assert(0, "Failed to load GLFW");
    }

    writeln("GLFW loaded: ", result);
}

private void prepareOpenGL()
{
    auto result = loadOpenGL();

    if (result < GLSupport.gl31)
    {
        writeln("Result: ", result);
        writeLoadErrors();

        assert(0, "Failed to load OpenGL");
    }

    writeln("OpenGL loaded: ", result);
}

private void writeLoadErrors()
{
    import std.string : fromStringz;
    import loader = bindbc.loader.sharedlib;

    foreach (error; loader.errors)
    {
        writefln("Error(%s): %s", error.error.fromStringz, error.message.fromStringz);
    }
}

dub.sdl configuration:

dependency "bindbc-freetype" version="~>1.0.3"
dependency "bindbc-glfw" version="~>1.0.1"
dependency "bindbc-opengl" version="~>1.0.2"
versions "GLFW_31" "GL_31"

Expected Output:

Performing "debug" build using /usr/bin/dmd for x86_64.
bindbc-loader 1.0.1: target for configuration "noBC" is up to date.
bindbc-freetype 1.0.3: target for configuration "dynamic" is up to date.
bindbc-glfw 1.0.1: target for configuration "dynamic" is up to date.
bindbc-opengl 1.0.0: target for configuration "dynamic" is up to date.
minuette ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.
Running minuette
GLFW loaded: glfw31
OpenGL loaded: gl31

A blank window opens and remains until closed by the user. This is the behaviour in 1.0.0.

Actual Output

Performing "debug" build using /usr/bin/dmd for x86_64.
bindbc-loader 1.0.1: target for configuration "noBC" is up to date.
bindbc-freetype 1.0.3: target for configuration "dynamic" is up to date.
bindbc-glfw 1.0.1: target for configuration "dynamic" is up to date.
bindbc-opengl 1.0.1: building configuration "dynamic"...
minuette ~master: building configuration "application"...
Linking...
To force a rebuild of up-to-date targets, run again with --force.
Running minuette
GLFW loaded: glfw31
Program exited with code -11

Hardware and Environment Information

WSL Ubuntu 20.04.3 LTS (inside of Windows 11 Pro Build 22000.708)
DUB version 1.26.1, built on Jul 22 2021
DMD64 D Compiler v2.097.2

GLXInfo
Extended renderer info (GLX_MESA_query_renderer):
    Vendor: Microsoft Corporation (0xffffffff)
    Device: D3D12 (Intel(R) Iris(R) Xe Graphics) (0xffffffff)
    Version: 21.2.6
    Accelerated: yes
    Video memory: 32787MB
    Unified memory: yes
    Preferred profile: core (0x1)
    Max core profile version: 3.3
    Max compat profile version: 3.1
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.0
OpenGL vendor string: Microsoft Corporation
OpenGL renderer string: D3D12 (Intel(R) Iris(R) Xe Graphics)
OpenGL core profile version string: 3.3 (Core Profile) Mesa 21.2.6
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

importing bindbc.opengl causes symbol conflicts with stdout

Simple test-case:

import std.stdio;
import bindbc.opengl;

void main()
{
    write("Edit source/app.d to start your project.");
    stdout.flush();
}

$ dub
source/app.d(7,5): Error: function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal at /home/drey/dlang/dmd-2.101.2/linux/bin64/../../src/phobos/std/stdio.d(5192,20) conflicts with variable core.stdc.stdio.stdout at /home/drey/dlang/dmd-2.101.2/linux/bin64/../../src/druntime/import/core/stdc/stdio.d(956,25)
source/app.d(7,11): Error: template makeGlobal(StdFileHandle _iob)() does not have property flush

It's caused by this public import:

debug public import core.stdc.stdio;

Support of GL_SHADING_LANGUAGE_VERSION​

In my code, trying to use a line like

import bindbc.opengl;
...
info ("OpenGL version: " ~ to!string(glGetString(GL_SHADING_LANGUAGE_VERSION​)));

yields

source/dterrent/system/window.d(123,58): Error: char 0x200b not allowed in identifier
source/dterrent/system/window.d(123,58): Error: character 0x200b is not a valid token

Grepping around bindbc-opengl, I can not find any occurrence of GL_SHADING_LANGUAGE_VERSION​ (Khronos reference page). Should be defined in file gl20.d I think, as GLSL version is defined from OpenGL 2.0.

Nvidia extensions

Would be nice to have support for nvidia extension. Specifically the new ones such as NV_command_list, NV_mesh_shader, NV_shading_rate_image, etc.

Will attempt to make a fork of this with nvidia support, though I'll probably only write the specific extensions I'm interesting in.

Need a way to load specific symbols

In SPEW, context creation requires the ability to lookup specific symbols (supports compat since it gets messy cross platform).

Currently with bindbc-opengl the ability to load specific functions are hidden behind private.
In essence I need access to bindGLSymbol in the form of void* function(string).

Would this be possible or will I need to write up a custom loader as a backup?

Bindless Textures int64 support

In order to use bindless textures along with set of UBO's, I need to use uint64_t types inside glsl.
This requires either the GL_NV_gpu_shader5 or GL_ARB_gpu_shader_int64 extension, neither of which are in the list provided.

Should support for one be added before I can use this, or is there another way I'm unaware of?

Dynamic version loading

It would be cool to support dynamic version change, without having to specify that during build.

Support Wayland on Linux

Currently bindbc-opengl only loads OpenGL symbols from the X11 server, which means applications will crash on Wayland desktops.
Solution is to check the XDG_SESSION_TYPE environment variable on Linux to see whether it reports x11 or wayland, if wayland is the active session type. then both libgl and libegl should be loaded, with libegl providing GetProcAddress (eglGetProcAddress) and GetCurrentContext (eglGetCurrentContext) and libgl providing all the OpenGL functions.

v0.3.0 compile errors

Hello, trying to compile bindbc-opengl (0.3.0, win32, dmd 2.082.0) results in the following errors:

bindbc-opengl 0.3.0: building configuration "dynamic"...
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(214,11): Error: undefined identifier useARBFramebufferSRGB
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(283,11): Error: undefined identifier useARBPipelineStatisticsQuery
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(307,11): Error: undefined identifier useARBRobustnessIsolation
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(318,11): Error: undefined identifier useARBSampleShading
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(344,11): Error: undefined identifier useARBTextureCompressionBPTC
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(362,11): Error: undefined identifier useARBTextureCubeMapArray
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(383,11): Error: undefined identifier useARBTextureGather
C:\Users\Danol\AppData\Local\dub\packages\bindbc-opengl-0.3.0\bindbc-opengl\source\bindbc\opengl\bind\arb\arb_01.d(399,11): Error: undefined identifier useARBTransformFeedbackOverflowQuery

v0.2.0 works fine

Missing GL_ constants

I've stumbled across some GL_ constants nowhere to be found in bindbc-opengl:

// added in 1.5
enum GL_SRC1_ALPHA = 0x8589;

// added in 3.0
enum GL_VERTEX_ARRAY_BINDING = 0x85B5;

// added in 3.3
enum GL_RGB10_A2UI = 0x906F;

// added in 4.1
enum GL_RGB565 = 0x8D62;
enum GL_SHADER_BINARY_FORMATS = 0x8DF8;
enum GL_NUM_SHADER_BINARY_FORMATS = 0x8DF9;

http://www.opengl.org/registry/api/GL/glcorearb.h

I can simply make a PR adding these, but there might be more, and I wonder if there is an underlying reason. Were they simply overlooked? Was a different reference used for bindbc?

Update loader

It is currently giving an error when trying to use opengl and glfw.

just add both

dub add bindbc-glfw
dub add bindbc-opengl

and we've got an error

Unresolvable dependencies to package bindbc-loader:
  bindbc-glfw 0.10.0 depends on bindbc-loader ~>0.3.0
  bindbc-glfw 0.10.0 depends on bindbc-loader ~>0.3.0
  bindbc-opengl 0.12.0 depends on bindbc-loader ~>0.2.1

glGetInteger64v takes "__GLsync*" instead of uint (GLenum)

When I try to get the value of GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, the compiler complains I need to pass in a __GLsync* instead. I can cast to it & hope for the best but am unsure what __GLsync* even means.

GLint64 a;
glGetInteger64v(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &a);
a.writeln;

GL33 and GL_ARB fails to load GL_ARB_vertex_array_object

Hi!

I'm currently puzzled why defining GL33 and GL_ARB specifically fails to load glGenVertexArrays, part of OpenGL 3.0 (GL30) and GL_ARB_vertex_array_object, but other versions work.

Defining GL34+GL_ARB, GL32+GL_ARB, GL31+GL_ARB, and GL30+GL_ARB works, but not GL33+GL_ARB specifically. So I'm thinking if the loader has more things to tell.

I've skimmed the source and didn't see anything off. If I see something later on, I'd be willing to make a PR. Though, I absolutely don't need my project to be on GL33, so this isn't a high priority for me.

glxinfo(1) reports that my card does support GL_ARB_vertex_array_object.

Much appreciated in advance.

UPDATE: I'm an idiot for thinking that GL34 is a thing. Will try GL40 when I get home.


Setup:

Item Desc
DMD DMD64 D Compiler v2.098.1
DUB 1.27.0
bindbc-opengl 1.2.1
GL_RENDERER AMD Radeon RX 6700 XT (navy_flounder, LLVM 13.0.1, DRM 3.47, 5.19.0-76051900-generic)
GL_VERSION 4.6 (Compatibility Profile) Mesa 22.0.5

Source (last assert checks if function pointer is loaded):

version (OSX)
    enum SHADER_VERSION = "#version 150\n";
else
    enum SHADER_VERSION = "#version 300 es\n";

immutable const(GLchar)* vertex_source =
    SHADER_VERSION~
    "uniform mat4 ProjMtx;\n"~
    "in vec2 Position;\n"~
    "in vec2 TexCoord;\n"~
    "in vec4 Color;\n"~
    "out vec2 Frag_UV;\n"~
    "out vec4 Frag_Color;\n"~
    "void main() {\n"~
    "   Frag_UV = TexCoord;\n"~
    "   Frag_Color = Color;\n"~
    "   gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"~
    "}\n";
immutable const(GLchar)* fragment_source =
    SHADER_VERSION~
    "precision mediump float;\n"~
    "uniform sampler2D Texture;\n"~
    "in vec2 Frag_UV;\n"~
    "in vec4 Frag_Color;\n"~
    "out vec4 Out_Color;\n"~
    "void main() {\n"~
    "   Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"~
    "}\n";

struct platform_vertex
{
    float[2] position;
    float[2] tex; // uv
    ubyte[4] color;
}

__gshared GLuint glprogram;
__gshared GLuint vertex_shader;
__gshared GLuint fragment_shader;

__gshared GLint uniform_texture;
__gshared GLint uniform_projmatrix; // Projection matrix
__gshared GLint attrib_position;
__gshared GLint attrib_texcoord; // UV
__gshared GLint attrib_color;

__gshared GLuint vbo;
__gshared GLuint ebo;
__gshared GLuint vao;

void initiate_renderer()
{
    // OpenGL setup
    GLSupport glstatus = loadOpenGL;
    assert(glstatus, "Failed to load OpenGL");
    glprogram = glCreateProgram();
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_source, null);
    glShaderSource(fragment_shader, 1, &fragment_source, null);
    glCompileShader(vertex_shader);
    glCompileShader(fragment_shader);
    
    GLint status = void;
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
    assert(status, "Compiling vertex shader failed");
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
    assert(status, "Compiling fragment shader failed");
    
    glAttachShader(glprogram, vertex_shader);
    glAttachShader(glprogram, fragment_shader);
    glLinkProgram(glprogram);
    
    glGetProgramiv(glprogram, GL_LINK_STATUS, &status);
    assert(status, "Linking GL program failed");
    
    uniform_texture    = glGetUniformLocation(glprogram, "Texture");
    uniform_projmatrix = glGetUniformLocation(glprogram, "ProjMtx");
    attrib_position    = glGetAttribLocation(glprogram,  "Position");
    attrib_texcoord    = glGetAttribLocation(glprogram,  "TexCoord");
    attrib_color       = glGetAttribLocation(glprogram,  "Color");
    
    // Buffer setup
    {
        glGenBuffers(1, &vbo);
        glGenBuffers(1, &ebo);
        assert(glGenVertexArrays, "glGenVertexArrays is null, is ARB loaded?");
        glGenVertexArrays(1, &vao);
        
        glBindVertexArray(vao);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        
        glEnableVertexAttribArray(attrib_position);
        glEnableVertexAttribArray(attrib_texcoord);
        glEnableVertexAttribArray(attrib_color);
        
        GLsizei vs = platform_vertex.sizeof;
        size_t  vp = platform_vertex.position.offsetof;
        size_t  vt = platform_vertex.tex.offsetof;
        size_t  vc = platform_vertex.color.offsetof;
        
        glVertexAttribPointer(cast(GLuint)attrib_position, 2, GL_FLOAT,         GL_FALSE, vs, cast(void*)vp);
        glVertexAttribPointer(cast(GLuint)attrib_texcoord, 2, GL_FLOAT,         GL_FALSE, vs, cast(void*)vt);
        glVertexAttribPointer(cast(GLuint)attrib_color,    4, GL_UNSIGNED_BYTE, GL_TRUE,  vs, cast(void*)vc);
    }
    
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

Only OpenGL 1.1 can be loaded on intel intergrated graphics

It appears this bindings fail loading anything over OpenGL 1.1 on Intel Intergrated Graphics.

import bindbc.sdl;
import bindbc.opengl;
import std.stdio;

/**
    Opens Window
*/
void main() {
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GLcontextFlag.SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    window = SDL_CreateWindow("Test App", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 1024, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    
    gl_context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, gl_context);
    SDL_GL_SetSwapInterval(1);

    // Load GL 3
    GLSupport support = loadOpenGL();
    switch(support) {
        case GLSupport.noLibrary:
            throw new Exception("OpenGL library could not be loaded!");

        case GLSupport.noContext:
            throw new Exception("No valid OpenGL context was found!");

        default: break;
    }

    import std.string : fromStringz;
    writefln("GLInfo:\n\t%s\n\t%s\n\t%s\n\tgls=%s",
        glGetString(GL_VERSION).fromStringz,
        glGetString(GL_VENDOR).fromStringz,
        glGetString(GL_RENDERER).fromStringz,
        support
    );
    
    // attempting to access glCreateShader causes the app to crash due to null pointer reference.
}

static this() {
    loadSDL();

    SDL_Init(SDL_INIT_EVERYTHING);
}

Output on some devices using Intel iGPUS:

GLInfo:
        3.2.0 - Build 27.20.100.8681
        Intel
        Intel(R) UHD Graphics 630
        gls=gl11
GLInfo:
        3.2.0 - Build 10.18.10.5161
        Intel
        Intel(R) HD Graphics 4000
        gls=gl11

While the GL_VERSION string says GL 3.2 is supported, the support returned by loadOpenGL only returns gl11

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.