Skip to content

Commit 127bc79

Browse files
committed
Add OpenGL Troubleshooting steps/hints
1 parent 3b59a30 commit 127bc79

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Loading
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: 'My Screen is Black'
3+
slug: 'my-screen-is-black'
4+
description: 'This shall be a little guide to help you troubleshoot graphics problems. Focussing mainly on OpenGL.'
5+
date: '2024-11-01'
6+
authors: ['deccer']
7+
tags: ['opengl', 'troubleshoot', 'guide', 'article', 'debug']
8+
image: 'https://raw.githubusercontent.com/graphicsprogramming/blog/main/blog/2024/2024-11-01-my-screen-is-black/arrested-for-opengl-crimes-full.png'
9+
---
10+
11+
![](arrested-for-opengl-crimes-full.png)
12+
13+
<!-- truncate -->
14+
15+
Those were my findings over the months and years of exposing myself to OpenGL. I hope it helps anyone.
16+
17+
### First Things To Do
18+
19+
Hook up [RenderDoc](https://renderdoc.org). If you have not read its getting-started, read it before anything else.
20+
There is also a plugin available "Where is my drawcall" hook it up by following the instructions on RenderDoc's site.
21+
22+
Setup `glDebugMessageCallback` see [here](https://deccer.github.io/OpenGL-Getting-Started/02-debugging/02-debug-callback/) for example code.
23+
24+
If you use `glGetError` with or without macros like `GLCALL` or `GLCHECK` or rolled your own, get rid of it. `glDebugMessageCallback` will replace those. There is a high chance that you used it incorrectly anyway because you copy pasted it from some questionable source.
25+
26+
Make sure you check that shader compilation _and_ linking was successful. See `glGetShaderiv` & `glGetProgramiv` on compile and link status.
27+
28+
### You are on a Mac
29+
30+
Seriously port your engine to `metal`, or `webgpu` at least. There is no support for `KHR_debug` and you cannot use anything > gl 4.1 is enough reason
31+
32+
You are getting `UNSUPPORTED (log once): POSSIBLE ISSUE: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable`. You need to call glGenerateMipmap(GL_TEXTURE_2D) after glTexImage2D() or set max level to 0 if you dont need/want mips.
33+
34+
### RenderDoc is crashing when trying to run your application
35+
36+
This is most likely **not** RenderDoc's fault, but yours. Something in your code is fishy and RenderDoc doesnt like it. Use a debugger/code-sanitizer to figure out
37+
what is going on in your application. Most likely some problem around memory allocation/freeing/UB related thing.
38+
39+
Another reason why RenderDoc is crashing is that it doesnt like certain extensions you might be using in your code. RenderDoc used to tell you usually and not just
40+
crash, but that behaviour has changed since 1.36 or so. I don't know why. I have not bothered asking baldur yet. But what you can do is check your code for
41+
things involving bindless textures, and bindless buffers. Stuff like `glMakeTextureResidentARB`, `glProgramUniform...64NV`, `glGetTextureHandleARB`. RenderDoc also does
42+
not support legacy OpenGL. Make sure you arent using those either `glVertexXy`, `glNormalXy` etc. To debug old school stuff, use `apitrace` or nVidia's NSight Graphics.
43+
Older versions of `gEDebugger` or `CodeXL` might work too.
44+
45+
### You use GLAD but it is giving you a hard time about symbols not found and multiple definitions or the likes
46+
47+
It is most likely that the headers you are using are just outdated. Regenerate the header on dav1d's site. Or check your build system that it is
48+
pulling a recent version of glad.
49+
50+
### Debug Callback Says...
51+
52+
- `GL_INVALID_OPERATION error generated. Array object is not active.`:
53+
You didn't bind a VAO. Core Context OpenGL requires a VAO bound at all times. Bind one.
54+
55+
### Shader Compiler Log Says...
56+
57+
- `function "main" is already defined`
58+
You probably compile your fragment shader as vertex shader or other way around
59+
60+
### You are unable to figure out if an extension is supported
61+
62+
`GL_NV_conservative_raster` for example despite calling `glGetString(GL_EXTENSIONS)` and all that.
63+
You either need to query extensions with a forward compatible context or you switch to query `GL_NUM_EXTENSIONS` first and
64+
then iterate over all of them with `glGetStringi` and then check if the extension is part of that list. The latter requires a core OpenGL context.
65+
66+
### Exception when calling glDrawElements - aka "0xC0000005"
67+
68+
You most likely have no indexbuffer is bound. Or it is not associated to/with the current VAO.
69+
70+
### Exception when calling glDrawArrays / or worse the driver is crashing
71+
72+
You probably want to draw more primitives than you have in your vertexbuffer, check arguments of your `glDrawArrays` call.
73+
Potentially you might not have set the vertex count variable and that contains an ununitialized value because you used c/c++ and are a doofus.
74+
75+
### Textures are black
76+
77+
- no textures bound
78+
- are your textures complete? if not should produce an output in debug callback, so, go check that (hmm this might not be the case for glXXXTextureStorage i might take this one off the list)
79+
- no samplers bound (check your sampler objects if you use them as separate objects)
80+
- fucked uvs
81+
- you might be sampling from a corner of your texture where its actually black, check uvs
82+
83+
### Your Tringle is black
84+
85+
- smells like your vao is fucked. make sure you setup the attributes (and stride when binding le vbo using DSA)
86+
- fucked uvs?
87+
- forgot to bind a texture?
88+
89+
### Screen is Black
90+
91+
- check if your screen is on/connected properly
92+
- camera (projection/view matrices are fucked) is not looking at the scene in question
93+
- no texture is sampled due to missing or wrong uvs => default value is 0 aka black (depends on the driver)
94+
- no shader bound (especially fragment shader)
95+
- fragment shader doesnt write anything to its output
96+
- no viewport is set/is too small
97+
- you might be rendering to a framebuffer, but not blitting that framebuffer to the default one
98+
- let clearcolor be something else than pure black
99+
- are you doing MRT?
100+
- if yes, check that you called the right `gl(Named)DrawBuffers` and not n times `gl(Named)DrawBuffer` one per render target
101+
- are you playing with depth pre pass-isms?
102+
- make sure the gl state between passes is the same, face winding, cullmode, etc, see Appending A.3 in the gl spec for more clues
103+
- check winding order and cullmode, you might be looking at the wrong side of your faces
104+
- you check renderdoc and wonder why the vertex list contains the same (perhaps even first element) only, for all vertices => make sure your `glDrawElements(..., ..., GL_UNSIGNED_INT, ...)` or whatever datatype your indexbuffer consists of matches that parameter
105+
106+
### Textures look funny, like a garbled version of the actual image
107+
108+
- make sure your internalformat and actual pixel format match. You probably used stb_image to load, but used 0 as the last parameter,
109+
and pixel data has 3 components, instead of the 4 (GL_RGBA) you told OpenGL about -> request 4 channels from stb_image
110+
111+
### Textures look like one color component is more prominent than others
112+
113+
- Colors are more shifted towards blue
114+
115+
- You probably messed up the format and asked for GL_BRG.. of sorts => make sure they match
116+
117+
- Colors are more shifted towards red
118+
119+
- Original pixeldata was probably in BGR... but you asked for GL_RGB... of sorts => make sure they match
120+
121+
### Textures seem to work, but mesh also appear to be shaded weirdly as if black Fog is on
122+
123+
Did you generate mipmaps?
124+
125+
### Render artifacts like small missing tiles on a floor
126+
127+
- synchronization issues - perhaps a missing glMemoryBarrier at the right spot
128+
- ubo/ssbo alignment issue - check std140/430 rule in the glsl spec
129+
- binding multiple textures to the same slot - check your glBindTextureUnit calls
130+
- you might be using a float to index into a buffer to grab material/texture info, use a flat int
131+
132+
### Depth buffer not cleared
133+
134+
- Despite calling `glClear(GL_DEPTH_BUFFER_BIT)` => check if `glDepthMask` was set to `GL_FALSE`. When you use FBOs migrate to glClearNamedFramebuffer() if you havent already (still requires glDepthMask set properly)
135+
136+
### Weird "Z-fighting"
137+
138+
- check your depth buffer, near and far planes... try near 0.1f and 512/1024 as farplane
139+
- your depth buffer might be too small and is set to D16 only, set it to something D24 or D32
140+
- you use SDL2 and on your platform the default might be set to D16, find the SDL2_GL_Set_Attribute which sets the depth bits for the default fbo

0 commit comments

Comments
 (0)