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(); } }
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 }