Something is wrong with my GLSL shader for Minecraft - glsl

While i was making my shader for minecraft ive run into a problem
0(13) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(14) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(18) : error C1503: undefined variable "gbufferModelView"
0(18) : error C1503: undefined variable "gbufferProjection"
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] Error linking program: 20 (gbuffers_terrain
[16:24:00] [Client thread/INFO] [net.optifine.shaders.SMCLog]: [Shaders] Info log: gbuffers_terrain
Vertex info
0(13) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(14) : error C0000: syntax error, unexpected ';', expecting '{' at token ";"
0(18) : error C1503: undefined variable "gbufferModelView"
0(18) : error C1503: undefined variable "gbufferProjection"
(0) : error C2003: incompatible options for link
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] OpenGL error: 1282 (Invalid operation), program: gbuffers_terrain, at: useProgram
[16:24:00] [Client thread/INFO] [minecraft/GuiNewChat]: [CHAT] �eOpenGL Error�f: 1282 (Invalid operation)
[16:24:00] [Client thread/ERROR] [net.optifine.shaders.SMCLog]: [Shaders] [Shaders] Error: Invalid program "gbuffers_terrain"
[16:24:00] [Client thread/INFO] [minecraft/GuiNewChat]: [CHAT] [Shaders] Error: Invalid program "gbuffers_terrain"
[16:24:00] [Client thread/INFO] [net.optifine.shaders.SMCLog]: [Shaders] Shader info log: /shaders/gbuffers_block.fsh
0(13) : warning C7533: global variable gl_FragData is deprecated after version 120
Fragment info
#version 460
#define lightBlocks
#define intensity 1 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]
#define BlocksOfLight 20 //[1 5 10 15 20 25 30 40 50 60 70 80 90 100 120 140 150 170 190 200]
layout(location = 0) in vec3 p;
int Num = 0;
//uniform sampler2D texture;
out vec4 color;
out vec4 texcoord;
out vec4 lmcoord;
uniform gbufferModelView;
uniform gbufferProjection;
void main() {
gl_Position = gbufferModelView * gbufferProjection * p;
color = vec4(1.0f,0.5f,1.0f,1.0f);
}
#version 120
uniform sampler2D texture;
uniform int worldTime;
float fac = 1.0f-abs(sin((worldTime/24000.0f)*3.14159f+3.14159f/4.0f));
in vec4 color;
in vec4 texcoord;
in vec4 lmcoord;
vec4 tex = texture2D(texture, texcoord.st);
vec3 colD = vec3(1.0f);
vec3 colN = vec3(0.0f,0.0f,0.5f);
vec3 light = (colD+(fac)*colN)/(fac+1.0f);
void main()
{
gl_FragColor = vec4(tex.r*color.r*(lmcoord.s+light.r),tex.g*color.g*(lmcoord.s+light.g),tex.b*color.b*(lmcoord.s+light.b),tex.a);
}
1st - Vertex 2nd - Fragment
Once, ive got wrong rendering of all blocks (all blocks in one single chunk somehow...), but then gbufferModelView and gbufferProjection stopped their work at all. Im on Minecraft 1.12.2

Related

Why I get error: OpenGL compatibility profile is not supported

