- Compiling x264 on Windows with MSVC
- C/C++ Snippets
- Reading Chunks from a Buffer
- Handy Bash Commands
- Building a zero copy parser
- Kalman Filter
- Saving pixel data using libpng
- Compile Apache, PHP and MySQL on Mac 10.10
- Fast Pixel Transfers with Pixel Buffer Objects
- High Resolution Timer function in C/C++
- Rendering text with Pango, Cairo and Freetype
- Fast OpenGL blur shader
- Spherical Environment Mapping with OpenGL
- Using OpenSSL with memory BIOs
- Attributeless Vertex Shader with OpenGL
- Circular Image Selector
- Decoding H264 and YUV420P playback
- Fast Fourier Transform
- OpenGL Rim Shader
- Rendering The Depth Buffer
- Delaunay Triangulation
- RapidXML
- Git Snippets
- Cross Platform OpenGL
- Basic Shading With OpenGL
- Open Source Libraries For Creative Coding
- Bouncing particle effect
- OpenGL Instanced Rendering
- A Collection Of Interesting Articles
- Mapping a texture on a disc
- Download HTML page using CURL
- Height Field Simulation on GPU
- Scholar
- OpenCV
- openGL
- Math
- Gists to remember
- Reverse SSH
- Working Set
- Consumer + Producer model with libuv
- Parsing binary data
- C++ file operation snippets
- Importance of blur with image gradients
- Real-time oil painting with openGL
- Basic CUDA example
- x264 encoder
- Generative helix with openGL
- Mini test with vector field
- Protractor gesture recognizer
- Hair simulation
- Some glitch screenshots
- Working on video installation
- Generative meshes
- Converting video/audio using avconv
- Auto start terminal app on mac
- Export blender object to simple file format
Attributeless Vertex Shader with OpenGL
When doing fullscreen shader passes with openGL I often use a simple technique
called "Attribute-less rendering" as described by Robert on his blog.
In short this means you store the vertices that you want to render
in your vertex shader using a const vec2 array and use the gl_VertexID
variable to access the correct element from this array. Great thing about
using this technique is that you don't need to setup an VBO or setup the
offsets for a Vertex Array Object (VAO).
Recently I want to use this technique to draw simple 2D textures for my Video Capture library. Though I had to find a way to specify the (x,y) offsets and the dimensions where I wanted to draw the texture.
To solve this, I added a vec4 u_pos uniform that holds the offsets in the (x,y)
elements and the scale in the (z,w) elements. The values of this u_pos uniform
are percentages for of the current viewport dimensions.
Lets say the viewport is 800 x 600. I store a inv_win_w and inv_win_h that I use
to convert the x/y/w/h values to percentages:
void CaptureGL::resize(int winW, int winH) { inv_win_w = 1.0 / winW; inv_win_h = 1.0 / winH; }
Then whenever you want to draw someting in 2D at a specific location and dimension,
I set the vec4 u_pos uniform values like:
void CaptureGL::draw(int x, int y, int w, int h) { GLint u_pos = glGetUniformLocation(prog, "u_pos"); // NOTE: do this somewhere in your constructor and keep a member glUniform4f(u_pos, x * inv_win_w, y * inv_win_h, w * inv_win_w, h * inv_win_h ); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }
The shaders that backs up this technique is pasted below. We first offset the
vertex position using the u_pos.x and u_pos.y after changing the values to
Normalized Device Context (NDC) ranges (-1, 1). Then we apply the scaled vertex
position.
/* u_pos.x = X position in percentage of viewport 0-1. 0% means -1.0 u_pos.y = Y position in percentage of viewport 0-1. 0% means -1.0 u_pos.z = WIDTH scale in percentage of viewport. u_pos.w = HEIGHT scale in percentage of viewport. */ static const char* CAPTURE_GL_VS = "" "#version 330\n" "uniform vec4 u_pos; " "" "const vec2 pos[] = vec2[4](" " vec2(0.0, 1.0), " " vec2(0.0, 0.0), " " vec2(1.0, 1.0), " " vec2(1.0, 0.0) " ");" "" " const vec2[] tex = vec2[4]( " " vec2(0.0, 0.0), " " vec2(0.0, 1.0), " " vec2(1.0, 0.0), " " vec2(1.0, 1.0) " ");" "" "out vec2 v_texcoord; " "" "void main() { " " vec2 p = pos[gl_VertexID]; " " vec2 offset = vec2(u_pos.x * 2.0 - 1.0, u_pos.y * 2.0 - 1.0); " " vec2 scale = vec2(u_pos.z * p.x * 2.0, u_pos.w * p.y * 2.0); " " gl_Position = vec4(offset.x + scale.x, " " offset.y + scale.y, " " 0.0, 1.0);" " v_texcoord = tex[gl_VertexID];" "}" "";