public void Draw(OpenGL gl, float originX, float originY, float originZ, float audioModifier, bool doOriginTranslation)
        {
            OriginX = originX;
            OriginY = originY;
            OriginZ = OriginZ;

            // Rotate colors
            if (_colorRotateStopwatch.ElapsedMilliseconds >= ColorRotateIntervalMs)
            {
                pickColor();
                _colorRotateStopwatch.Restart();
            }

            for (int index = 0; index < _particles.Count; index++)
            {
                Particle particle = _particles[index];
                float    x        = particle.X;
                float    y        = particle.Y;
                float    z        = particle.Z;
                float    r        = particle.R;
                float    g        = particle.G;
                float    b        = particle.B;
                float    a        = particle.Life;
                float    size     = particle.Size;

                _pointData[_point.DataStride * index + 0] = x;
                _pointData[_point.DataStride * index + 1] = y;
                _pointData[_point.DataStride * index + 2] = z;
                _pointData[_point.DataStride * index + 3] = size;
                _pointData[_point.DataStride * index + 4] = r;
                _pointData[_point.DataStride * index + 5] = g;
                _pointData[_point.DataStride * index + 6] = b;
                _pointData[_point.DataStride * index + 7] = a;

                // Increment particle location and speed
                if (OverrideParticleUpdate != null)
                {
                    OverrideParticleUpdate(particle, audioModifier);
                }
                else
                {
                    particle.Update();
                }

                // Invoke after update delegate if present
                if (AfterParticleUpdate != null)
                {
                    AfterParticleUpdate(particle, audioModifier);
                }

                // Reset dead particles
                if (particle.Life <= 0.0f)
                {
                    if (_isContinuous)
                    {
                        if (OverrideParticleInit != null)
                        {
                            // Call custom init if specified
                            OverrideParticleInit(particle, audioModifier);
                        }
                        else
                        {
                            // Re-init happening, no longer initial
                            particle.IsInitialInit = false;

                            // Default init
                            particle.Init(_random, audioModifier);

                            // Custom init if specified
                            if (AfterParticleInit != null)
                            {
                                AfterParticleInit(particle, audioModifier);
                            }
                        }

                        if (_autoRotateColors)
                        {
                            particle.R = Constants.Colors[_colorIndex, 0];
                            particle.G = Constants.Colors[_colorIndex, 1];
                            particle.B = Constants.Colors[_colorIndex, 2];
                        }
                    }
                    else
                    {
                        if (particle.IsAlive)
                        {
                            _deadParticleCount++;
                            particle.IsAlive = false;

                            if (_deadParticleCount == _particles.Count)
                            {
                                // None are alive. This particle system is no longer active
                                // and the caller should let it get GC'd
                                _isActive = false;
                            }
                        }
                    }
                }
            }

            // Begin Draw
            if (doOriginTranslation)
            {
                GlState.Instance.ModelMatrix = glm.translate(GlState.Instance.ModelMatrix, new vec3(originX, originY, originZ));
            }

            // Update buffers
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _vertexBufferObject[0]);
            GlBuffer.SetArrayData(gl, null, _pointData.Length * PrimitiveSizes.FloatBytes, OpenGL.GL_STREAM_DRAW);
            GlBuffer.SetArraySubData(gl, _pointData, _pointData.Length * PrimitiveSizes.FloatBytes);

            // Make model matrix available for drawing
            gl.UniformMatrix4(GlState.Instance.ParticleModelMatrixLocation, 1, false, GlState.Instance.ModelMatrix.to_array());

            // Set blending for particle system
            gl.BlendFunc(_blendMode, OpenGL.GL_ONE);
            gl.DepthFunc(OpenGL.GL_ALWAYS);

            // Draw
            gl.ActiveTexture(OpenGL.GL_TEXTURE0);
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, _texture);
            gl.Uniform1(GlState.Instance.ParticleTextureLocation, 0);
            gl.BindVertexArray(_vertexArrayObject[0]);
            gl.DrawArrays(OpenGL.GL_POINTS, 0, _pointData.Length);
            gl.BindVertexArray(0);
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, 0);

            // Reset depth and blend func
            gl.DepthFunc(OpenGL.GL_LESS);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

            if (doOriginTranslation)
            {
                GlState.Instance.ModelMatrix = mat4.identity();
            }
            // End Draw
        }
        public void Draw(OpenGL gl, float originX, float originY, float originZ, float[] audioData)
        {
            _ballOrigin.x = originX;
            _ballOrigin.y = originY;
            _ballOrigin.z = originZ;

            for (int index = 0; index < _pointSphere.VertexData.Length / _pointSphere.DataStride; index++)
            {
                float x    = _pointSphere.VertexData[_pointSphere.DataStride * index + 0];
                float y    = _pointSphere.VertexData[_pointSphere.DataStride * index + 1];
                float z    = _pointSphere.VertexData[_pointSphere.DataStride * index + 2];
                float r    = Constants.Colors[_colorIndex, 0];
                float g    = Constants.Colors[_colorIndex, 1];
                float b    = Constants.Colors[_colorIndex, 2];
                float a    = 0.0f;
                float size = audioData[0] / 8.0f;

                if (size < MinPointSize)
                {
                    size = MinPointSize;
                }
                if (size > MaxPointSize)
                {
                    size = MaxPointSize;
                }

                _pointData[_point.DataStride * index + 0] = x;
                _pointData[_point.DataStride * index + 1] = y;
                _pointData[_point.DataStride * index + 2] = z;
                _pointData[_point.DataStride * index + 3] = size;
                _pointData[_point.DataStride * index + 4] = r;
                _pointData[_point.DataStride * index + 5] = g;
                _pointData[_point.DataStride * index + 6] = b;
                _pointData[_point.DataStride * index + 7] = a;
            }

            // Rotation and scale factor
            _rotX += IdleRotationSpeed;
            _rotY += IdleRotationSpeed;
            _rotZ += IdleRotationSpeed;
            float scaleFactor = 1.0f + (audioData[0] * 0.04f);

            // Begin Draw
            GlState.Instance.ModelMatrix = mat4.identity();
            GlState.Instance.ModelMatrix = glm.translate(GlState.Instance.ModelMatrix, new vec3(originX, originY, originZ));
            GlState.Instance.ModelMatrix = glm.scale(GlState.Instance.ModelMatrix, new vec3(scaleFactor, scaleFactor, scaleFactor));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotX, new vec3(1, 0, 0));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotY, new vec3(0, 1, 0));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotZ, new vec3(0, 0, 1));

            // Update buffers
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _vertexBufferObject[0]);
            GlBuffer.SetArrayData(gl, null, _pointData.Length * PrimitiveSizes.FloatBytes, OpenGL.GL_STREAM_DRAW);
            GlBuffer.SetArraySubData(gl, _pointData, _pointData.Length * PrimitiveSizes.FloatBytes);

            // Make model matrix available for drawing
            gl.UniformMatrix4(GlState.Instance.ParticleModelMatrixLocation, 1, false, GlState.Instance.ModelMatrix.to_array());

            // Set blending for particle system
            gl.BlendFunc(OpenGL.GL_ONE, OpenGL.GL_ONE);
            gl.DepthFunc(OpenGL.GL_ALWAYS);

            // Draw
            gl.ActiveTexture(OpenGL.GL_TEXTURE0);
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, _texture);
            gl.Uniform1(GlState.Instance.ParticleTextureLocation, 0);
            gl.BindVertexArray(_vertexArrayObject[0]);
            gl.DrawArrays(OpenGL.GL_POINTS, 0, _pointData.Length);
            gl.BindVertexArray(0);
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, 0);

            // Reset depth and blend func
            gl.DepthFunc(OpenGL.GL_LESS);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

            GlState.Instance.ModelMatrix = mat4.identity();
            // End Draw
        }
        public void Draw(OpenGL gl, float originX, float originY, float originZ, float[] spectrumData)
        {
            float initialOffsetX = 0.0f;

            if (spectrumData != null)
            {
                // Reset model matrix
                GlState.Instance.ModelMatrix = mat4.identity();

                // Consider this as one "item". Start drawing offset -x by half
                // This means offset = -(bar count / 2) * (thickness + barspacing)
                initialOffsetX = ((spectrumData.Length / 2.0f) * (_cube.Thickness + BarSpacing)) * -1.0f;

                // Tranlate to offset - this is where we'll start drawing
                GlState.Instance.ModelMatrix = glm.translate(GlState.Instance.ModelMatrix, new vec3(initialOffsetX + originX, originY, originZ));

                float offsetX = 0.0f;

                // Update vertex data
                for (int index = 0; index < BarCount; index++)
                {
                    float pointHeight = spectrumData[index] > 0.0f ? spectrumData[index] : ParticleSystem.NoSpeedModifier;

                    _positionData[PositionDataLength * index + 0] = offsetX;
                    _positionData[PositionDataLength * index + 3] = pointHeight;

                    _colorData[ColorDataLength * index + 0] = _lineColors[index].Item1;
                    _colorData[ColorDataLength * index + 1] = _lineColors[index].Item2;
                    _colorData[ColorDataLength * index + 2] = _lineColors[index].Item3;
                    _colorData[ColorDataLength * index + 3] = 0.8f;

                    offsetX += _cube.Thickness + BarSpacing;
                }

                // Push vertex data back in 2D array
                int rows = _allPositionDataStructured.GetLength(0);
                int cols = _allPositionDataStructured.GetLength(1);

                if (_rowDrawStopwatch.ElapsedMilliseconds > RowDrawIntervalMs)
                {
                    if (_rowsToDraw == rows - 1)
                    {
                        _rowsToDraw = 0;
                    }

                    _rowDrawStopwatch.Restart();
                }

                for (int row = 0; row < rows - 1; row++)
                {
                    for (int col = 0; col < cols; col++)
                    {
                        // Push data back a dimension
                        _allPositionDataStructured[row + 1, col] = _allPositionDataStructured[row, col];
                    }
                }

                // Copying complete - bring new data in
                for (int col = 0; col < cols; col++)
                {
                    _allPositionDataStructured[0, col] = _positionData[col];
                }

                _rowsToDraw++;

                // Flatten 2D array
                int   destFlatIndex = 0;
                float zOffset       = 0.0f;

                for (int row = 0; row < rows; row++)
                {
                    for (int col = 0; col < cols; col++)
                    {
                        if (col % PositionDataLength == 2)
                        {
                            _allPositionDataStructured[row, col] = zOffset;
                        }

                        _allPositionData[destFlatIndex] = _allPositionDataStructured[row, col];
                        destFlatIndex++;
                    }

                    // Move "in" for each row
                    zOffset -= _cube.Thickness + BarSpacing;
                }

                // Vertex attribute
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _vertexBufferObject[0]);
                GlBuffer.SetArrayData(gl, _cube.VertexData, _cube.SizeOfVertexDataBytes, OpenGL.GL_STATIC_DRAW);

                // PositionAndSize attribute
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _positionBufferObject[0]);
                GlBuffer.SetArrayData(gl, null, _allPositionData.Length * PrimitiveSizes.FloatBytes, OpenGL.GL_STREAM_DRAW);
                GlBuffer.SetArraySubData(gl, _allPositionData, _allPositionData.Length * PrimitiveSizes.FloatBytes);

                // Color attribute
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _colorBufferObject[0]);
                GlBuffer.SetArrayData(gl, null, _colorData.Length * PrimitiveSizes.FloatBytes, OpenGL.GL_STREAM_DRAW);
                GlBuffer.SetArraySubData(gl, _colorData, _colorData.Length * PrimitiveSizes.FloatBytes);

                // Make model matrix available for drawing
                gl.UniformMatrix4(GlState.Instance.SpectrumModelMatrixLocation, 1, false, GlState.Instance.ModelMatrix.to_array());

                // Draw
                gl.BindVertexArray(_vertexArrayObject[0]);
                gl.DrawArraysInstanced(OpenGL.GL_TRIANGLES, 0, _cube.VertexCount, TotalBarCount);
                gl.BindVertexArray(0);

                // Done drawing - reset model matrix
                GlState.Instance.ModelMatrix = mat4.identity();
            }
        }
