百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
P

PortableGL

> 包管理
开源

一个基于干净 C 语言的 OpenGL 3.x 实现

1.3K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

一个基于干净 C 语言的 OpenGL 3.x 实现

PortableGL

Shader Workshop Announcement

If you'd like to support PortableGL development or are interested in shader art (or ideally both) check it out here


"Because of the nature of Moore's law, anything that an extremely clever graphics programmer can do at one point can be replicated by a merely competent programmer some number of years later." -John Carmack

In a nutshell, PortableGL is an implementation of OpenGL 3.x core (mostly; see GL Version) in clean C99 as a single header library (in the style of the stb libraries). This means it compiles cleanly as C++ and can be easily added to almost any codebase.

It can theoretically be used with anything that takes a 32 or 16 bit framebuffer/texture as input in any format. (including just writing images to disk manually or using something like stb_image_write). That should mean it supports almost everything, barring performance issues.

Almost all the demos use SDL2 except the programs in the backends directory which show how to use it with other backends (currently x11/xlib and win32).

It supports arbitrary 32- and 16-bit color buffer formats (selected at compile time) with several common ones ready to use out of the box. See the documentation for more details.

Its goals are, roughly in order of priority,

  1. Portability
  2. Matching the API within reason, at the least matching features/abilities
  3. Ease of Use
  4. Straightforward code
  5. Speed

Obviously there are trade-offs between several of those. An example where 4 trumps 2 (and arguably 3) is with shaders. Rather than write or include a GLSL parser and have a built in compiler or interpreter, shaders are special C/C++ functions that match a specific prototype. Uniforms are another example where 3 and 4 beat 2 because it made no sense to match the API because we can do things so much simpler by passing a pointer to a user defined struct (see the examples).

Download

Get the source from Github.

You can also install it via Homebrew.

Gallery

The last is a PortableGL port of Michael Fogleman's Craft.

Directory Structure

  • demos: Unpolished open ended programs demonstrating a wide variety of features
  • examples: More polished examples in C and C++, some graduating from demos
    • original: Original custom examples, C++ programs use rsw_math rather than glm
    • classic: Ports of classic OpenGL programs/demos, currently just gears
    • webgl_lessons: Ports of lessons from learningwebgl.com based off my ports to OpenGL 3.3 here
  • backends: "hello triangle" using backends other than SDL2 (win32 and xlib currently)
  • glcommon: Collection of helper libraries I use for graphics programming
  • media: Parent directory for external resources
    • models: Models in my own simplified text format (created with demos/assimp_convert)
    • screenshots: screenshots of demos and external programs
    • textures: All textures used in any program in the repo
  • src: Contains the actual source files of portablegl.h which are amalgamated with generate_gl_h.py
  • testing: Contains a more formal regression and performance test suite
    • expected_output: The expected output frames for the regression tests (run_tests)
    • test_output: The output of the regression tests (see Building section)
  • portablegl.h : Current dev version of PortableGL

While I try not to introduce bugs, they do occasionally slip in, as well as (rarely) breaking changes. At some point I'll move to more frequent point releases for fixes and non-breaking changes and be more consistent with semantic versioning.

Documentation

There is the documentation including a minimal program in the comments at the top of the file but there is currently no formal documentation.

The best way to learn is to look at the examples (and demos) and comparing them to equivalent OpenGL 3.3+ programs.

My ports of the learnopengl.com tutorial code here are the best resource, combining his tutorials explaining the OpenGL aspects and my comments in the ported code explaining PortableGL's differences and limitations (at least in the first time they appear).

For the original examples and demos you can compare with my equivalent programs in opengl_reference).

Honestly, the official OpenGL docs and reference pages are good for 90-95% of it as far as basic usage:

4.6 Core reference 4.5 comprehensive reference tutorials and guides

Building

There are no dependencies for PortableGL itself, other than a compliant C99/C++ compiler.

If you just want to do a quick test that it compiles and runs:

cd testing
make run_tests
...
./run_tests
All tests passed

See the testing README for more on the formal testing.

See the examples README which describes how to get SDL2 if you don't already have it and how to use make to build them.

To sum up, the only thing that is guaranteed to build and run anywhere out of the box with no extra effort on your part are the regression tests since they don't depend on anything except a compliant C++ compiler.

Modifying

portablegl.h is generated in the src subdirectory with the python script generate_gl_h.py. You can see how it's put together and either modify the script to leave out or add files, or actually edit any of the code. Make sure if you add any actual gl functions that you add them to gl_function_list.c as it's used in the script for optionally wrapping all of them in a macro to allow user defined prefix/namespacing.

