diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..0bdde7b Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index c99ff6a..b8b0341 100644 --- a/.gitignore +++ b/.gitignore @@ -296,4 +296,6 @@ __pycache__/ *.btp.cs *.btm.cs *.odx.cs -*.xsd.cs \ No newline at end of file +*.xsd.cs +.DS_Store +.DS_Store diff --git a/Examples/hello.py b/Examples/hello.py deleted file mode 100644 index 26d35f8..0000000 --- a/Examples/hello.py +++ /dev/null @@ -1,12 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import SpoutSDK - -x = SpoutSDK.SpoutSender() - -print(x.SayHello()) - - - diff --git a/Examples/spout_FBO_sender_example.py b/Examples/spout_FBO_sender_example.py deleted file mode 100644 index 53d1a70..0000000 --- a/Examples/spout_FBO_sender_example.py +++ /dev/null @@ -1,149 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GLU import * - -verticies = ( - (1, -1, -1), - (1, 1, -1), - (-1, 1, -1), - (-1, -1, -1), - (1, -1, 1), - (1, 1, 1), - (-1, -1, 1), - (-1, 1, 1) - ) - -edges = ( - (0,1), - (0,3), - (0,4), - (2,1), - (2,3), - (2,7), - (6,3), - (6,4), - (6,7), - (5,1), - (5,4), - (5,7) - ) - - -def Cube(): - glBegin(GL_LINES) - for edge in edges: - for vertex in edge: - glVertex3fv(verticies[vertex]) - glEnd() - - -def main(): - - # window details - width = 800 - height = 600 - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout Python Sender') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) - - # OpenGL init - # setup OpenGL perspective - glMatrixMode(GL_PROJECTION) - gluPerspective(45, (display[0]/display[1]), 0.1, 50.0) - # setup default colours, blending modes, rotation and translation parameters - glMatrixMode(GL_MODELVIEW) - # reset the drawing perspective - glLoadIdentity() - # can disable depth buffer because we aren't dealing with multiple geometry in our scene - glDisable(GL_DEPTH_TEST) - glEnable(GL_ALPHA_TEST) - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(0.0,0.0,0.0,0.0) - glColor4f(1.0, 1.0, 1.0, 1.0); - glTranslatef(0,0, -5) - glRotatef(25, 2, 1, 0) - - # init spout sender - spoutSender = SpoutSDK.SpoutSender() - spoutSenderWidth = width - spoutSenderHeight = height - # Its signature in C++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); - spoutSender.CreateSender('Spout Python Sender', spoutSenderWidth, spoutSenderHeight, 0) - - # init spout sender texture ID - senderTextureID = glGenTextures(1) - - # initialise texture - glBindTexture(GL_TEXTURE_2D, senderTextureID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - # fill texture with blank data - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,spoutSenderWidth,spoutSenderHeight,0); - glBindTexture(GL_TEXTURE_2D, 0) - - # create fbo and connect it to our senderTexture - fbo = glGenFramebuffers(1) - glBindFramebuffer(GL_FRAMEBUFFER, fbo) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, senderTextureID, 0) - glBindFramebuffer(GL_FRAMEBUFFER, 0) - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - # setup frame - glActiveTexture(GL_TEXTURE0) - glClearColor(0.0,0.0,0.0,0.0) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # bind our fbo and render some content to it - by using an FBO we will get alpha transparency sent with Spout - glBindFramebuffer(GL_FRAMEBUFFER, fbo) - #Start fbo frame afresh by setting clear color and performing a clear operation - glClearColor(0.0,0.0,0.0,0.0) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # Perform a rotation and since we aren't resetting our perspective with glLoadIdentity, then each frame will perform a successive rotation on top of what we already see - glRotatef(1, 3, 1, 1) - - # draw cube - Cube() - - # back to the default framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, 0) - - # read the FBO and then use Blit to copy into the backbuffer. - # A faster approach may be to render the fbo to a textured quad, but this will do for now. - glBindFramebuffer (GL_READ_FRAMEBUFFER, fbo); - glBlitFramebuffer (0,0, spoutSenderWidth,spoutSenderHeight, 0,0, spoutSenderWidth,spoutSenderHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST) - glBindFramebuffer(GL_FRAMEBUFFER, 0) - - # send texture to Spout - # Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0); - spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, True, 0) - - # update display - pygame.display.flip() - - pygame.time.wait(10) - -main() - - - - - diff --git a/Examples/spout_NST_receiver.py b/Examples/spout_NST_receiver.py deleted file mode 100644 index ee1e955..0000000 --- a/Examples/spout_NST_receiver.py +++ /dev/null @@ -1,177 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import tensorflow as tf -import numpy as np -import transform -import argparse -import time -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GL.framebufferobjects import * -from OpenGL.GLU import * - - -"""parsing and configuration""" -def parse_args(): - desc = "Tensorflow implementation of 'Perceptual Losses for Real-Time Style Transfer and Super-Resolution', Spout receiver version" - parser = argparse.ArgumentParser(description=desc) - - parser.add_argument('--style_model', type=str, default='style/Checkpoints/saraswati.ckpt', help='location for model file (*.ckpt)') - - parser.add_argument('--spout_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the spout receiver') - - parser.add_argument('--spout_name', type=str, default='Composition - Resolume Arena', help='Spout receiving name - the name of the sender you want to receive') - - parser.add_argument('--window_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the window') - - return parser.parse_args() - - -"""main""" -def main(): - - # parse arguments - args = parse_args() - - # window details - width = args.window_size[0] - height = args.window_size[1] - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout Neural Style Receiver') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - - # OpenGL init - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glOrtho(0,width,height,0,1,-1) - glMatrixMode(GL_MODELVIEW) - glDisable(GL_DEPTH_TEST) - glClearColor(0.0,0.0,0.0,0.0) - glEnable(GL_TEXTURE_2D) - - # init spout receiver - receiverName = args.spout_name - spoutReceiverWidth = args.spout_size[0] - spoutReceiverHeight = args.spout_size[1] - # create spout receiver - spoutReceiver = SpoutSDK.SpoutReceiver() - - # Its signature in c++ looks like this: bool pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive); - spoutReceiver.pyCreateReceiver(receiverName,spoutReceiverWidth,spoutReceiverHeight, False) - - # create textures for spout receiver and spout sender - textureReceiveID = glGenTextures(1) - textureStyleID = glGenTextures(1) - - # initalise receiver texture - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - - # copy data into texture - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spoutReceiverWidth, spoutReceiverHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, None ) - glBindTexture(GL_TEXTURE_2D, 0) - - # initalise sender texture - glBindTexture(GL_TEXTURE_2D, textureStyleID); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - glBindTexture(GL_TEXTURE_2D, 0) - - # open tf session - soft_config = tf.ConfigProto(allow_soft_placement=True) - soft_config.gpu_options.allow_growth = True # to deal with large image - sess = tf.Session(config=soft_config) - # build tf graph - style = tf.placeholder(tf.float32, shape=[spoutReceiverHeight, spoutReceiverWidth, 3], name='input') - styleI = tf.expand_dims(style, 0) # add one dim for batch - - # result image from transform-net - scaler = transform.Transform() - y_hat = scaler.net(styleI/255.0) - y_hat = tf.squeeze(y_hat) # remove one dim for batch - y_hat = tf.clip_by_value(y_hat, 0., 255.) - - # initialize parameters - sess.run(tf.global_variables_initializer()) - - # load pre-trained model - saver = tf.train.Saver() - saver.restore(sess, args.style_model) - - # loop for graph frame by frame - while(True): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - spoutReceiver.ReleaseReceiver() - pygame.quit() - quit() - - # receive texture - # Its signature in c++ looks like this: bool pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO); - spoutReceiver.pyReceiveTexture(receiverName, spoutReceiverWidth, spoutReceiverHeight, textureReceiveID, GL_TEXTURE_2D, False, 0) - - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - # copy pixel byte array from received texture - data = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, outputType=None) #Using GL_RGB can use GL_RGBA - glBindTexture(GL_TEXTURE_2D, 0) - # swap width and height data around due to oddness with glGetTextImage. http://permalink.gmane.org/gmane.comp.python.opengl.user/2423 - data.shape = (data.shape[1], data.shape[0], data.shape[2]) - - # start time of the loop for FPS counter - start_time = time.time() - #run the graph - output = sess.run(y_hat, feed_dict={style: data}) - # fiddle back to an image we can display. I *think* this is correct - output = np.clip(output, 0.0, 255.0) - output = output.astype(np.uint8) - - # setup the texture so we can load the stylised output into it - glBindTexture(GL_TEXTURE_2D, textureStyleID) - # copy style output into texture - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, spoutReceiverWidth, spoutReceiverHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, output ) - - # setup window to draw to screen - glActiveTexture(GL_TEXTURE0) - - # clean start - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) - # reset drawing perspective - glLoadIdentity() - - # draw texture on screen - glBegin(GL_QUADS) - - glTexCoord(0,0) - glVertex2f(0,0) - - glTexCoord(1,0) - glVertex2f(spoutReceiverWidth,0) - - glTexCoord(1,1) - glVertex2f(spoutReceiverWidth,spoutReceiverHeight) - - glTexCoord(0,1) - glVertex2f(0,spoutReceiverHeight) - - glEnd() - - # update window - pygame.display.flip() - - # FPS = 1 / time to process loop - print("FPS: ", 1.0 / (time.time() - start_time)) - -if __name__ == '__main__': - main() diff --git a/Examples/spout_NST_sender_receiver.py b/Examples/spout_NST_sender_receiver.py deleted file mode 100644 index 24705bc..0000000 --- a/Examples/spout_NST_sender_receiver.py +++ /dev/null @@ -1,187 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import tensorflow as tf -import numpy as np -import transform -import argparse -import time -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GL.framebufferobjects import * -from OpenGL.GLU import * - - -"""parsing and configuration""" -def parse_args(): - desc = "Tensorflow implementation of 'Perceptual Losses for Real-Time Style Transfer and Super-Resolution', Spout sender/receiver version" - parser = argparse.ArgumentParser(description=desc) - - parser.add_argument('--style_model', type=str, default='style/Checkpoints/saraswati.ckpt', help='location for model file (*.ckpt)') - - parser.add_argument('--spout_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the spout receiver and sender') - - parser.add_argument('--spout_name', type=str, default='Composition - Resolume Arena', help='Spout receiving name - the name of the sender you want to receive') - - parser.add_argument('--window_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the window') - - return parser.parse_args() - - -"""main""" -def main(): - - # parse arguments - args = parse_args() - - # window details - width = args.window_size[0] - height = args.window_size[1] - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout Neural Style Sender/Receiver') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - - # OpenGL init - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glOrtho(0,width,height,0,1,-1) - glMatrixMode(GL_MODELVIEW) - glDisable(GL_DEPTH_TEST) - glClearColor(0.0,0.0,0.0,0.0) - glEnable(GL_TEXTURE_2D) - - # init spout receiver - receiverName = args.spout_name - spoutReceiverWidth = args.spout_size[0] - spoutReceiverHeight = args.spout_size[1] - # create spout receiver - spoutReceiver = SpoutSDK.SpoutReceiver() - - # Its signature in c++ looks like this: bool pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive); - spoutReceiver.pyCreateReceiver(receiverName,spoutReceiverWidth,spoutReceiverHeight, False) - - # init spout sender - spoutSender = SpoutSDK.SpoutSender() - spoutSenderWidth = args.spout_size[0] - spoutSenderHeight = args.spout_size[1] - # Its signature in c++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); - spoutSender.CreateSender('Neural Style Sender', spoutSenderWidth, spoutSenderHeight, 0) - - # create textures for spout receiver and spout sender - textureReceiveID = glGenTextures(1) - textureStyleID = glGenTextures(1) - - # initalise receiver texture - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - - # copy data into texture - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spoutReceiverWidth, spoutReceiverHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, None ) - glBindTexture(GL_TEXTURE_2D, 0) - - # open tf session - soft_config = tf.ConfigProto(allow_soft_placement=True) - soft_config.gpu_options.allow_growth = True # to deal with large image - sess = tf.Session(config=soft_config) - # build tf graph - style = tf.placeholder(tf.float32, shape=[spoutSenderHeight, spoutSenderWidth, 3], name='input') - styleI = tf.expand_dims(style, 0) # add one dim for batch - - # result image from transform-net - scaler = transform.Transform() - y_hat = scaler.net(styleI/255.0) - y_hat = tf.squeeze(y_hat) # remove one dim for batch - y_hat = tf.clip_by_value(y_hat, 0., 255.) - - # initialize parameters - sess.run(tf.global_variables_initializer()) - - # load pre-trained model - saver = tf.train.Saver() - saver.restore(sess, args.style_model) - - # loop for graph frame by frame - while(True): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - spoutReceiver.ReleaseReceiver() - pygame.quit() - quit() - - # receive texture - # Its signature in c++ looks like this: bool pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO); - spoutReceiver.pyReceiveTexture(receiverName, spoutReceiverWidth, spoutReceiverHeight, textureReceiveID, GL_TEXTURE_2D, False, 0) - - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - # copy pixel byte array from received texture - data = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, outputType=None) #Using GL_RGB can use GL_RGBA - glBindTexture(GL_TEXTURE_2D, 0) - # swap width and height data around due to oddness with glGetTextImage. http://permalink.gmane.org/gmane.comp.python.opengl.user/2423 - data.shape = (data.shape[1], data.shape[0], data.shape[2]) - - # start time of the loop for FPS counter - start_time = time.time() - #run the graph - output = sess.run(y_hat, feed_dict={style: data}) - # fiddle back to an image we can display. I *think* this is correct - output = np.clip(output, 0.0, 255.0) - output = output.astype(np.uint8) - - # setup the texture so we can load the stylised output into it - glBindTexture(GL_TEXTURE_2D, textureStyleID); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - # copy output into texture - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, spoutSenderWidth, spoutSenderHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, output ) - - # setup window to draw to screen - glActiveTexture(GL_TEXTURE0) - - # clean start - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) - # reset drawing perspective - glLoadIdentity() - - # draw texture on screen - glBegin(GL_QUADS) - - glTexCoord(0,0) - glVertex2f(0,0) - - glTexCoord(1,0) - glVertex2f(spoutSenderWidth,0) - - glTexCoord(1,1) - glVertex2f(spoutSenderWidth,spoutSenderHeight) - - glTexCoord(0,1) - glVertex2f(0,spoutSenderHeight) - - glEnd() - - # update window - pygame.display.flip() - - # Send texture to spout... - # Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0); - spoutSender.SendTexture(textureStyleID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0) - # FPS = 1 / time to process loop - print("FPS: ", 1.0 / (time.time() - start_time)) - -if __name__ == '__main__': - main() diff --git a/Examples/spout_receiver_example.py b/Examples/spout_receiver_example.py deleted file mode 100644 index c63a0f0..0000000 --- a/Examples/spout_receiver_example.py +++ /dev/null @@ -1,127 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import argparse -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GLU import * - - -"""parsing and configuration""" -def parse_args(): - desc = "Spout for Python texture receiving example" - parser = argparse.ArgumentParser(description=desc) - - parser.add_argument('--spout_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the spout receiver') - - parser.add_argument('--spout_name', type=str, default='Composition - Resolume Arena', help='Spout receiving name - the name of the sender you want to receive') - - parser.add_argument('--window_size', nargs = 2, type=int, default=[640, 480], help='Width and height of the window') - - return parser.parse_args() - - -"""main""" -def main(): - - # parse arguments - args = parse_args() - - # window details - width = args.window_size[0] - height = args.window_size[1] - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout Receiver') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - - # OpenGL init - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glOrtho(0,width,height,0,1,-1) - glMatrixMode(GL_MODELVIEW) - glDisable(GL_DEPTH_TEST) - glClearColor(0.0,0.0,0.0,0.0) - glEnable(GL_TEXTURE_2D) - - # init spout receiver - receiverName = args.spout_name - spoutReceiverWidth = args.spout_size[0] - spoutReceiverHeight = args.spout_size[1] - # create spout receiver - spoutReceiver = SpoutSDK.SpoutReceiver() - - # Its signature in c++ looks like this: bool pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive); - spoutReceiver.pyCreateReceiver(receiverName,spoutReceiverWidth,spoutReceiverHeight, False) - - # create texture for spout receiver - textureReceiveID = glGenTextures(1) - - # initalise receiver texture - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - - # copy data into texture - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spoutReceiverWidth, spoutReceiverHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, None ) - glBindTexture(GL_TEXTURE_2D, 0) - - # loop for graph frame by frame - while(True): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - spoutReceiver.ReleaseReceiver() - pygame.quit() - quit() - - # receive texture - # Its signature in c++ looks like this: bool pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO); - spoutReceiver.pyReceiveTexture(receiverName, spoutReceiverWidth, spoutReceiverHeight, textureReceiveID, GL_TEXTURE_2D, False, 0) - - glBindTexture(GL_TEXTURE_2D, textureReceiveID) - - # copy pixel byte array from received texture - this example doesn't use it, but may be useful for those who do want pixel info - # data = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, outputType=None) #Using GL_RGB can use GL_RGBA - - # swap width and height data around due to oddness with glGetTextImage. http://permalink.gmane.org/gmane.comp.python.opengl.user/2423 - # data.shape = (data.shape[1], data.shape[0], data.shape[2]) - - # setup window to draw to screen - glActiveTexture(GL_TEXTURE0) - - # clean start - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) - # reset drawing perspective - glLoadIdentity() - - # draw texture on screen - # glPushMatrix() use these lines if you want to scale your received texture - # glScale(0.3, 0.3, 0.3) - glBegin(GL_QUADS) - - glTexCoord(0,0) - glVertex2f(0,0) - - glTexCoord(1,0) - glVertex2f(spoutReceiverWidth,0) - - glTexCoord(1,1) - glVertex2f(spoutReceiverWidth,spoutReceiverHeight) - - glTexCoord(0,1) - glVertex2f(0,spoutReceiverHeight) - - glEnd() - # glPopMatrix() make sure to pop your matrix if you're doing a scale - # update window - pygame.display.flip() - -if __name__ == '__main__': - main() diff --git a/Examples/spout_sender_example.py b/Examples/spout_sender_example.py deleted file mode 100644 index 892d73c..0000000 --- a/Examples/spout_sender_example.py +++ /dev/null @@ -1,133 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GLU import * - -verticies = ( - (1, -1, -1), - (1, 1, -1), - (-1, 1, -1), - (-1, -1, -1), - (1, -1, 1), - (1, 1, 1), - (-1, -1, 1), - (-1, 1, 1) - ) - -edges = ( - (0,1), - (0,3), - (0,4), - (2,1), - (2,3), - (2,7), - (6,3), - (6,4), - (6,7), - (5,1), - (5,4), - (5,7) - ) - - -def Cube(): - glBegin(GL_LINES) - for edge in edges: - for vertex in edge: - glVertex3fv(verticies[vertex]) - glEnd() - - -def main(): - - # window details - width = 800 - height = 600 - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout Python Sender') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) - - # OpenGL init - # setup OpenGL perspective - glMatrixMode(GL_PROJECTION) - gluPerspective(45, (display[0]/display[1]), 0.1, 50.0) - # setup default colours, blending modes, rotation and translation parameters - glMatrixMode(GL_MODELVIEW) - # reset the drawing perspective - glLoadIdentity() - # can disable depth buffer because we aren't dealing with multiple geometry in our scene - glDisable(GL_DEPTH_TEST) - glEnable(GL_ALPHA_TEST) - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(0.0,0.0,0.0,0.0) - glColor4f(1.0, 1.0, 1.0, 1.0); - glTranslatef(0,0, -5) - glRotatef(25, 2, 1, 0) - - # init spout sender - spoutSender = SpoutSDK.SpoutSender() - spoutSenderWidth = width - spoutSenderHeight = height - # Its signature in c++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); - spoutSender.CreateSender('Spout Python Sender', spoutSenderWidth, spoutSenderHeight, 0) - - # init spout sender texture ID - senderTextureID = glGenTextures(1) - - # initialise texture - glBindTexture(GL_TEXTURE_2D, senderTextureID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - # fill texture with blank data - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,spoutSenderWidth,spoutSenderHeight,0); - glBindTexture(GL_TEXTURE_2D, 0) - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - # setup frame - glActiveTexture(GL_TEXTURE0) - glClearColor(0.0,0.0,0.0,0.0) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # Perform a rotation and since we aren't resetting our perspective with glLoadIdentity, then each frame will perform a successive rotation on top of what we already see - glRotatef(1, 3, 1, 1) - - # draw cube - Cube() - - #bind our senderTexture and copy the window's contents into the texture - glBindTexture(GL_TEXTURE_2D, senderTextureID) - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,spoutSenderWidth,spoutSenderHeight,0); - glBindTexture(GL_TEXTURE_2D, 0) - - # send texture to Spout - # Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0); - spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, True, 0) - - # update display - pygame.display.flip() - - pygame.time.wait(10) - -main() - - - - - diff --git a/Examples/spout_webcam_sender_example.py b/Examples/spout_webcam_sender_example.py deleted file mode 100644 index ca854a9..0000000 --- a/Examples/spout_webcam_sender_example.py +++ /dev/null @@ -1,122 +0,0 @@ -# Add relative directory ../Library to import path, so we can import the SpoutSDK.pyd library. Feel free to remove these if you put the SpoutSDK.pyd file in the same directory as the python scripts. -import sys -sys.path.append('../Library') - -import argparse -import cv2 -import SpoutSDK -import pygame -from pygame.locals import * -from OpenGL.GL import * -from OpenGL.GLU import * - -"""parsing and configuration""" -def parse_args(): - desc = "Spout for Python webcam sender example" - parser = argparse.ArgumentParser(description=desc) - - parser.add_argument('--camSize', nargs = 2, type=int, default=[640, 480], help='File path of content image (notation in the paper : x)') - - parser.add_argument('--camID', type=int, default=1, help='Webcam Device ID)') - - return parser.parse_args() - - -"""main""" -def main(): - - # parse arguments - args = parse_args() - - # window details - width = args.camSize[0] - height = args.camSize[1] - display = (width,height) - - # window setup - pygame.init() - pygame.display.set_caption('Spout for Python Webcam Sender Example') - pygame.display.set_mode(display, DOUBLEBUF|OPENGL) - pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) - - # init capture & set size - cap = cv2.VideoCapture(args.camID) - cap.set(3, width) - cap.set(4, height) - - # OpenGL init - glMatrixMode(GL_PROJECTION) - glOrtho(0,width,height,0,1,-1) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - glDisable(GL_DEPTH_TEST) - glClearColor(0.0,0.0,0.0,0.0) - glEnable(GL_TEXTURE_2D) - - # init spout sender - spoutSender = SpoutSDK.SpoutSender() - spoutSenderWidth = width - spoutSenderHeight = height - # Its signature in c++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); - spoutSender.CreateSender('Spout for Python Webcam Sender Example', width, height, 0) - - # create texture id for use with Spout - senderTextureID = glGenTextures(1) - - # initalise our sender texture - glBindTexture(GL_TEXTURE_2D, senderTextureID) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) - glBindTexture(GL_TEXTURE_2D, 0) - - # loop - while(True): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - ret, frame = cap.read() - frame = cv2.flip(frame, 1 ) - frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - - # Copy the frame from the webcam into the sender texture - glBindTexture(GL_TEXTURE_2D, senderTextureID) - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, frame ) - - # Send texture to Spout - # Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0); - spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0) - - # Clear screen - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) - # reset the drawing perspective - glLoadIdentity() - - # Draw texture to screen - glBegin(GL_QUADS) - - glTexCoord(0,0) - glVertex2f(0,0) - - glTexCoord(1,0) - glVertex2f(width,0) - - glTexCoord(1,1) - glVertex2f(width,height) - - glTexCoord(0,1) - glVertex2f(0,height) - - glEnd() - - # update window - pygame.display.flip() - - # unbind our sender texture - glBindTexture(GL_TEXTURE_2D, 0) - -if __name__ == '__main__': - main() diff --git a/Images/neural style resolume.png b/Images/neural style resolume.png deleted file mode 100644 index b82d3a9..0000000 Binary files a/Images/neural style resolume.png and /dev/null differ diff --git a/Library/SpoutSDK.pyd b/Library/35/SpoutSDK.pyd old mode 100644 new mode 100755 similarity index 100% rename from Library/SpoutSDK.pyd rename to Library/35/SpoutSDK.pyd diff --git a/Library/36/SpoutSDK.pyd b/Library/36/SpoutSDK.pyd new file mode 100755 index 0000000..3e544a1 Binary files /dev/null and b/Library/36/SpoutSDK.pyd differ diff --git a/Library/37/SpoutSDK.pyd b/Library/37/SpoutSDK.pyd new file mode 100755 index 0000000..d1821d8 Binary files /dev/null and b/Library/37/SpoutSDK.pyd differ diff --git a/Library/Spout.py b/Library/Spout.py new file mode 100755 index 0000000..a515999 --- /dev/null +++ b/Library/Spout.py @@ -0,0 +1,249 @@ +import sys +import os + +sys.path.append('{}/Library/3{}'.format(os.getcwd(), sys.version_info[1])) + +import numpy as np +import argparse +import time +import SpoutSDK +import pygame +from pygame.locals import * +from OpenGL.GL import * +from OpenGL.GL.framebufferobjects import * +from OpenGL.GLU import * + +class Spout() : + """ + Spout class for python wrapper + """ + + def __init__( self, silent = False, width = 1280, height = 720, n_rec = 1, n_send = 1 ): + """ + Initialize spout object + Args: + silent: boolean, hide windows, default = False + width: window width, default = 1280 + height: window height, default = 720 + n_rec: number of receivers, default = 1 + n_send: number of sender, default = 1 + """ + + self.n_rec = n_rec + self.n_send = n_send + + self.width = width + self.height = height + self.silent = silent + self.display = ( self.width, self.height ) + + self.spoutReceiver = [None] * self.n_rec + self.receiverWidth = [None] * self.n_rec + self.receiverHeight = [None] * self.n_rec + self.textureReceiveID = [None] * self.n_rec + self.receiverName = [None] * self.n_rec + self.receiverType = [None] * self.n_rec + self.receiverDataType = [None] * self.n_rec + + self.spoutSender = [None] * self.n_send + self.textureSendID = [None] * self.n_send + self.senderWidth = [None] * self.n_send + self.senderHeight = [None] * self.n_send + self.senderType = [None] * self.n_send + self.senderDataType = [None] * self.n_send + self.senderName = [None] * self.n_send + + #window setup + pygame.init() + pygame.display.set_caption( 'Spout For Python' ) + pygame.display.set_mode( self.display, DOUBLEBUF|OPENGL ) + + # OpenGL init + glMatrixMode( GL_PROJECTION ) + glLoadIdentity() + glOrtho(0, self.width, self.height, 0, 1, -1 ) + glMatrixMode( GL_MODELVIEW ) + glDisable( GL_DEPTH_TEST ) + glClearColor( 0.0, 0.0, 0.0, 0.0) + glEnable( GL_TEXTURE_2D ) + + def createReceiver( self, name = 'input', type = GL_RGB, dataType = GL_UNSIGNED_BYTE , id = 0): + """ + Initialize spout receiver + Args: + name: receiver name, default = 'input' + type: texture type, default = GL_RGB, available = GL_RGBA, GL_RGB, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA + dataType: texture data type, default = GL_UNSIGNED_BYTE, available = GL_UNSIGNED_BYTE, GL_FLOAT + id: id of receiver if want multiple, default = 0 + """ + + self.receiverName[id] = name + self.receiverType[id] = type + self.receiverDataType[id] = dataType + + # init spout receiver + self.spoutReceiver[id] = SpoutSDK.SpoutReceiver() + + self.receiverWidth[id] = self.spoutReceiver[id].GetWidth( self.receiverName[id] ) + self.receiverHeight[id] = self.spoutReceiver[id].GetHeight( self.receiverName[id] ) + + # create spout receiver + # Its signature in c++ looks like this: bool pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive); + self.spoutReceiver[id].pyCreateReceiver( self.receiverName[id], self.receiverWidth[id], self.receiverHeight[id], False ) + # create textures for spout receiver and spout sender + self.textureReceiveID[id] = glGenTextures(1) + + # initalise receiver texture + glBindTexture( GL_TEXTURE_2D, self.textureReceiveID[id] ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) + + # copy data into texture + glTexImage2D( GL_TEXTURE_2D, 0, self.receiverType[id], self.receiverWidth[id], self.receiverHeight[id], 0, self.receiverType[id], self.receiverDataType[id], None ) + glBindTexture(GL_TEXTURE_2D, 0) + + return True + + def createSender(self, name = 'output', type = GL_RGB, dataType = GL_UNSIGNED_BYTE, id = 0): + """ + Initialize spout sender + Args: + name: receiver name, default = 'output' + type: texture type, default = GL_RGB, available = GL_RGBA, GL_RGB, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA + dataType: texture data type, default = GL_UNSIGNED_BYTE, available = GL_UNSIGNED_BYTE, GL_FLOAT + id: id of sender if want multiple, default = 0 + """ + + self.senderName[id] = name + self.senderWidth[id] = 0 + self.senderHeight[id] = 0 + self.senderType[id] = type + self.senderDataType[id] = dataType + # init spout sender + + self.spoutSender[id] = SpoutSDK.SpoutSender() + # Its signature in c++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); + self.spoutSender[id].CreateSender(self.senderName[id], self.width, self.height, 0) + # create textures for spout receiver and spout sender + self.textureSendID[id] = glGenTextures(1) + + def receive( self , id = 0): + """ + Receive texture + Args: + id: id of receiver if want multiple, default = 0 + """ + + # if textures sizes do not match recreate receiver + if self.receiverWidth[id] != self.spoutReceiver[id].GetWidth(self.receiverName[id]) or self.receiverHeight[id] != self.spoutReceiver[id].GetHeight(self.receiverName[id]): + + self.receiverWidth[id] = self.spoutReceiver[id].GetWidth( self.receiverName[id] ) + self.receiverHeight[id] = self.spoutReceiver[id].GetHeight( self.receiverName[id] ) + + self.spoutReceiver[id].pyCreateReceiver( self.receiverName[id], self.receiverWidth[id], self.receiverHeight[id], False ) + self.textureReceiveID[id] = glGenTextures(1) + + glBindTexture( GL_TEXTURE_2D, self.textureReceiveID[id] ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) + + glTexImage2D( GL_TEXTURE_2D, 0, self.receiverType[id], self.receiverWidth[id], self.receiverHeight[id], 0, self.receiverType[id], self.receiverDataType[id], None ) + glBindTexture(GL_TEXTURE_2D, 0) + + if self.spoutReceiver[id] != None and self.textureReceiveID[id] != None: + # receive texture + # Its signature in c++ looks like this: bool pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO); + self.spoutReceiver[id].pyReceiveTexture( self.receiverName[id], self.receiverWidth[id], self.receiverHeight[id], self.textureReceiveID[id].item(), GL_TEXTURE_2D, False, 0 ) + + glBindTexture( GL_TEXTURE_2D, self.textureReceiveID[id] ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) + # copy pixel byte array from received texture + data = glGetTexImage( GL_TEXTURE_2D, 0, self.receiverType[id], self.receiverDataType[id], outputType=None ) #Using GL_RGB can use GL_RGBA + glBindTexture( GL_TEXTURE_2D, 0 ) + # swap width and height data around due to oddness with glGetTextImage. http://permalink.gmane.org/gmane.comp.python.opengl.user/2423 + data.shape = (data.shape[1], data.shape[0], data.shape[2]) + + return data + + else: + return self.empty() + + def send(self, data, id = 0): + """ + Send texture + Args: + id: id of sender if want multiple, default = 0 + """ + + if data.size == 0: + data = self.empty() + else: + self.senderWidth[id] = data.shape[1] + self.senderHeight[id] = data.shape[0] + + if self.spoutSender[id] != None and self.textureSendID[id] != None: + + # setup the texture so we can load the output into it + glBindTexture( GL_TEXTURE_2D, self.textureSendID[id] ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) + # copy output into texture + glTexImage2D( GL_TEXTURE_2D, 0, self.senderType[id], self.senderWidth[id], self.senderHeight[id], 0, self.senderType[id], self.senderDataType[id], data ) + + # setup window to draw to screen + glActiveTexture( GL_TEXTURE0 ) + # clean start + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) + # reset drawing perspective + glLoadIdentity() + # draw texture on screen + glBegin( GL_QUADS ) + + glTexCoord( 0,0 ) + glVertex2f( 0,0 ) + + glTexCoord( 1,0 ) + glVertex2f(self.width,0) + + glTexCoord(1,1) + glVertex2f(self.width,self.height) + + glTexCoord(0,1) + glVertex2f(0,self.height) + + glEnd() + + if self.silent: + pygame.display.iconify() + + # update window + pygame.display.flip() + + self.spoutSender[id].SendTexture(self.textureSendID[id].item(), GL_TEXTURE_2D, self.senderWidth[id], self.senderHeight[id], False, 0) + + def check(self): + """ + Check on closed window + """ + for event in pygame.event.get(): + if event.type == pygame.QUIT: + for i in range(0,self.n_rec): + self.spoutReceiver[i].ReleaseReceiver() + pygame.quit() + quit() + + def empty(self): + """ + Create empty texture + """ + data = np.zeros((self.height,self.width,3)) + return data \ No newline at end of file diff --git a/README.md b/README.md index 75d84c6..47a8030 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,58 @@ # Spout for Python -A modified Spout library using Boost::Python to enable Spout texture sharing using Python. -![Spout for Python](https://raw.githubusercontent.com/spiraltechnica/Spout-for-Python/master/Images/neural%20style%20resolume.png) -This library is for use with Python 3.5 64bit. - -It was built against Boost 1.65 and Python 3.5.2-amd64 using Visual Studio 2015 on Windows 10 64bit - -The Visual Studio solution depends on: -- Boost being located in C:\Program Files\boost_1_65_0 and +Based on https://github.com/spiraltechnica/Spout-for-Python -- Python 3.5 64bit being located in %UserProfile%\AppData\Local\Programs\Python\Python35\include - -This modified library does not yet fully implement the functionality available in the SpoutSDK. +A modified Spout library using Boost::Python to enable Spout texture sharing using Python. +This library is for use with Python 3.5 / 3.6 / 3.7 64bit. Now it will automatically define python version and load appropriate file. ## Using the Library -The SpoutSDK.pyd library is located in the [Library/](Library/) folder of this repository. The example files are in the [Examples/](Examples/) folder. - -You shouldn't need to compile Boost or have Visual Studio installed to run these examples and integrate the library into your own Python projects - -And of course, if you don't have Spout installed, you'll definitely need to get it and install it. It's available at http://spout.zeal.co/ - -## Examples - - -Take a look in the [Examples/](Examples/) folder for a list of python scripts that can interface with the modified SpoutSDK.pyd library. - -The simplest example file is ```hello.py```. This merely attempts to import the library, create an instance of a Spout Sender, and call a function that returns text into the console. - -The example scripts ```spout_NST_receiver.py``` and ```spout_NST_sender_receiver.py``` will not run by themselves, because they are designed to work with Tensorflow Fast Style Transfer, located at https://github.com/hwalsuklee/tensorflow-fast-style-transfer - -### Running the Examples - -A number of the examples will require libraries not in the base Python 3.5 install. That base install is available at https://www.python.org/downloads/release/python-352/ - -You'll need -- numpy-1.13.1+mkl-cp35-cp35m-win_amd64.whl -- opencv_python-3.3.0-cp35-cp35m-win_amd64.whl -- pygame-1.9.3-cp35-cp35m-win_amd64.whl - -From the Unofficial Windows Binaries for Python Extension Packages at http://www.lfd.uci.edu/~gohlke/pythonlibs/ - -Install them using the pip3 manager that comes with Python 3.5, using the ```pip install ``` command from the command line. - -In addition to the aforementioned packages, you'll need PyOpenGL from the pip default repositories: -- Install using ```pip install PyOpenGL``` command. The version I'm using is PyOpenGL 3.1.0 -- It would be also worth installing Pillow with ```pip install Pillow```. I'm using Pillow 4.2.1 - -## Building Boost -- Download the Boost 1.65 source for windows from http://www.boost.org/users/history/version_1_65_0.html -- Extract to C:\Program Files\boost_1_65_0 -- Open an Administrative access Command Prompt (right click on Command Prompt and Run As Administrator) -- cd into C:\Program Files\boost_1_65_0 -- Type ```boostrap.bat``` and run the command -- Now run ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.0 --threading=multi --runtime-link=shared --variant=debug``` - -This will take some time. Once it's complete run -- ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.0 --threading=multi --runtime-link=shared --variant=release``` - -Which will also take some time. However, it should say it is successfully built at the end and give you locations for linker library include paths and compiler include paths. - -## Building the DLL -With Boost and Python installed you should now be able to use Visual Studio 2015 and build the ```SpoutSDK.dll``` for 64bit architecture in Debug and Release modes. In order to interface the dll with Python, rename the dll from ```SpoutSDK.dll``` to ```SpoutSDK.pyd```. +Watch video use/demo > +[![](http://img.youtube.com/vi/CmI4zwSAajw/0.jpg)](http://www.youtube.com/watch?v=CmI4zwSAajw "Spout for Python") + +```python test.py``` +or just check sample code in the test.py +``` +# import library +from Library.Spout import Spout + +def main() : + # create spout object + spout = Spout(silent = True) + # create receiver + spout.createReceiver('input') + # create sender + spout.createSender('output') + + while True : + # check on exit + spout.check() + # receive data + data = spout.receive() + # send data + spout.send(data) + +if __name__ == "__main__": + main() +``` + +If want multiple receivers/senders, check ```test_mult.py``` + +## Parameters +Parameters and arguments for sender and receiver can be checked in the ```Library/Spout.py``` + +## Requirements + +``` +pip install -r requirements.txt +``` + +- pygame +- pyopengl + +## Additional +* Allow multiple receivers senders +* Now it can be used as any python library, just few lines of code +* Automatically define the size of receiver and data to send +* Can change receiver size on the go +* Support different receiver/sender imageFormat/type diff --git a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj index 984c0ed..43420fd 100644 --- a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj +++ b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,33 +22,33 @@ {9E8255CD-175A-4421-9B0D-F634E889B46B} Win32Proj SpoutSDK - 8.1 + 10.0.18362.0 SpoutSDK DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode @@ -145,7 +145,7 @@ true NDEBUG;_WINDOWS;_USRDLL;SPOUTFORPYTHON_EXPORTS;%(PreprocessorDefinitions) true - %UserProfile%\AppData\Local\Programs\Python\Python35\include;C:\Program Files\boost_1_65_0;%(AdditionalIncludeDirectories) + C:\Users\Vasily\.conda\envs\tf3.6\include;C:\Program Files\boost_1_72_0;%(AdditionalIncludeDirectories) Windows @@ -153,7 +153,7 @@ true true opengl32.lib;%(AdditionalDependencies) - C:\Program Files\boost_1_65_0\stage\x64\lib;C:\Program Files\boost_1_65_0\;%UserProfile%\AppData\Local\Programs\Python\Python35\libs;%(AdditionalLibraryDirectories) + C:\Program Files\boost_1_72_0\stage\lib;C:\Users\Vasily\.conda\envs\tf3.6\libs;%(AdditionalLibraryDirectories) diff --git a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters index 866cbe4..bdabc98 100644 --- a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters +++ b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters @@ -15,81 +15,81 @@ - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..77f62f1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pygame +pyopengl +numpy \ No newline at end of file diff --git a/test.py b/test.py new file mode 100755 index 0000000..ac19688 --- /dev/null +++ b/test.py @@ -0,0 +1,22 @@ +# load library +from Library.Spout import Spout + +def main() : + # create spout object + spout = Spout(silent = False) + # create receiver + spout.createReceiver('input') + # create sender + spout.createSender('output') + + while True : + + # check on close window + spout.check() + # receive data + data = spout.receive() + # send data + spout.send(data) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/test.toe b/test.toe new file mode 100755 index 0000000..6504b0f Binary files /dev/null and b/test.toe differ diff --git a/test_mult.py b/test_mult.py new file mode 100755 index 0000000..6d94cb2 --- /dev/null +++ b/test_mult.py @@ -0,0 +1,38 @@ +# load library +from Library.Spout import Spout + +import random + +def main() : + # create spout object + spout = Spout(silent = True, n_rec = 3, n_send = 3) + # create receiver + spout.createReceiver('input1', id = 0) + spout.createReceiver('input2', id = 1) + spout.createReceiver('input3', id = 2) + # create sender + spout.createSender('output1', id = 0) + spout.createSender('output2', id = 1) + spout.createSender('output3', id = 2) + + while True : + + # check on close window + spout.check() + # receive data + data = spout.receive(id = 0) + data1 = spout.receive(id = 1) + data2 = spout.receive(id = 2) + # send data + if random.random() > .9: + spout.send(data1) + spout.send(data, 1) + else: + spout.send(data) + spout.send(data1, 1) + + spout.send(data2, id = 2) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/test_mult.toe b/test_mult.toe new file mode 100755 index 0000000..827062d Binary files /dev/null and b/test_mult.toe differ