diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index 39b2883c..b964b557 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,4 +1,8 @@
[
+ [
+ "2024-07-28",
+ "New documentation: OpenGL"
+ ],
[
"2024-06-12",
"New documentations: Next.js, click"
diff --git a/docs/file-scrapers.md b/docs/file-scrapers.md
index 403c8333..9d51e4f4 100644
--- a/docs/file-scrapers.md
+++ b/docs/file-scrapers.md
@@ -161,6 +161,19 @@ curl https://v2.ocaml.org/releases/$VERSION/ocaml-$VERSION-refman-html.tar.gz |
tar xz --transform 's/htmlman/ocaml/' --directory docs/
```
+## Opengl
+
+Clone https://github.com/KhronosGroup/OpenGL-Refpages.git
+
+```sh
+DEVDOCS_ROOT=/path/to/devdocs
+git clone https://github.com/KhronosGroup/OpenGL-Refpages.git
+mkdir $DEVDOCS_ROOT/docs/opengl~4
+mkdir $DEVDOCS_ROOT/docs/opengl~2.1
+cp -r OpenGL-Refpages/gl4/html/* "$DEVDOCS_ROOT/docs/opengl~4"
+cp -r OpenGL-Refpages/gl2.1/xhtml/* "$DEVDOCS_ROOT/docs/opengl~2.1"
+```
+
## OpenJDK
Search 'Openjdk' in https://www.debian.org/distrib/packages, find the `openjdk-$VERSION-doc` package,
download it, extract it with `dpkg -x $PACKAGE ./` and move `./usr/share/doc/openjdk-16-jre-headless/api/`
diff --git a/lib/docs/filters/opengl/clean_html.rb b/lib/docs/filters/opengl/clean_html.rb
new file mode 100644
index 00000000..60c870bf
--- /dev/null
+++ b/lib/docs/filters/opengl/clean_html.rb
@@ -0,0 +1,32 @@
+module Docs
+ class Opengl
+ class CleanHtmlFilter < Filter
+ def call
+ return '
OpenGL
' if root_page?
+
+ @doc = at_css('.refentry') if at_css('.refentry')
+
+ # Remove table from function definitions
+ css('.funcprototype-table').each do |node|
+ node.css('td').each do |data|
+ data.replace(data.children)
+ end
+ node.css('tr').each do |row|
+ row.replace(row.children)
+ end
+ node.wrap('')
+ node.parent['id'] = node.css('.fsfunc').text
+ node.replace(node.children)
+ end
+
+ css('a').remove_attribute('target')
+
+ # needed for scraper's options[:attribution]
+ copyright = at_css('h2:contains("Copyright")')
+ copyright.parent['style'] = 'display: none' if copyright
+
+ doc
+ end
+ end
+ end
+ end
diff --git a/lib/docs/filters/opengl/entries.rb b/lib/docs/filters/opengl/entries.rb
new file mode 100644
index 00000000..32ae2e3c
--- /dev/null
+++ b/lib/docs/filters/opengl/entries.rb
@@ -0,0 +1,25 @@
+module Docs
+ class Opengl
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ slug.chomp('.xhtml').chomp('.xml')
+ end
+
+ # gl4 also has documentation of GLSL, this string is present under Version Support
+ def get_type
+ return 'GLSL' if html.include?('OpenGL Shading Language Version')
+ 'OpenGL'
+ end
+
+ # functions like glUniform1f, glUniform2f, glUniform... have the same documentation
+ def additional_entries
+ entries = []
+ css('.fsfunc').each do |function|
+ next if function.text == name
+ entries << [ function.text, function.text ]
+ end
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/opengl.rb b/lib/docs/scrapers/opengl.rb
new file mode 100644
index 00000000..e860625f
--- /dev/null
+++ b/lib/docs/scrapers/opengl.rb
@@ -0,0 +1,31 @@
+module Docs
+ class Opengl < FileScraper
+ self.type = 'simple'
+ self.name = 'OpenGL'
+ self.root_path = 'index.php'
+ self.links = {
+ home: 'https://registry.khronos.org/OpenGL-Refpages/'
+ }
+ html_filters.push 'opengl/entries', 'opengl/clean_html'
+
+ # indexflat.php is a copy of index.php
+ options[:skip] = %w(indexflat.php)
+
+ options[:attribution] = ->(filter) {
+ # copyright is the last section in these pages
+ return filter.css('h2:contains("Copyright") ~ p').inner_text
+ }
+
+ version '4' do
+ self.root_path = 'index.php'
+ self.release = '4'
+ self.base_url = "https://registry.khronos.org/OpenGL-Refpages/gl#{self.version}/"
+ end
+
+ version '2.1' do
+ self.root_path = 'index.html'
+ self.release = '2.1'
+ self.base_url = "https://registry.khronos.org/OpenGL-Refpages/gl#{self.version}/"
+ end
+ end
+end
diff --git a/public/icons/docs/opengl/16.png b/public/icons/docs/opengl/16.png
new file mode 100644
index 00000000..92a58e08
Binary files /dev/null and b/public/icons/docs/opengl/16.png differ
diff --git a/public/icons/docs/opengl/16@2x.png b/public/icons/docs/opengl/16@2x.png
new file mode 100644
index 00000000..31143bb8
Binary files /dev/null and b/public/icons/docs/opengl/16@2x.png differ
diff --git a/public/icons/docs/opengl/SOURCE b/public/icons/docs/opengl/SOURCE
new file mode 100644
index 00000000..bb57df17
--- /dev/null
+++ b/public/icons/docs/opengl/SOURCE
@@ -0,0 +1 @@
+https://www.khronos.org/legal/trademarks/