Some notes on OpenGL
FBO + Render-To-Texture + Depth testing
When you use and FBO to render the scene into a texture and then
another pass to apply some effect, you need to make sure that you're
not using the same depth values (gl_Position.z) because else the second
pass will not be rendered when depth testing is enabled. A simple fix for
this (but this might be a bit heavy if you do it do often) is turning on/off
depth testing using glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST)
Texture formats
When you use glTexImage2D() you specify the internalFormat, format
and the type of your texture data. Choosing the correct values is important
when you're streaming data to the gpu as the driver might want to rearrange
the pixel data you provide which you really don't want.
internalFormat:
number of color components in the texture (GL_R, GL_RG, GL_RGB, GL_RGBA).format:
format of the pixel data triggers swizzling! (GL_BGRA, GL_YCBCR_422_APPLE)type:
data type of the pixel data (GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT)
Apple advices to use these formats and types
Format With type -------------------------------------------------------- GL_BGRA | GL_UNSIGNED_INT_8_8_8_8_REV GL_BGRA | GL_UNSIGNED_SHORT_1_5_5_5_REV GL_YCBCR_422_APPLE | GL_UNSIGNED_SHORT_8_8_REV_APPLE --------------------------------------------------------
YUV420P (I420p) shader
Snippet to remember for video decoding on gpu
static const char* DEBUG_VS = "" "#version 150\n" "const vec2 verts[4] = vec2[] (" " vec2(-1.0, 1.0), " " vec2(-1.0, -1.0), " " vec2(1.0, 1.0), " " vec2(1.0, -1.0) " ");" "const vec2 texcoords[4] = vec2[] (" " 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() {" " gl_Position = vec4(verts[gl_VertexID], 0.0, 1.0);" " v_texcoord = texcoords[gl_VertexID];" "}" ; static const char* DEBUG_FS = "" "#version 150\n" "uniform sampler2D y_tex;" "uniform sampler2D u_tex;" "uniform sampler2D v_tex;" "in vec2 v_texcoord;" "out vec4 fragcolor;" "const vec3 R_cf = vec3(1.164383, 0.000000, 1.596027);" "const vec3 G_cf = vec3(1.164383, -0.391762, -0.812968);" "const vec3 B_cf = vec3(1.164383, 2.017232, 0.000000);" "const vec3 offset = vec3(-0.0625, -0.5, -0.5);" "void main() {" " float y = texture(y_tex, v_texcoord).r;" " float u = texture(u_tex, v_texcoord).r;" " float v = texture(v_tex, v_texcoord).r;" " vec3 yuv = vec3(y,u,v);" " yuv += offset;" " fragcolor = vec4(0.0, 0.0, 0.0, 1.0);" " fragcolor.r = dot(yuv, R_cf);" " fragcolor.g = dot(yuv, G_cf);" " fragcolor.b = dot(yuv, B_cf);" "}";
FBOs with different sized texture attachments
With the framebuffer feature it's possible to render offscreen into what is called color attachments. Color attachments can be textures or render buffers for example.
Although the specification states that you can use different sized
color attachments, which is true, you need to be aware that the
effective FBO size, is the size of the intersection of the attachments
dimensions... aka the smallest dimension. This is important when you
e.g. need to use glBlitFramebuffer as it will only blit the smallest
area.
See this comment "Notice that there is no restriction based on size. The effective size of the FBO is the intersection of all of the sizes of the bound images (ie: the smallest in each dimension)." on the openGL wiki
Attribute less rendering
By using the build in gl_VertexID variable in your vertex
shader and defining a array for vertex positions and texture
coordinates you can draw basic triangle strips withouth using
a VBO. You still need to create a vertex array object but you
don't need to set any attributes or pointers. See the shader
below which uses this attribute less rendering technique.
static const char* FULLSCREEN_VS = "" "#version 150\n" "const vec2 verts[4] = vec2[] (" " vec2(-1.0, 1.0), " " vec2(-1.0, -1.0), " " vec2(1.0, 1.0), " " vec2(1.0, -1.0)" ");" "const vec2 tex[4] = vec2[] (" " vec2(0.0, 1.0), " " vec2(0.0, 0.0), " " vec2(1.0, 1.0), " " vec2(1.0, 0.0)" ");" "out vec2 v_tex; " "void main() {" " gl_Position = vec4(verts[gl_VertexID], 0.0, 1.0);" " v_tex = tex[gl_VertexID];" "}" ""; static const char* TEX_FS = "" "#version 150\n" "uniform sampler2D u_tex;" "in vec2 v_tex;" "out vec4 fragcolor;" "void main() {" " vec4 tc = texture(u_tex, v_tex);" " fragcolor.rgb = tc.rgb;" " fragcolor.a = 1.0f;" "}" "";
By using the above shader and by taking care of your model matrix in a smart way you can draw textures using an orthographic matrix in such a way that the texture can be drawn at any location, size and rotation. In the following code I'm setting up a ortho matrix. See the updated attribute less shader below too.
bool Graphics::setup() // tex_pm is a Mat4 and is the projection matrix glGenVertexArrays(1, &tex_vao); tex_pm.ortho(0.0f, settings.win_w, settings.win_h, 0.0f, 0.0f, 100.0f); tex_vs = rx_create_shader(GL_VERTEX_SHADER, TEX_VS); tex_fs = rx_create_shader(GL_FRAGMENT_SHADER, TEX_FS); tex_prog = rx_create_program(tex_vs, tex_fs); glLinkProgram(tex_prog); rx_print_shader_link_info(tex_prog); glUseProgram(tex_prog); glUniformMatrix4fv(glGetUniformLocation(tex_prog, "u_pm"), 1, GL_FALSE, tex_pm.ptr()); return true } void Graphics::drawTexture(GLuint tex, float x, float y, float w, float h) { glUseProgram(tex_prog); glActiveTexture(GL_TEXTURE0); glBindVertexArray(tex_vao); float hw = w * 0.5; float hh = h * 0.5; // use the following model matrix to draw the texture at the given (x,y) and (width,height) // here I also rotate (around the center) tex_mm.identity(); tex_mm.translate(x + hw, y + hh, 0.0f); tex_mm.rotate(45.0f * DEG_TO_RAD, 0.0f, 0.0f, 1.0f); tex_mm.scale(hw, hh, 1.0f); glUniformMatrix4fv(glGetUniformLocation(tex_prog, "u_mm"), 1, GL_FALSE, tex_mm.ptr()); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }
And the (updated) shader:
static const char* TEX_VS = "" "#version 150\n" "uniform mat4 u_pm;" "uniform mat4 u_mm;" "const vec2 verts[4] = vec2[] (" " vec2(-1.0, 1.0), " " vec2(-1.0, -1.0), " " vec2(1.0, 1.0), " " vec2(1.0, -1.0)" ");" "const vec2 tex[4] = vec2[] (" " vec2(0.0, 1.0), " " vec2(0.0, 0.0), " " vec2(1.0, 1.0), " " vec2(1.0, 0.0)" ");" "out vec2 v_tex; " "void main() {" " vec4 vert = vec4(verts[gl_VertexID], 0.0, 1.0);" " gl_Position = vert; " " gl_Position = u_pm * vert;" " gl_Position = u_pm * u_mm * vert;" " v_tex = tex[gl_VertexID];" "}" ""; static const char* TEX_FS = "" "#version 150\n" "in vec2 v_tex;" "out vec4 fragcolor;" "void main() {" " fragcolor = vec4(1.0, 0.0, 0.0, 1.0);" "}" "";
NAT Types
Building Cabinets
Compiling GStreamer from source on Windows
Debugging CMake Issues
Dual Boot Arch Linux and Windows 10
Mindset Updated Edition, Carol S. Dweck (Book Notes)
How to setup a self-hosted Unifi NVR with Arch Linux
Blender 2.8 How to use Transparent Textures
Compiling FFmpeg with X264 on Windows 10 using MSVC
Blender 2.8 OpenGL Buffer Exporter
Blender 2.8 Baking lightmaps
Blender 2.8 Tips and Tricks
Setting up a Bluetooth Headset on Arch Linux
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
Basic Shading With OpenGL
Open Source Libraries For Creative Coding
Bouncing particle effect
OpenGL Instanced Rendering
Mapping a texture on a disc
Download HTML page using CURL
Height Field Simulation on GPU
OpenCV
Some notes on 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
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