remove modules under test; see dev branch

This commit is contained in:
khenderson96
2025-10-07 11:35:27 -04:00
parent 441866a970
commit acf44d9407
2 changed files with 0 additions and 347 deletions
-122
View File
@@ -479,125 +479,3 @@ class LavaLampSynth(Animation):
Public method to get the next frame of the metaball animation.
"""
return self.do_metaballs(frame)
# def metaballs_sliders(self, default_font_id=None, global_font_id=None):
# with dpg.collapsing_header(label=f"\tMetaballs", tag="metaballs"):
# num_metaballs_slider = TrackbarRow(
# "Num Metaballs",
# params.get("num_metaballs"),
# TrackbarCallback(params.get("num_metaballs"), "num_metaballs").__call__,
# self.reset_slider_callback,
# default_font_id)
# min_radius_slider = TrackbarRow(
# "Min Radius",
# params.get("min_radius"),
# TrackbarCallback(params.get("min_radius"), "min_radius").__call__,
# self.reset_slider_callback,
# default_font_id)
# max_radius_slider = TrackbarRow(
# "Max Radius",
# params.get("max_radius"),
# TrackbarCallback(params.get("max_radius"), "max_radius").__call__,
# self.reset_slider_callback,
# default_font_id)
# max_speed_slider = TrackbarRow(
# "Max Speed",
# params.get("max_speed"),
# TrackbarCallback(params.get("max_speed"), "max_speed").__call__,
# self.reset_slider_callback,
# default_font_id)
# threshold_slider = TrackbarRow(
# "Threshold",
# params.get("threshold"),
# TrackbarCallback(params.get("threshold"), "threshold").__call__,
# self.reset_slider_callback,
# default_font_id)
# smooth_coloring_max_field_slider = TrackbarRow(
# "Smooth Coloring Max Field",
# params.get("smooth_coloring_max_field"),
# TrackbarCallback(params.get("smooth_coloring_max_field"), "smooth_coloring_max_field").__call__,
# self.reset_slider_callback,
# default_font_id)
# feedback_alpha_slider = TrackbarRow(
# "Feedback Alpha",
# params.get("metaballs_feedback"),
# TrackbarCallback(params.get("metaballs_feedback"), "metaballs_feedback").__call__,
# self.reset_slider_callback,
# default_font_id)
# frame_blend_slider = TrackbarRow(
# "Frame Blend",
# params.get("frame_blend"),
# TrackbarCallback(params.get("frame_blend"), "frame_blend").__call__,
# self.reset_slider_callback,
# default_font_id)
# dpg.bind_item_font("metaballs", global_font_id)
class MoirePattern(Animation):
#TODO: implement dynamic moire pattern animation
#TODO: add parameters to control line frequency, angle, and animation speed
def __init__(self):
pass
def create_moire_pattern(size=(800, 800)):
"""
Generates a Moire pattern image by combining two sets of oscillating lines.
The Moire effect is created when two regular patterns (like grids or
sine waves) are superimposed, resulting in a new, larger-scale pattern.
"""
# 1. Initialize an empty image canvas (8-bit grayscale)
height, width = size
canvas = np.zeros(size, dtype=np.uint8)
# Create coordinate grids
# 'X' gives column index for every pixel, 'Y' gives row index
X, Y = np.meshgrid(np.arange(width), np.arange(height))
# --- Pattern 1: Vertical lines, slightly angled ---
# Freq: 0.1, Angle: 1 degree
frequency1 = 0.1
angle1 = np.deg2rad(1)
# Project coordinates onto the angled line
P1 = X * np.cos(angle1) + Y * np.sin(angle1)
# Use sine wave to create oscillating intensity (lines)
pattern1 = (np.sin(P1 * frequency1) * 127 + 128).astype(np.uint8)
# --- Pattern 2: Vertical lines, slightly different frequency and angle ---
# Freq: 0.105, Angle: -1 degree
frequency2 = 0.105
angle2 = np.deg2rad(-1)
# Project coordinates onto the second angled line
P2 = X * np.cos(angle2) + Y * np.sin(angle2)
# Second sine wave pattern
pattern2 = (np.sin(P2 * frequency2) * 127 + 128).astype(np.uint8)
# 2. Combine patterns to create the Moire effect
# Multiplication or addition of the two patterns creates the interference.
# Here, we use multiplication (scaled and normalized) for a strong effect.
combined_pattern = (pattern1.astype(np.float32) * pattern2.astype(np.float32)) / 255.0
# Scale back to 0-255 range and convert to 8-bit integer
moire_image = (combined_pattern * 255).astype(np.uint8)
# 3. Apply a contrast stretch (optional but makes pattern clearer)
# The Moire effect is usually visible in the darker parts of the image.
moire_image = cv2.equalizeHist(moire_image)
return moire_image
def get_frame(self):
return self.create_moire_pattern((self.width, self.height))
-225
View File
@@ -1,225 +0,0 @@
import cv2
import numpy as np
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram
# --- GLSL Shader Source Code (Inline) ---
# The shaders remain the same as the rendering logic is OpenGL standard.
VERTEX_SHADER_SOURCE = """
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
TexCoord = aTexCoord;
}
"""
# Fragment Shader: Applies the simple 'Cyberpunk Grayscale' effect
FRAGMENT_SHADER_SOURCE = """
#version 330 core
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D ourTexture;
uniform float time; // Time uniform for animation
void main()
{
vec4 texColor = texture(ourTexture, TexCoord);
float gray = dot(texColor.rgb, vec3(0.2126, 0.7152, 0.0722));
// Apply color shift effect (Cyberpunk/Monochrome look)
vec3 outputColor = vec3(gray, gray, gray);
outputColor.g *= 1.0 + sin(time) * 0.1;
outputColor.b *= 1.2 + cos(time) * 0.1;
outputColor.r *= 0.8;
FragColor = vec4(outputColor, texColor.a);
}
"""
def compile_and_link_shader(vs_source, fs_source):
"""Compiles the vertex and fragment shaders and links them into a program."""
try:
vertex_shader = compileShader(vs_source, GL_VERTEX_SHADER)
fragment_shader = compileShader(fs_source, GL_FRAGMENT_SHADER)
shader_program = compileProgram(vertex_shader, fragment_shader)
return shader_program
except Exception as e:
print(f"Shader compilation/linking failed: {e}")
return 0
def load_opencv_image_as_texture(image_path):
"""
Loads an image using OpenCV and converts it into an OpenGL texture ID.
NOTE: A placeholder image is used if loading fails.
"""
try:
# Load image using OpenCV
img = cv2.imread(image_path)
if img is None:
raise FileNotFoundError(f"Image not found at path: {image_path}. Using placeholder.")
except Exception:
# Create a simple placeholder image (512x512 blue gradient)
img = np.zeros((512, 512, 3), dtype=np.uint8)
for i in range(512):
img[:, i, 0] = 255 - i // 2
img[:, i, 2] = i // 2
print("Using a generated blue gradient placeholder image.")
# Convert BGR (OpenCV default) to RGB, and flip vertically (OpenGL convention)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_flipped = np.flipud(img_rgb)
# Generate and bind the texture
texture_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture_id)
# Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# Upload the image data to the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img_flipped.shape[1], img_flipped.shape[0], 0, GL_RGB, GL_UNSIGNED_BYTE, img_flipped)
glGenerateMipmap(GL_TEXTURE_2D)
return texture_id, img_flipped.shape[1], img_flipped.shape[0]
# --- Main Application Logic (Using GLFW) ---
def run_shader_app_glfw():
# --- Configuration ---
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
IMAGE_PATH = "sample_image.jpg" # Replace with your image path
# --- GLFW Initialization ---
if not glfw.init():
print("Failed to initialize GLFW")
return
# Set OpenGL version hints
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
# Load image first to determine window size
texture_id, img_width, img_height = load_opencv_image_as_texture(IMAGE_PATH)
# Calculate window size based on image aspect ratio
aspect_ratio = img_width / img_height
final_width = SCREEN_WIDTH
final_height = int(SCREEN_WIDTH / aspect_ratio)
if final_height > SCREEN_HEIGHT:
final_height = SCREEN_HEIGHT
final_width = int(SCREEN_HEIGHT * aspect_ratio)
# Create a windowed mode window and its OpenGL context
window = glfw.create_window(final_width, final_height, "OpenCV Image with GLSL Shader (GLFW)", None, None)
if not window:
glfw.terminate()
print("Failed to create GLFW window")
return
glfw.make_context_current(window)
# Set up the viewport
glViewport(0, 0, final_width, final_height)
# Define the key callback function for exiting
def key_callback(window, key, scancode, action, mods):
if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
glfw.set_window_should_close(window, True)
glfw.set_key_callback(window, key_callback)
# --- Shader Compilation ---
shader_program = compile_and_link_shader(VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
if not shader_program:
glfw.terminate()
return
# --- Quad Geometry Setup (The screen where the texture is drawn) ---
quad_vertices = np.array([
# Positions # Texture Coords
-1.0, 1.0, 0.0, 0.0, 1.0, # Top-Left
1.0, 1.0, 0.0, 1.0, 1.0, # Top-Right
1.0, -1.0, 0.0, 1.0, 0.0, # Bottom-Right
-1.0, -1.0, 0.0, 0.0, 0.0 # Bottom-Left
], dtype=np.float32)
quad_indices = np.array([0, 1, 2, 2, 3, 0], dtype=np.uint32)
# Setup VAO/VBO/EBO (identical to the Pygame script)
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, quad_vertices.nbytes, quad_vertices, GL_STATIC_DRAW)
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, quad_indices.nbytes, quad_indices, GL_STATIC_DRAW)
# Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * quad_vertices.itemsize, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# Texture coordinate attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * quad_vertices.itemsize, ctypes.c_void_p(3 * quad_vertices.itemsize))
glEnableVertexAttribArray(1)
# --- Main Loop ---
glUseProgram(shader_program)
start_time = glfw.get_time()
while not glfw.window_should_close(window):
# Poll and process events (required by GLFW)
glfw.poll_events()
# Clear the screen
glClearColor(0.1, 0.1, 0.1, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
# Use the compiled shader program
glUseProgram(shader_program)
# Pass the current time to the shader for simple animation
current_time = glfw.get_time()
time_uniform_location = glGetUniformLocation(shader_program, "time")
glUniform1f(time_uniform_location, current_time - start_time)
# Bind the texture and sampler uniform
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, texture_id)
glUniform1i(glGetUniformLocation(shader_program, "ourTexture"), 0)
# Draw the quad
glBindVertexArray(VAO)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
# Swap buffers and display the rendered frame
glfw.swap_buffers(window)
# --- Cleanup ---
glDeleteTextures([texture_id])
glDeleteProgram(shader_program)
glDeleteVertexArrays(1, [VAO])
glDeleteBuffers(1, [VBO, EBO])
glfw.terminate()
if __name__ == '__main__':
run_shader_app_glfw()