https://github.com/pyzh/triangle
https://github.com/pyzh/triangle
Last synced: over 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/pyzh/triangle
- Owner: pyzh
- Created: 2019-01-07T12:08:34.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-01-19T09:48:14.000Z (over 8 years ago)
- Last Synced: 2025-01-22T01:36:41.638Z (over 1 year ago)
- Language: C++
- Size: 17.6 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
Awesome Lists containing this project
README
========
triangle
========
.. image:: https://travis-ci.org/bhuztez/triangle.svg?branch=master
:target: https://travis-ci.org/bhuztez/triangle
.. image:: https://codenvy.io/factory/resources/codenvy-contribute.svg
:target: https://codenvy.io/f?url=https://github.com/bhuztez/triangle
There are many good OpenGL tutorials out there. They have good
explanation on how OpenGL works. However, most of them treat OpenGL as
a black box. It would be better to implement a small part of OpenGL to
see how things fit together.
The biggest challenge of emulating GLSL in C++ is shader linking. This
has been made possible by stateful metaprogramming. Like we did in
implementing precise garbage collector, we also record names of all
uniform, attribute, varying variables, so that when linking, we can
check if variables of same name have same type.
Another problem is that vertex and fragment shaders will be run many
times, and at each run, attribute and varying variables point to
different locations. To make it as close as possible to GLSL, and
avoid much boilerplate, there variables are declared as union. For
example, :code:`gl_Position`.
.. code:: c++
union {
vec4& gl_Position;
vec4* _ptr_gl_Position;
}
Let's see a complete example.
the vertex shader
.. code:: c++
template
struct Vertex {
VERTEX_SHADER(Vertex, T);
UNIFORM(perspective, mat4);
ATTRIBUTE(position, vec3);
ATTRIBUTE(aColor, vec3);
VARYING(vColor, vec3);
void
main() {
gl_Position = perspective * vec4(position, 1.0);
vColor = aColor;
}
};
the fragment shader
.. code:: c++
template
struct Fragment {
FRAGMENT_SHADER(Fragment, T);
VARYING(vColor, vec3);
void
main() {
gl_FragColor = vec4(vColor, 1.0);
}
};
link and then create program of 3 vertices
.. code:: c++
using Program = ::gl::Link;
using T = typename Program::Float;
using vec3 = typename Program::vec3;
Program prog(3);
specify locations of variables.
.. code:: c++
auto p = perspective(::gl::sl::radians(90.0), T(width)/T(height), 0.1, 100.0);
vec3 position[] = {
{-0.5, -0.5, -1.0},
{ 0.5, -0.5, -1.0},
{ 0.5, 0.5, -5.0}
};
vec3 color[] = {
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}
};
prog.uniform.set("perspective"_s, &p);
prog.attribute.set("position"_s, position);
prog.attribute.set("aColor"_s, color);
draw
.. code:: c++
::gl::Context(width, height, buffer).draw(prog, ::gl::triangles);