I recently created a game (LD21) that uses a geometry shader to convert points into textured triangles/culling. Since I was under the impression that the support for #330 was widespread I only wrote #330 shaders, but it seems that a lot of not so old hardware only support #130 (according to GLView)
Now, since I'm only familiar with the #330 core functionality I am having trouble rewriting my shaders to #130. The fragment shader was quite trivial to rewrite, but I've only managed to get my vertex and geometry shader down to #150.
So, is it possible to rewrite the shaders, or would it require a lot of changes in my rendering engine?
#version 150
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
uniform mat4 oMatrix;
in VertexData
{
vec4 position;
vec4 texcoord;
vec4 size;
} vert;
out vec2 gTexCoord;
void main()
{
if(vert.position.x>-4f && vert.position.x<4f && vert.position.y>-2f && vert.position.y<2f)
{
gTexCoord=vec2(vert.texcoord.z,vert.texcoord.y);
gl_Position = vert.position + vec4(vert.size.x,vert.size.y,0,0);
EmitVertex();
gTexCoord=vec2(vert.texcoord.x,vert.texcoord.y);
gl_Position = vert.position + vec4(0.0,vert.size.y,0,0);
EmitVertex();
gTexCoord=vec2(vert.texcoord.z,vert.texcoord.w);
gl_Position = vert.position + vec4(vert.size.x,0.0,0,0);
EmitVertex();
gTexCoord=vec2(vert.texcoord.x,vert.texcoord.w);
gl_Position = vert.position;
EmitVertex();
EndPrimitive();
}
}
#version 150
#extension GL_ARB_explicit_attrib_location : enable
layout (location = 0) in vec2 position;
layout (location = 1) in vec4 textureCoord;
layout (location = 2) in vec2 size;
uniform mat4 oMatrix;
uniform vec2 offset;
out VertexData
{
vec4 position;
vec4 texcoord;
vec4 size;
} outData;
void main()
{
outData.position = oMatrix * vec4(position.x+offset.x,position.y+offset.y,0,1);
outData.texcoord = textureCoord;
outData.size = oMatrix * vec4(size.x,size.y,0,0);
}
Answer
First of all, you won't be able to use struct
s for varying data (changed by 1.50), but you still can use in
and out
instead of attribute
and varying
. Additionally you have to write into the builtin variable gl_Position
in the vertex shader (changed by 1.40). So in your vertex shader substitute the declaration of outData
with something similar to
out vec4 texcoord;
out vec4 vSize; //size already used
and use gl_Position
instead of outData.position
.
I'm not sure if the ARB_explicit_attrib_location extension is already core, so maybe you have to add
#extension ARB_explicit_attrib_location : require
to use the layout
syntax or just set the attribute locations in the application by calling glBindAttribLocation
before linking the shader, if this extension is not supprted.
In the geometry shader change the decralation of vert to something like
in vec4 texcoord[]; //names have to match vertex shader, of course
in vec4 vSize[];
Although you only get a single input (as you're using points), they still have to be arrays, I think (although always index with [0]
, when used). Change the use of vert.position
to gl_PositionIn[0]
.
Next, I think the layout
syntax for the geometry shader has been introduced in 1.50, so you might have to set the geometry shader layout in the application by means of glProgramParameteri
.
I have to admit, that I have not much practical experience with geometry shaders or the modern syntax, as I still sit on 2.1 hardware, but all these changes can be deduced by looking into the respective specifications. Just look at the shader info logs if compilation (or linking) fails to gain some hints about what could be wrong.
The missing of the layout
syntax in both the vertex and the geometry shader are the only things that might require some small additions to your application code, but I'm not completely sure if they are really unsupprted, so try them last.
Also, feel free to update your question if I missed anything and the shaders still don't work, maybe this time with some error messages from the GLSL compiler.
No comments:
Post a Comment