internal void SetConstantBuffers(GraphicsDevice device, ShaderProgram shaderProgram)
#endif
        {
            // If there are no constant buffers then skip it.
            if (_valid == 0)
                return;

            var valid = _valid;

            for (var i = 0; i < _buffers.Length; i++)
            {
                var buffer = _buffers[i];
                if (buffer != null && !buffer.IsDisposed)
                {
#if DIRECTX
                    buffer.PlatformApply(device, _stage, i);
#elif OPENGL || PSM || WEB
                    buffer.PlatformApply(device, shaderProgram);
#endif
                }

                // Early out if this is the last one.
                valid &= ~(1 << i);
                if (valid == 0)
                    return;
            }
        }
        public MonoGameSpriteBatchUnpacked(GraphicsContext context, int size)
        {
            _context = context;
            Size = size;

            _indexArray = new ushort[6 * size];
            for (int i = 0; i < size; i++)
            {
                _indexArray[i * 6 + 0] = (ushort)(i * 4);
                _indexArray[i * 6 + 1] = (ushort)(i * 4 + 1);
                _indexArray[i * 6 + 2] = (ushort)(i * 4 + 2);
                _indexArray[i * 6 + 3] = (ushort)(i * 4 + 1);
                _indexArray[i * 6 + 4] = (ushort)(i * 4 + 3);
                _indexArray[i * 6 + 5] = (ushort)(i * 4 + 2);
            }

            _vertexArrayVector = new Vector2[4 * size];
            _vertexArrayColor = new VertexElementColor[4 * size];
            _vertexArrayTexture = new Vector2[4 * size];

            _vertexBuffer = new VertexBuffer(4 * size, 6 * size, VertexFormat.Float2, VertexFormat.UByte4N, VertexFormat.Float2);
            _vertexBuffer.SetIndices(_indexArray, 0, 0, 6 * size);

            _shader = new ShaderProgram("/Application/shaders/Texture.cgx");
        }
        public MonoGameSpriteBatchNoIndex(GraphicsContext context, int size)
        {
            _context = context;
            Size = size;

            _vertexArray = new VertexPosition2ColorTexture[4 * size];
            _vertexBuffer = new VertexBuffer(4 * size, VertexFormat.Float2, VertexFormat.UByte4N, VertexFormat.Float2);

            _shader = new ShaderProgram("/Application/shaders/Texture.cgx");
        }
        public unsafe void PlatformApply(GraphicsDevice device, ShaderProgram program)
        {
            // NOTE: We assume here the program has
            // already been set on the device.

            // If the program changed then lookup the
            // uniform again and apply the state.
            if (_shaderProgram != program)
            {
                var location = program.GetUniformLocation(_name);
                if (location == -1)
                    return;

                _shaderProgram = program;
                _location = location;
                _dirty = true;
            }

            // If the shader program is the same, the effect may still be different and have different values in the buffer
            if (!Object.ReferenceEquals(this, _lastConstantBufferApplied))
                _dirty = true;

            // If the buffer content hasn't changed then we're
            // done... use the previously set uniform state.
            if (!_dirty)
                return;

            fixed (byte* bytePtr = _buffer)
            {
                // TODO: We need to know the type of buffer float/int/bool
                // and cast this correctly... else it doesn't work as i guess
                // GL is checking the type of the uniform.

            #if SDL2
                device.GLDevice.glUniform4fv(
                    _location,
                    _buffer.Length / 16,
                    (IntPtr) bytePtr
                );
            #else
                GL.Uniform4(_location, _buffer.Length / 16, (float*)bytePtr);
            #endif
            }

            // Clear the dirty flag.
            _dirty = false;

            _lastConstantBufferApplied = this;
        }
Exemple #5
0
        internal EffectPass(Effect effect, EffectPass cloneSource)
        {
            Debug.Assert(effect != null, "Got a null effect!");
            Debug.Assert(cloneSource != null, "Got a null cloneSource!");

            _effect = effect;

            // Share all the immutable types.
            Name = cloneSource.Name;
            _blendState = cloneSource._blendState;
            _depthStencilState = cloneSource._depthStencilState;
            _rasterizerState = cloneSource._rasterizerState;
            Annotations = cloneSource.Annotations;
            _vertexShader = cloneSource._vertexShader;
            _pixelShader = cloneSource._pixelShader;
#if PSM
            _shaderProgram = cloneSource._shaderProgram;
#endif
        }