I've just downloaded the lastest Vulkan SDK version (1.3.224.1) and when I try to compile a shader using shaderc I get this error: error: OpenGL compatibility profile is not supported.
I've cloned Hazel-2D Engine: https://github.com/TheCherno/Hazel by The Cherno just to check if it works fine because it builds the same Vulkan SDK things as in my project and has the same shaderc and spirv-cross code. It works in hazel but does not work inside my project.
shader code:
#version 450 core
layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_uv;
layout(location = 0) out vec2 v_uv;
void main()
{
v_uv = a_uv;
vec4 position = vec4(a_position, 0.0, 1.0);
gl_Position = position;
}
#version 450 core
layout(location = 0) out vec4 f_color;
layout(location = 0) in vec2 v_uv;
void main()
{
f_color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
I guess it's not important to show the whole premake script since the project builds fine.
I'll show just the most important part:
dependencies are defined like this:
VULKAN_SDK = os.getenv("VULKAN_SDK")
IncludeDir["VulkanSDK"] = "%{VULKAN_SDK}/Include"
LibraryDir = {}
LibraryDir["VulkanSDK"] = "%{VULKAN_SDK}/Lib"
Library = {}
Library["ShaderC_Debug"] = "%{LibraryDir.VulkanSDK}/shaderc_sharedd.lib"
Library["SPIRV_Cross_Debug"] = "%{LibraryDir.VulkanSDK}/spirv-cross-cored.lib"
Library["SPIRV_Cross_GLSL_Debug"] = "%{LibraryDir.VulkanSDK}/spirv-cross-glsld.lib"
Library["SPIRV_Tools_Debug"] = "%{LibraryDir.VulkanSDK}/SPIRV-Toolsd.lib"
and linked like this:
includedirs {
--other things...
"%{IncludeDir.VulkanSDK}",
}
filter "configurations:Debug"
symbols "On"
links {
"%{Library.ShaderC_Debug}",
"%{Library.SPIRV_Cross_Debug}",
"%{Library.SPIRV_Cross_GLSL_Debug}",
"%{Library.SPIRV_Tools_Debug}",
}
What I do first is compile Vulkan GLSL code into a spirv binaries (+ caching, but to provide a minimal example I removed it):
std::unordered_map<uint32_t, std::vector<uint32_t>> Shader::CompileGLSLToVulkanSpirvAndCache(const std::unordered_map<uint32_t, std::string>& shaderSource)
{
std::unordered_map<uint32_t, std::vector<uint32_t>> resultBinaries;
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
uint32_t shadersCount = static_cast<uint32_t>(shaderSource.size());
resultBinaries.reserve(shadersCount);
for(const auto& [type, source] : shaderSource) {
shaderc::SpvCompilationResult compilationResult = compiler.CompileGlslToSpv(source, GLShaderTypeToShadercShaderType(type), filepath.generic_string().c_str(), options);
if(compilationResult.GetCompilationStatus() != shaderc_compilation_status_success) {
EngineLogError(compilationResult.GetErrorMessage());
__debugbreak();
}
resultBinaries[type] = std::vector<uint32_t>(compilationResult.cbegin(), compilationResult.cend());
}
return resultBinaries;
}
and then using spirv_cross::CompilerGLSL I compile the vulkan spirv binaries to opengl spirv.
std::unordered_map<uint32_t, std::vector<uint32_t>> Shader::CompileFromVulkanToOpengl(const std::unordered_map<uint32_t, std::vector<uint32_t>>& vulkanBinaries)
{
std::unordered_map<uint32_t, std::vector<uint32_t>> resultBinaries;
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.SetTargetEnvironment(shaderc_target_env_opengl_compat, shaderc_env_version_opengl_4_5);
uint32_t shadersCount = static_cast<uint32_t>(vulkanBinaries.size());
resultBinaries.reserve(shadersCount);
for(const auto& [type, binaries] : vulkanBinaries) {
spirv_cross::CompilerGLSL glsl(binaries);
std::string source = glsl.compile();
shaderc::SpvCompilationResult compilationResult = compiler.CompileGlslToSpv(source, GLShaderTypeToShadercShaderType(type), filepath.generic_string().c_str(), options);
if(compilationResult.GetCompilationStatus() != shaderc_compilation_status_success) {
EngineLogError(compilationResult.GetErrorMessage());
__debugbreak();
}
resultBinaries[type] = std::vector<uint32_t>(compilationResult.cbegin(), compilationResult.cend());
}
return resultBinaries;
}
and CompileFromVulkanToOpengl this function returns this error: error: OpenGL compatibility profile is not supported.
How to fix it? Why it works in hazel 2d and does not work in my project?
OpenGL Info:
OpenGL Info:
Vendor: NVIDIA Corporation
Renderer: NVIDIA GeForce GTX 1080/PCIe/SSE2
Version: 4.6.0 NVIDIA 516.94

Unable to read the entire file correctly using fseek() and fread()

I have a file with shader source which i want to read that looks like this:
#version 460 core
layout(location = 0) in vec2 pos;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 fragColor;
uniform float rand;
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
void main()
{
fragColor = color * rand;
gl_Position = vec4(pos.x + 0.5 * gl_InstanceID, pos.y, 0, 1);
}
first i find out the size of my file:
fseek(m_file, 0L, SEEK_END);
size_t size = ftell(m_file);
This returns 364. The problem is that if i just copy+paste the file content into a R"()" string and get a strlen it returns 347.
After getting file size i try reading the whole file:
fseek(m_file, 0, SEEK_SET);
size_t count = fread(buffer, 1, size, m_file);
where buffer is allocated with 364 bytes. But fread returns 347 and feof(m_file) returns true. So as a result i get this:
(File explorer also shows that the file size is 364).
However, when i read the same file into a string using std::ifstream, everything works properly:
std::ifstream ifs(filename);
std::string content((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
auto size = content.size();
and size is equal to 347.
The question is: am i doing something wrong or Windows/fseek just show the file size wrongly?
The difference between the two sizes is 19 which coincidencally is the number of lines in your shader.
My guess is this has something to do with line ending conversations. Open the file as binary and the discrepency should go away.

Issues with TexelFetch and "Scalar Swizzle" in GLSL

I have done some work with shaders before but I would consider myself relatively inexperienced with GLSL. I am trying to write a fluid solver that simulates smoke using a series of fragment shaders. Most of these involve taking discrete samples from the texture and then doing some operation onh them, so they all have similar compilation errors. Every pixel, and only each pixel, must be evaluated so I am using texelFetch as opposed to texture2D for my sampling. The following is an example of such a fragment shader:
uniform sampler2D velocity;
uniform sampler2D pressure;
uniform sampler2D solid;
uniform float numCellsX;
uniform float numCellsY;
void main(void) {
ivec2 pos = ivec2(gl_FragCoord.xy);
if (texelFetch(solid, pos.xy, 0).x > 0.0)
discard;
float c = texelFetch(pressure, pos.xy, 0).x;
float up = texelFetchOffset(pressure, pos.xy, 0, ivec2(0, 1)).x;
float down = texelFetchOffset(pressure, pos.xy, 0, ivec2(0, -1)).x;
float left = texelFetchOffset(pressure, pos.xy, 0, ivec2(-1, 0)).x;
float right = texelFetchOffset(pressure, pos.xy, 0, ivec2(1, 0)).x;
float upS = texelFetchOffset(solid, pos.xy, 0, ivec2(0, 1)).x;
float downS = texelFetchOffset(solid, pos.xy, 0, ivec2(0, -1)).x;
float leftS = texelFetchOffset(solid, pos.xy, 0, ivec2(-1, 0)).x;
float rightS = texelFetchOffset(solid, pos.xy, 0, ivec2(1, 0)).x;
if (upS > 0.0) up = c;
if (downS > 0.0) down = c;
if (leftS > 0.0) left = c;
if (rightS > 0.0) right = c;
gl_FragColor = texelFetch(velocity, pos.xy, 0) - vec2(0.5 * numCellsX * (right - left), 0.5 * numCellsY * (up - down));
}
And when I run this through glSlangValidator, I get the following errors:
ERROR: 0:14: 'texelFetch' : no matching overloaded function found
ERROR: 0:14: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:17: 'texelFetch' : no matching overloaded function found
ERROR: 0:17: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:18: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:18: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:19: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:19: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:20: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:20: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:21: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:21: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:23: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:23: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:24: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:24: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:25: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:25: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:26: 'texelFetchOffset' : no matching overloaded function found
ERROR: 0:26: 'scalar swizzle' : not supported with this profile: es
ERROR: 0:33: 'texelFetch' : no matching overloaded function found
ERROR: 0:33: 'assign' : cannot convert from 'temp 2-component vector of float'
to 'fragColor mediump 4-component vector of float FragColor'
ERROR: 23 compilation errors. No code generated.
There is pretty much an error on almost every line and I have found very little information online about these things. Per the GLSL reference manual:
gvec4 texelFetch(gsampler2D sampler, ivec2 P, int lod);
I don't quite understand why it isn't accepting my texelFetch calls. I also don't know what scalar swizzle is (can't find this anywhere online) or why its an issue.
not supported with this profile: es
Perhaps you should compile it with the desktop version of GLSL, instead of GLSL ES (presumably 2.0). You should always use a #version declaration in your GLSL shaders.
Also, if you're using texelFetch, why are you still writing to deprecated outputs like gl_FragColor?
However:
cannot convert from 'temp 2-component vector of float'
That's true regardless of the version for this line:
texelFetch(velocity, pos.xy, 0) - vec2(0.5 * numCellsX * (right - left), 0.5 * numCellsY * (up - down))
texelFetch returns a 4-element vector. You cannot subtract a 2 element vector from a 4-element vector.

CgFx compiler error "Unknown state 'VertexShader'"

I' have the following CgFx file:
struct VertIn {
float4 pos : POSITION;
float4 color : COLOR0;
};
struct VertOut {
float4 pos : POSITION;
float4 color : COLOR0;
};
VertOut vert(VertIn IN) {
VertOut OUT;
OUT.pos = IN.pos;
OUT.color = IN.color;
OUT.color.z = 0.0f;
return OUT;
}
struct FragIn {
float4 color: COLOR;
};
struct FragOut {
float4 color : COLOR;
};
FragOut frag(FragIn IN) {
FragOut OUT;
OUT.color = IN.color;
OUT.color.y = 0.0f;
return OUT;
}
struct GeomIn {
float4 position : POSITION;
float4 color : COLOR0;
};
TRIANGLE void geom(AttribArray<GeomIn> IN) {
for(int i=0; i<IN.length; i++) {
emitVertex(IN[i]);
}
}
technique technique0 {
pass p0 {
VertexShader = compile gp4vp vert(); //line 47
FragmentShader = compile gp4fp frag(); //line 48
GeometryShader = compile gp4gp geom(); //line 49
}
}
when using cgc to verify the 3 shaders, they all compile fine.
but when I try to compile the whole effect using:
context=cgCreateContext();
effect=cgCreateEffectFromFile(context, "my_shader.cgfx", NULL);
if(!effect) {
printf(ygl.cgGetLastErrorString(NULL));
printf(cgGetLastListing(context));
}
then I get the following errors:
CG ERROR : The compile returned an error.
my_shader.cgfx(47) : error C8001: Unknown state 'VertexShader'
my_shader.cgfx(48) : error C8001: Unknown state 'FragmentShader'
my_shader.cgfx(49) : error C8001: Unknown state 'GeometryShader'
What do I do wrong?
After creating your context, you need to call
cgGLRegisterStates(handle);
where handle is your CG context handle. This will register things like VertexShader, PixelShader, FillMode, etc. I'm not sure why those aren't registered by default, but there you have it.
well, solved it, but don't know how. I think the compiler didn't expect CgFx because i did load a cg profile earlier, so it tried to use that one. but not sure.

How to make this code work on Mesa3d?

This GLSL code compile and run warningless in ATI's OpenGL:
void main()
{
vec4 tmp = gl_ModelViewMatrix * gl_Vertex;
tmp.xyz = tmp.xyz / (1 - tmp.w);
tmp.w = 1;
gl_Position = gl_ProjectionMatrix * tmp;
gl_FrontColor = gl_Color;
}
Why does it fail with mesa? How to decrypt that error message and make it Mesa's implementation compliant?
Compilation log:
0:1(88): error: Could not implicitly convert operands to arithmetic operator
0:1(89): error: Operands to arithmetic operators must be numeric
0:1(97): error: type mismatch
Try changing your 1s to 1.0s.