5
\$\begingroup\$

I'm working on implementing forward rendering in my 2D engine, as far as I'm aware everything should be set up correctly, I've ran into some issues earlier but I'm sure I've fixed those at this point.

So what I'm doing to achieve this (May or may not be the correct way of going about this) is that I'm rendering the object first with ambient light (Which works), and then for each light affecting the object, I render it once again using a different shader for point lights. I've set that shader to only output the color red atm, but nothing shows up apart from the first render of the object (The one with the ambient light).

Here are some pieces of my code.

Rendering of the object

        shader.Use();

        shader.SetUniform("_Model", transform.Model);
        shader.SetUniform("_Color", color.Normalized.ToVector3());
        shader.SetUniform("_Diffuse", texture.ArrayPos);

        VertexAttributePointer.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5, (System.IntPtr)0);
        VertexAttributePointer.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5, (System.IntPtr)(3 * sizeof(float)));

        //Render sprite
        quad.VAO.Bind();

        GL.Enable(EnableCap.Blend);

        //Transparency
        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);

        //Draw object
        GL.DrawElements(PrimitiveType.Quads, 4, DrawElementsType.UnsignedInt, 0);

        //Forward rendering
        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One);

        GL.DepthFunc(DepthFunction.Equal);
        GL.DepthMask(false);

        Shader pointLightShader = Shader.GetShader("Forward-Point");
        if (pointLightShader != null)
        {
            pointLightShader.Use();
            shader.SetUniform("_Model", transform.Model);
            shader.SetUniform("_Color", color.Normalized.ToVector3());
            shader.SetUniform("_Diffuse", texture.ArrayPos);

            foreach (Light l in Light.lights)
            {
                pointLightShader.SetUniform("_PointLight.position", new Vector3(l.position.X, l.position.Y, 0));
                pointLightShader.SetUniform("_PointLight.color", l.color.Normalized.ToVector3());

                GL.DrawElements(PrimitiveType.Quads, 4, DrawElementsType.UnsignedInt, 0);
            }
        }

        GL.DepthFunc(DepthFunction.Lequal);
        GL.DepthMask(true);
        GL.Disable(EnableCap.Blend);

        quad.VAO.Unbind();

        texture.Unbind();

Forward-Point fragment shader

Note that it is temporarily set to only output red, which should globally tint all objects if it works.

#version 330 core

struct Light {
    vec3 position;  
    vec3 color;
}; 

uniform vec3 _CameraPos;
uniform vec3 _Color;
uniform sampler2D _Diffuse;
uniform Light _PointLight;

out vec4 color;
in vec2 TexCoords;
in vec3 FragPos;

void main()
{
    vec4 diffuse = texture(_Diffuse, TexCoords);

    float distance = length(_PointLight.position - FragPos);
    float attenuation = 1.0;

    vec3 finalLight = _PointLight.color * attenuation;

    color = vec4(1.0, 0.0, 0.0, 1.0);
}
\$\endgroup\$
  • \$\begingroup\$ What happen if you change glDepthFunc to always passes? \$\endgroup\$ – Greffin28 Jun 20 '16 at 2:09
  • \$\begingroup\$ Tried that earlier, same result. It doesn't seem to be a depth issue. I even tried not drawing to the depth buffer at all so it shouldn't be that. @Greffin28 \$\endgroup\$ – Lym Jun 20 '16 at 2:10
  • \$\begingroup\$ If i were you, i would leave glDepthFunc to always passes and then do debugging, such as trying to render just 1 light. Or test it to render not from the light variables (Input the variables manually). If that renders, then bit by bit try to reconstruct the code. \$\endgroup\$ – Greffin28 Jun 20 '16 at 8:05
  • \$\begingroup\$ That's what I've been doing, I just changed it to Equal before I posted this since it technically is my actual value for it. I've tried changing around a lot of values while having it set to always pass with no luck, so I'm thinking it might be another issue. \$\endgroup\$ – Lym Jun 20 '16 at 14:54
  • \$\begingroup\$ Silly me, I forgot to mention you in my comment. @Greffin28 Is there anything else you can think of that might be causing the problem? \$\endgroup\$ – Lym Jun 21 '16 at 0:46
1
\$\begingroup\$

Here is a short list of things to check:

  • Does Forward-Point shader compiles successfully?
  • Does point light shader program (Program Object) links successfully?
  • Do you call glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) before rendering?
  • Have you enabled depth test (glEnable(GL_DEPTH_TEST))?
\$\endgroup\$
  • \$\begingroup\$ Yes to all of those, sadly. \$\endgroup\$ – Lym Jun 22 '16 at 21:38
  • \$\begingroup\$ @Lym do you bind variable named texture somewhere in your code? \$\endgroup\$ – Shot May 5 '17 at 7:45
0
\$\begingroup\$

One of the big benefits of forward rendering is that you can do all your lights in one shader. Switching programs is very expensive so you should not be switching programs for each rendering of objects. At the least you should do all of the rendering for all objects with the first shader THEN switch to the point light shader.

Here is a tutorial illustrating this idea:

http://www.learnopengl.com/#!Lighting/Multiple-lights

My guess is that you are doing something incorrect with the quad draw however, and that is the current error. Probably the wrong space is being used for the position or something like that. There are too many possible errors to know for sure without spending a lot of time on it though.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.