Exemple #6
0
      internal EffectParameter EffectParameterForUniform(ShaderProgram shaderProgram, int index)
      {
          //var b = shaderProgram.GetUniformBinding(i);
          var name = shaderProgram.GetUniformName(index);
          //var s = shaderProgram.GetUniformSize(i);
          //var x = shaderProgram.GetUniformTexture(i);
          var type = shaderProgram.GetUniformType(index);
          
          //EffectParameter.Semantic => COLOR0 / POSITION0 etc
 
          //FIXME: bufferOffset in below lines is 0 but should probably be something else
          switch (type)
          {
          case ShaderUniformType.Float4x4:
              return new EffectParameter(
                  EffectParameterClass.Matrix, EffectParameterType.Single, name,
                  4, 4, "float4x4",EffectAnnotationCollection.Empty, EffectParameterCollection.Empty, EffectParameterCollection.Empty, new float[4 * 4]);
          case ShaderUniformType.Float4:
              return new EffectParameter(
                  EffectParameterClass.Vector, EffectParameterType.Single, name,
                  4, 1, "float4",EffectAnnotationCollection.Empty, EffectParameterCollection.Empty, EffectParameterCollection.Empty, new float[4]);
          case ShaderUniformType.Sampler2D:
              return new EffectParameter(
                  EffectParameterClass.Object, EffectParameterType.Texture2D, name,
                  1, 1, "texture2d",EffectAnnotationCollection.Empty, EffectParameterCollection.Empty, EffectParameterCollection.Empty, null);
          default:
              throw new Exception("Uniform Type " + type + " Not yet implemented (" + name + ")");
          }
      }
        private void Link(Shader vertexShader, Shader pixelShader)
        {
            // NOTE: No need to worry about background threads here
            // as this is only called at draw time when we're in the
            // main drawing thread.
            var program = GL.CreateProgram();
            GraphicsExtensions.CheckGLError();

            GL.AttachShader(program, vertexShader.GetShaderHandle());
            GraphicsExtensions.CheckGLError();

            GL.AttachShader(program, pixelShader.GetShaderHandle());
            GraphicsExtensions.CheckGLError();

            //vertexShader.BindVertexAttributes(program);

            GL.LinkProgram(program);
            GraphicsExtensions.CheckGLError();

            GL.UseProgram(program);
            GraphicsExtensions.CheckGLError();

            vertexShader.GetVertexAttributeLocations(program);

            pixelShader.ApplySamplerTextureUnits(program);

            var linked = 0;

            GL.GetProgram(program, GetProgramParameterName.LinkStatus, out linked);
            GraphicsExtensions.LogGLError("VertexShaderCache.Link(), GL.GetProgram");
            if (linked == 0)
            {
                var log = GL.GetProgramInfoLog(program);
                Console.WriteLine(log);
                GL.DetachShader(program, vertexShader.GetShaderHandle());
                GL.DetachShader(program, pixelShader.GetShaderHandle());
#if MONOMAC
                GL.DeleteProgram(1, ref program);
#else
                GL.DeleteProgram(program);
#endif
                throw new InvalidOperationException("Unable to link effect program");
            }

            ShaderProgram shaderProgram = new ShaderProgram(program);

            _programCache.Add(vertexShader.HashKey | pixelShader.HashKey, shaderProgram);
        }
 private void PlatformClear()
 {
     // Force the uniform location to be looked up again
     _shaderProgram = null;
 }
        public unsafe void PlatformApply(GraphicsDevice device, ShaderProgram program)
        {
#warning Unimplemented
        }
 private static void SetEffectParameter(ShaderProgram program, EffectParameter param)
 {
     if (param.Name == "posFixup")
         return;
     int location = program.GetUniformLocation(param.Name);
     switch (param.ParameterClass)
     {
         case EffectParameterClass.Object:
             SetEffectParameterObject(program,location, param);
             break;
         case EffectParameterClass.Vector:
             SetEffectParameterVector(program, location, param);
             break;
         case EffectParameterClass.Matrix:
             SetEffectParameterMatrix(program,location, param);
             break;
         case EffectParameterClass.Scalar:
             SetEffectParameterFloat(program, location, param);
             break;
     }
     GraphicsExtensions.CheckGLError();
 }
 private static void SetEffectParameterVector(ShaderProgram program,int location, EffectParameter param)
 {
     //int elementCount = param.RowCount * param.ColumnCount;
     unsafe
     {
         float[] objArray = (float[])param.Data;
         fixed (float* data = objArray)
         {
             if (objArray.Length == 2)
                 GL.Uniform2(location, 1, data);
             else if(objArray.Length == 3)
                 GL.Uniform3(location, 1, data);
             else
                 GL.Uniform4(location, 1, data);
         }
     }
 }
 private static void SetEffectParameterMatrix(ShaderProgram program, int location, EffectParameter param)
 {
     //int elementCount = param.RowCount * param.ColumnCount;
     unsafe
     {
         float[] objArray = (float[])param.Data;
         fixed (float* data = objArray)
         {
             GL.UniformMatrix4(location, 1,false, data);
         }
     }
 }
 private static void SetEffectParameterObject(ShaderProgram program,int location,EffectParameter param)
 {
     object obj = param.Data;
 }
 private void PlatformClear()
 {
     // Force the uniform location to be looked up again
     _shaderProgram = null;
 }