Exemple #4
0
        public void Draw(OpenGL gl, float originX, float originY, float originZ, float[] audioData)
        {
            // Initial offset = half radius
            float initialXOffset = originX - (BaseRadius / 2.0f);

            for (int index = 0; index < _lineSphere.VertexData.Length / _lineSphere.DataStride; index++)
            {
                float x    = _lineSphere.VertexData[_lineSphere.DataStride * index + 0];
                float y    = _lineSphere.VertexData[_lineSphere.DataStride * index + 1];
                float z    = _lineSphere.VertexData[_lineSphere.DataStride * index + 2];
                float r    = Constants.Colors[_colorIndex, 0];
                float g    = Constants.Colors[_colorIndex, 1];
                float b    = Constants.Colors[_colorIndex, 2];
                float a    = 1.0f;
                float size = 0.6f;

                _pointData[_point.DataStride * index + 0] = x;
                _pointData[_point.DataStride * index + 1] = y;
                _pointData[_point.DataStride * index + 2] = z;
                _pointData[_point.DataStride * index + 3] = size;
                _pointData[_point.DataStride * index + 4] = r;
                _pointData[_point.DataStride * index + 5] = g;
                _pointData[_point.DataStride * index + 6] = b;
                _pointData[_point.DataStride * index + 7] = a;
            }

            _rotX += IdleRotationSpeed;
            _rotY += IdleRotationSpeed;
            _rotZ += IdleRotationSpeed;
            float scaleFactor = 1.0f + (audioData[0] * 0.1f);

            // Begin Draw
            GlState.Instance.ModelMatrix = mat4.identity();
            GlState.Instance.ModelMatrix = glm.translate(GlState.Instance.ModelMatrix, new vec3(initialXOffset, originY, originZ));
            GlState.Instance.ModelMatrix = glm.scale(GlState.Instance.ModelMatrix, new vec3(scaleFactor, scaleFactor, scaleFactor));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotX, new vec3(1, 0, 0));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotY, new vec3(0, 1, 0));
            GlState.Instance.ModelMatrix = glm.rotate(GlState.Instance.ModelMatrix, _rotZ, new vec3(0, 0, 1));

            // Update buffers
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, _vertexBufferObject[0]);
            GlBuffer.SetArrayData(gl, null, _pointData.Length * PrimitiveSizes.FloatBytes, OpenGL.GL_STREAM_DRAW);
            GlBuffer.SetArraySubData(gl, _pointData, _pointData.Length * PrimitiveSizes.FloatBytes);

            // Make model matrix available for drawing
            gl.UniformMatrix4(GlState.Instance.DefaultModelMatrixLocation, 1, false, GlState.Instance.ModelMatrix.to_array());

            // Set blending for particle system
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE);
            gl.DepthFunc(OpenGL.GL_ALWAYS);

            // Draw
            gl.BindVertexArray(_vertexArrayObject[0]);
            gl.DrawArrays(OpenGL.GL_LINES, 0, _pointData.Length);
            gl.BindVertexArray(0);

            // Reset depth and blend func
            gl.DepthFunc(OpenGL.GL_LESS);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

            GlState.Instance.ModelMatrix = mat4.identity();
            // End Draw
        }