Reputation: 566
Shaders written in for example GLSL are typically loaded into a graphics application at runtime. I am wondering why not just compile the application with the shaders so they will not have to be loaded later. Like this:
#define glsl(version, glsl) "#version " #version "\n" #glsl
namespace glsl { namespace vs {
//VERTEX SHADERS
//=========================
// simple VS
//=========================
constexpr GLchar * const simple = glsl(450 core,
layout(location = 0) in vec3 position;
void main() {
gl_Position = vec4(position, 1.0f);
}
);
} namespace fs {
//FRAGMENT SHADERS
//=========================
// simple FS
//=========================
constexpr GLchar * const simple = glsl(450 core,
out vec4 color;
void main() {
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
);
} }
I don't think this would result in too large of an exe file and it would speed up loading times; unless I'm mistaken about how many shaders are used for a typical graphics application. I realize you may want to update shaders after compile time, but does that really happen?
Is there any reason that I should not want to do this?
Upvotes: 7
Views: 2230
Reputation: 162164
How do you figure it would speed up load times? It doesn't!
It doesn't matter if you read data from a regular file that you opened with fopen
(or std::ifstream
or CreateFile
or whatever) and read from that, or if you're accessing some part of the process image. Heck, in most cases accessing some large-ish hunk of pages in the process image may perform worse, because most OSs are lazily populating pages in the segments that hold nonexecutable, readonly data; mmaped read access on unpopulated pages is actually slower than just a plain read, because it involves faulting the page table and a subsequent I/O read to populate the page with data.
Mandatory read: http://lkml.iu.edu/hypermail/linux/kernel/0004.0/0728.html
The OpenGL API specifices GLSL source code being the only way to actually load shaders. There's a caching API (glShaderBinary, glProgramBinary) but the binaries loaded through that are in an unspecified format, that may change at any time, and it's a valid error condition that the driver rejects a binary for whatever reason to enforce loading the original GLSL source. To actually obtain such a shader binary you first load a regular GLSL shader source, compile it and then retrieve a binary blob from OpenGL.
Upvotes: 1
Reputation: 14057
A few reasons:
Upvotes: 5
Reputation: 708
The shader compilation process is part of OpenGL's glsl compiler, while you can hardcore the shaders into memory as a string, it would require recompilation everytime you make ANY edit to the shaders.
In game programming you generally do not want to recompile the whole project when you are making small tweaks to hundreds of parts of the code, shaders, libraries, etc. This is one of the main reasons why all large game engines have scripting engines, it is often better to write extra boilerplate code to integrate scripting into your engine than have to compile a program 10 times just to get the color/shininess/position of your object just right. Try hardcoding all your shaders so they compile at runtime in memory and you'll see just how tedious it becomes after a day!
Upvotes: 0