Additionally, there is a growing set of more formal tests in testing, one set of regression/feature tests, and one for performance. If you make any changes to core algorithms or data structures, you should definitely run those and make sure nothing broke or got drastically slower. The examples and demos can also function as performance tests, so if one of those would be especially affected by a change, it might be worth comparing its before/after performance too.

On the other hand, if you're adding a function or feature that doesn't really affect anything else, it might be worth adding your own test if applicable. You can see how they work from looking at the code, but I'll add more details and documentation about the testing system later when it's more mature.

Bindings/Ports

portablegl-rs is a Rust port created with the assistance of AI (Anthropic's Claude Opus 4.6).

pgl is a Go port using CXGO, and hand translating the individual examples/demos.

Sponsors

You can help support PortableGL development by becoming a Github Sponsor or via one of the other methods shown/linked to in the Sponsor popup.

Past Aeronix Sep-Oct 2023

LICENSE

PortableGL is licensed under the MIT License (MIT)

The code used for clipping is copyright (c) Fabrice Bellard from TinyGL also under the MIT License, see LICENSE.

History

PortableGL started as a very simple wireframe software renderer based on a tutorial in summer 2011. I kept playing with it, adding minor features over the next year, until in early 2013 I decided I should turn it into a software implementation of OpenGL. This would save me a huge amount of time and energy on API design since I'd just be implementing an existing good API (though some disagree) and also make the project more useful both to me and potentially others. Also, at the time Mesa3D was still years away from full 3.x support, not that I'm really competing, and the fact that there was no finished implementation was a little motivating. I made a lot of progress that year and had a few bursts here and there since, but once I got it mostly working, I was less motivated and when I did work on it I spent my time on creating new demos/examples and tweaking or fixing minor things. I could have released an MVP back in 2014 at the earliest but late 2016 would have been the best compromise. Anyway, after several thousand hours spread out over more than 10 years, it is as you see it today. Software is never finished, and I'll be the first to admit PortableGL could use more polish.

Why

Aside from the fact that I just wrote it for fun and because I thought it was cool (maybe others will too), I can think of a few semi-practical purposes.

Educational

I took a 400 level 3D Graphics course in college in fall 2010 months after OpenGL 3.3/4.0 was released. It was taught based on the original Red Book using OpenGL 1.1. Fortunately, the professor let me use OpenGL 3.3 as long as I met the assignment requirements. Sadly, college graphics professors still teach 1.x and 2.x OpenGL today in 2022 more commonly than 3.x/4.x (or Vulkan). A few are using WebGL 2.0 which I kind of consider 1 step forward, 2 steps back.

While Vulkan is the newest thing (already 5 years old time flies), it really is overkill for learning 3D graphics. There is rarely anything that students make in your standard intro to 3D graphics that remotely stresses the performance of any laptop built in the last decade plus. Using modern OpenGL (ie 3.3+ core profile) to introduce all the standard concepts, vertices, triangles, textures, shaders, fragments/pixels, the transformation pipeline etc. first is much better than trying to teach them Vulkan and graphics at the same time, and obviously better than teaching OpenGL API's that are decades old.

PortableGL could be a very convenient base for such a class. It's easy to walk through the code and see the pipeline and how all the steps flow together. For more advanced classes or graduate students in a shared class, modifying PortableGL in some way would be a good project. It could be some optimization or algorithm, maybe a new feature. Theoretically it could be used as starter code for actual research into new graphics algorithms or techniques because it's such a convenient small foundation to change and share, vs trying to modify a project the size and complexity of Mesa3D or create a software renderer from scratch.

Special Cases

It's hard to imagine any hardware today that has a CPU capable of running software rendered 3D graphics at any respectable speed (especially with full IEEE floating point) that doesn't also have some kind of dedicated GPU. The GPU might only support OpenGL 2.0 give or take but for performance it'd be better to stick to whatever the hardware supported than use PortableGL. However, theoretically, there could be some platform somewhere where the CPU is relatively powerful that doesn't have a GPU. Maybe some of the current and future RISC SoC's for example? In such a case PortableGL might be a useful alternative to Mesa3D or similar.

Another special case is hobby OS's. The hardware they run on might have a GPU but it migh

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

C3d3d-graphicscomputer-graphicsgraphics

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类包管理
定价开源

> 相关工具

N
npm
Node.js 默认包管理器
P
pnpm
高效节省磁盘的 Node 包管理器
I
is-gif
Check if a Buffer/Uint8Array is a GIF image