Exemple #15
0
        private void Link(Shader vertexShader, Shader pixelShader)
        {
            // NOTE: No need to worry about background threads here
            // as this is only called at draw time when we're in the
            // main drawing thread.
            var program = vertexShader.GraphicsDevice.GLDevice.glCreateProgram();

            vertexShader.GraphicsDevice.GLDevice.glAttachShader(program, vertexShader.GetShaderHandle());

            vertexShader.GraphicsDevice.GLDevice.glAttachShader(program, pixelShader.GetShaderHandle());

            vertexShader.GraphicsDevice.GLDevice.glLinkProgram(program);

            vertexShader.GraphicsDevice.GLDevice.glUseProgram(program);

            vertexShader.GetVertexAttributeLocations(program);

            pixelShader.ApplySamplerTextureUnits(program);

            var linked = 0;
            vertexShader.GraphicsDevice.GLDevice.glGetProgramiv(
                program,
                OpenGLDevice.GLenum.GL_LINK_STATUS,
                out linked
            );
            if (linked == 0)
            {
                Console.WriteLine(
                    vertexShader.GraphicsDevice.GLDevice.glGetProgramInfoLog(program)
                );

                vertexShader.GraphicsDevice.GLDevice.glDetachShader(program, vertexShader.GetShaderHandle());
                vertexShader.GraphicsDevice.GLDevice.glDetachShader(program, pixelShader.GetShaderHandle());

                vertexShader.GraphicsDevice.GLDevice.glDeleteProgram(program);
                throw new InvalidOperationException("Unable to link effect program");
            }

            ShaderProgram shaderProgram = new ShaderProgram(program);

            _programCache.Add(vertexShader.HashKey | pixelShader.HashKey, shaderProgram);
        }
        /// <summary>
        /// Activates the Current Vertex/Pixel shader pair into a program.
        /// </summary>
        private void ActivateShaderProgram()
        {
            // Lookup the shader program.
            var shaderProgram = _programCache.GetProgram(VertexShader, PixelShader);

            if (shaderProgram.Program == -1)
            {
                return;
            }
            // Set the new program if it has changed.
            if (_shaderProgram != shaderProgram)
            {
                GL.UseProgram(shaderProgram.Program);
                GraphicsExtensions.CheckGLError();
                _shaderProgram = shaderProgram;
            }

            var posFixupLoc = shaderProgram.GetUniformLocation("posFixup");

            if (posFixupLoc == -1)
            {
                return;
            }

            // Apply vertex shader fix:
            // The following two lines are appended to the end of vertex shaders
            // to account for rendering differences between OpenGL and DirectX:
            //
            // gl_Position.y = gl_Position.y * posFixup.y;
            // gl_Position.xy += posFixup.zw * gl_Position.ww;
            //
            // (the following paraphrased from wine, wined3d/state.c and wined3d/glsl_shader.c)
            //
            // - We need to flip along the y-axis in case of offscreen rendering.
            // - D3D coordinates refer to pixel centers while GL coordinates refer
            //   to pixel corners.
            // - D3D has a top-left filling convention. We need to maintain this
            //   even after the y-flip mentioned above.
            // In order to handle the last two points, we translate by
            // (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
            // translating slightly less than half a pixel. We want the difference to
            // be large enough that it doesn't get lost due to rounding inside the
            // driver, but small enough to prevent it from interfering with any
            // anti-aliasing.
            //
            // OpenGL coordinates specify the center of the pixel while d3d coords specify
            // the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
            // 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
            // contains 1.0 to allow a mad.

            _posFixup[0] = 1.0f;
            _posFixup[1] = 1.0f;
            _posFixup[2] = (63.0f / 64.0f) / Viewport.Width;
            _posFixup[3] = -(63.0f / 64.0f) / Viewport.Height;

            //If we have a render target bound (rendering offscreen)
            if (IsRenderTargetBound)
            {
                //flip vertically
                _posFixup[1] *= -1.0f;
                _posFixup[3] *= -1.0f;
            }

            GL.Uniform4(posFixupLoc, 1, _posFixup);
            GraphicsExtensions.CheckGLError();
        }