View Full Version : FLuaG - OpenGL rendering on video stream
Youka
9th July 2011, 05:49
After some time of karaoke effect making, tools like VSFilter (http://avisynth.org.ru/docs/english/externalfilters/vsfilter.htm) (WinGDI) and Overlua (http://forums.animesuki.com/showthread.php?t=52757) (Cairo) weren't enough anymore, so the next step should be an OpenGL filter for Avisynth - and here it is.
FLuaG calls scripts in scripting language Lua (http://en.wikipedia.org/wiki/Lua_%28programming_language%29) to render with OpenGL (http://en.wikipedia.org/wiki/OpenGL) on video frames or modify audio data.
Downloads:
Github (https://github.com/Youka/FLuaG)
Usage:
FLuaG(clip c, string video = void, string audio = void, bool onscreen = false, bool samples32 = false, string userdata = void)
c: Clip with video and/or audio.
video: Lua script, extended with OpenGL and other utility functions, for working on video frames.
audio: Lua script for working on audio samples.
onscreen: OpenGL render context visible? (needed for graphic cards which don't support window offscreen rendering)
samples32: Samples with size of 32 bit instead of 16 bit?
userdata: AVS variable names for sending data to Lua.
Video presentation (http://www.youtube.com/watch?v=mWKuA1V_Yug)
Todo:
Lua functions
FFT
TGA loading & saving
Outline path utilities
Others
Examples: advanced karaoke and drawing
Documentation: extended + german version
Changelog:
Version 0.5 (11.12.2011):
Userdata (AVS variables to Lua)
Option for 32 bit samples
More utility functions (math and print path)
Version 0.4 (24.11.2011):
New process structure (similar to Avisynth Filter SDK)
OpenGL 2.1 support
Audio access
various fixes
Version 0.3 (13.07.2011):
Just one OpenGL context for the whole progress (frame-wise before)
flDrawPath's internal tesselation combine function call doesn't change color to black/alpha=0 if there're no alternative colors
Version 0.2 (09.07.2011):
Faster frame processing
Compiled for .NET 3.5
Function fixes: math.on_line, math.in_triangle, glReadPixels, flDrawPath
Color and pixel data from range 0-255 changed to 0-1
OpenGL 1.3
tin3tin
9th July 2011, 08:27
Thank you. Looking forward to tinker with it. :)
[the download links seems dead atm.]
Youka
9th July 2011, 09:33
Fixed.
Gavino
9th July 2011, 10:31
Thanks for the new version, Youka.
Looking through the source code, I've spotted a minor efficiency glitch in GLWindow.cpp:
valid = wglChoosePixelFormatARB(hdc, iAttributes, fAttributes, 1, &pformat, &num);
if(!(valid && num >= 1))
//8x AA
iAttributes[23] = 8;
valid = wglChoosePixelFormatARB(hdc, iAttributes, fAttributes, 1, &pformat, &num);
if(!(valid && num >= 1))
//4x AA
iAttributes[23] = 4;
valid = wglChoosePixelFormatARB(hdc, iAttributes, fAttributes, 1, &pformat, &num);
if(!(valid && num >= 1))
//2x AA
iAttributes[23] = 2;
wglChoosePixelFormatARB(hdc, iAttributes, fAttributes, 1, &pformat, &num);
Even if the first call to wglChoosePixelFormatARB (for 16x AA) succeeds, it is still called a further three times, because of a lack of {} on the 'if' statements. The indentation doesn't match what the code actually does.
Youka
9th July 2011, 12:15
Arg, you're right. Tried in past with a computer without graphic card, so i didn't noticed it + forgot in my last check the GLWindow class ^^"
Will add brackets immediatly!
Thx for reporting.
Youka
13th July 2011, 15:37
Version 0.3 released.
There're just 2 small changes.
If internal combine function of tesselation of flDrawPath was called without colors in given path table, it changed color to black/alpha=0 for following triangles. Fixed now, that color doesn't change in this case.
OpenGL context was recreated for every frame. Now it creates one context for whole progress. Reuse of textures, display lists, etc. possible -> faster processing.
Because of the second change you can do a lot of shit now if you forget to disable something. See internal frame initialization and understand the problem:glMatrixMode(GL_TEXTURE)
glLoadIdentity()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glViewport( 0, 0, flGetVideoWidth(), flGetVideoHeight() )
glClearColor(0, 0, 0, 0)
glClearDepth(1.0)
glClearStencil(0)
glClearAccum(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT)
local frame = --Gets video frame pixels
glDepthMask(false)
glDrawPixels(flGetVideoWidth(), flGetVideoHeight(), GL_RGBA, frame)
glDepthMask(true)
--Calls registered functions from user in right order!!!
frame = glReadPixels(0, 0, flGetVideoWidth(), flGetVideoHeight(), GL_RGBA)
--Sets video frame pixels (frame)But it's much faster than before :)
Added a small example how to make karaoke effects (http://youka.xobor.de/t97f12-Download.html).
Advanced creations of me i cannot post here or upload to YT regrettably because of music and video material :rolleyes:
Documentation just reaches until OpenGL 1.1, but 1.3 is available.
Documentation is more work than the source, so it will take some time, but will continue it.
Because of the plan to allow audio access:
Video and audio runs in 2 threads, so i cannot bring it together in one function. Another developer used ffmpeg for loading audio data separatly... will think about it.
Gavino
13th July 2011, 17:40
Version 0.3 released.
OpenGL context was recreated for every frame. Now it creates one context for whole progress.
The code that does this (in GLWindow::GLWindow) will only create the context if running on an OpenGL implementation that supports multisampling.
if(CheckMultisampling())
{
...
//Set pixel format
SetPixelFormat(hdc, pformat, &pfd);
//My OpenGL context to current window
cx = wglCreateContext(hdc);
}
Shouldn't the call to wglCreateContext be outside the conditional part?
Youka
14th July 2011, 04:39
The code that does this (in GLWindow::GLWindow) will only create the context if running on an OpenGL implementation that supports multisampling.
if(CheckMultisampling())
{
...
//Set pixel format
SetPixelFormat(hdc, pformat, &pfd);
//My OpenGL context to current window
cx = wglCreateContext(hdc);
}
Shouldn't the call to wglCreateContext be outside the conditional part?
Most graphic card's today have OpenGL >1.3 and are supporting multisampling, so it's not such bad, but will change it.
(always the GLWindow part, ~grrr~)
Gavino
14th July 2011, 10:15
Most graphic card's today have OpenGL >1.3 and are supporting multisampling, so it's not such bad
True, but as the previous code worked without multisampling capability, you might as well continue to support this.
Incidentally, the reason I was so quick to spot this issue (and the previous one) is that I am working on something similar (without Lua) for my own purposes, and I had already made a similar change (create the context only once) in my own code.
Other points which you might find helpful:
- Some graphics cards/drivers (like my laptop!) will not render to an invisible window. You can use a pbuffer (http://www.opengl.org/registry/specs/ARB/wgl_pbuffer.txt) context (where supported) to avoid this problem.
- Instead of copying to and from an intermediate buffer when passing pixel data between Avisynth and OpenGL, you can use glPixelStorei(GL_[UN]PACK_ROW_LENGTH, pitch/4) with a format of GL_BGRA_EXT in glReadPixels and glDrawPixels. (This probably makes your PixelHandler class redundant.)
Youka
14th July 2011, 11:24
Incidentally, the reason I was so quick to spot this issue (and the previous one) is that I am working on something similar (without Lua) for my own purposes, and I had already made a similar change (create the context only once) in my own code.It's mysterious that for every frame in avisynth the same context has to be make the current again. You know why?
Other points which you might find helpful:
- Some graphics cards/drivers (like my laptop!) will not render to an invisible window. You can use a pbuffer (http://www.opengl.org/registry/specs/ARB/wgl_pbuffer.txt) context (where supported) to avoid this problem.Never heard of such a case. Know PBOs but weren't needed until know (slower than standard). Maybe add to next version with VBOs.
- Instead of copying to and from an intermediate buffer when passing pixel data between Avisynth and OpenGL, you can use glPixelStorei(GL_[UN]PACK_ROW_LENGTH, pitch/4) with a format of GL_BGRA_EXT in glReadPixels and glDrawPixels. (This probably makes your PixelHandler class redundant.)The BGRA format is an official part of OpenGL 1.2, so i'd chosen the way by swapping RGBA because of my old PC (without graphic card) didn't support it + won't become much faster.
Gavino
14th July 2011, 11:49
It's mysterious that for every frame in avisynth the same context has to be make the current again. You know why?
I found that this was not necessary, per se. Perhaps something in the Lua part (which I don't have) screws with the context? However, in order to support multiple calls to FLuaG in the same script, it would be necessary to re-establish the current context for each frame anyway.
Never heard of such a case.
The OpenGL spec allows rendering of non-visible pixels to be skipped (the "pixel ownership test"). And I found I had to change to using a pbuffer to see anything on my laptop (NVidia GeForce FX Go5200).
Gavino
19th July 2011, 11:54
It's mysterious that for every frame in avisynth the same context has to be make the current again.
Revisiting this, it occurs to me that the reason you are seeing this could be multithreading. The OpenGL context is specific to a single thread, but depending on your encoder (or if using a MT version of Avisynth), GetFrame() may be called from a different thread than the constructor.
EmuAGR
12th November 2011, 13:23
FLuaG x64 v0.5
Updated v0.5 x64 build: FLuaG64.dll (http://www.mediafire.com/?1n60be5k0zgmud8)
v0.4
FLuaG64.dll (http://www.mediafire.com/?aihcn9d9m0flbh7)
v0.3
I've compiled FLuaG v0.3 for AviSynth64 (MSVC++ 10): FLuaG64.dll (http://www.mediafire.com/?3ce4m759a3v18cr)
The source code is almost the same, just converted inline ASM to intrinsic functions for MSVC to compile fine in x64. Replace PixelHandler.h (http://www.mediafire.com/?4b7cwga1y1bo1l1) in the Source folder and libs\Lua_5.1.4_static.lib with a suitable Win64 VC lib from here (http://sourceforge.net/projects/luabinaries/files/5.1.4/Windows%20Libraries): Lib for MVSC++ 10 (http://sourceforge.net/projects/luabinaries/files/5.1.4/Windows%20Libraries/lua5_1_4_Win64_vc10_lib.zip/download)
Youka
22nd November 2011, 13:06
(Release next)
Büke
22nd November 2011, 21:50
You are awesome Youka! This opens worlds of possibilities for AviSynth.
I am especially looking forward to fragment shader support.
Multiple inputs would be nice too, but I imagine, one workaround would be StackVertical() for video...
Youka
24th November 2011, 08:07
FLuaG 0.4 release (see first post (http://forum.doom9.org/showpost.php?p=1512422&postcount=1)).
Gavino
24th November 2011, 12:03
Thanks for the update, Youka.
Version 0.4 (24.11.2011):
New process structure (similar to Avisynth Filter SDK)
Does this mean scripts written for the earlier version will no longer work and must be adapted for the new interface?
Youka
24th November 2011, 12:26
Regrettably yes, but it's not really work to change this and i will not change it in future anymore.
tin3tin
25th November 2011, 19:50
Truely great work Youka! Very nice with all the included examples, but why did you leave out your previous 3D OpenGl examples?
I've got to investigate further myself, but is it possible in this version to make video 3D transitions over a video background?
Youka
26th November 2011, 13:09
My old examples are all rewritten and included into the new ones, so there's nothing missing except the video cube.
Making a video 3D transition over a video background won't be a problem but it might be you mean working with more than one video stream. That will come with clip array input to FLuaG soon, but for now you have to use some tricks.
Multiple inputs would be nice too, but I imagine, one workaround would be StackVertical() for video...
tin3tin
26th November 2011, 21:05
That will come with clip array input to FLuaG soon
That's good news. Thank you for all the time you put into this. :)
Gavino
27th November 2011, 13:58
Making a video 3D transition over a video background won't be a problem but it might be you mean working with more than one video stream. That will come with clip array input to FLuaG soon, but for now you have to use some tricks.
In order to write generic transition functions (for example), the ability to pass parameters from the Avisynth script would also be useful (as I suggested here and explained here).
Youka
27th November 2011, 14:17
Don't worry, i remembered your suggestion.
Next weekend i'm seriously planning version 0.5 and update first post (main item will be multiple input).
EmuAGR
28th November 2011, 01:35
FLuaG x64 v0.4: http://forum.doom9.org/showthread.php?p=1538264#post1538264
Youka
11th December 2011, 20:50
FLuaG version 0.5 released (http://forum.doom9.org/showthread.php?p=1512422#post1512422).
Main change is the userdata option for access on multiple clips, so it's possible now to use it for professional video editing like some commercial software.
Youka
14th December 2011, 01:45
Video room (http://www.youtube.com/watch?v=iMJ_NZDgyo0)
Note: All clip versions were made with FLuaG too.
room.avsImport("..\..\Head.avs")
blur = DirectShowSource("blur.mkv")
edgedetect = DirectShowSource("edgedetect.mkv")
numbers = DirectShowSource("numbers.mkv")
soundwave = DirectShowSource("soundwave.mkv").Trim(0,304)
FLuaG(soundwave, video = "room.lua", userdata = "blur edgedetect numbers")
room.lua--Init 3D room with perspective view
flInit3D(90, VIDEO_WIDTH/VIDEO_HEIGHT, 0.01, 10)
--Camera
gluLookAt(0, 0, 1, 0, 0, -1, 0, 1, 0)
--Face culling
glEnable(GL_CULL_FACE)
glFrontFace(GL_CW)
glCullFace(GL_BACK)
--Light + material
glLightModel(GL_LIGHT_MODEL_AMBIENT, {0, 0, 0, 1})
glLight(GL_LIGHT0, GL_AMBIENT, {0.1, 0.1, 0.1, 1})
glLight(GL_LIGHT0, GL_DIFFUSE, {1, 1, 1, 1})
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
--Texture
local tex = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, tex[1])
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
--Render objects
local quad = gluNewQuadric()
local wall = glGenLists(1)
do
local function rect_splitted(x1, y1, x2, y2, parts)
local x_step = (x2-x1) / parts
local y_step = (y2-y1) / parts
for y=1, parts do
for x=1, parts do
glTexCoord((x-1) / parts, y - (y-1) / parts)
glVertex(x1 + (x-1) * x_step, y1 + (y-1) * y_step)
glTexCoord(x / parts, y - (y-1) / parts)
glVertex(x1 + x * x_step, y1 + (y-1) * y_step)
glTexCoord(x / parts, y - y / parts)
glVertex(x1 + x * x_step, y1 + y * y_step)
glTexCoord((x-1) / parts, y - y / parts)
glVertex(x1 + (x-1) * x_step, y1 + y * y_step)
end
end
end
glNewList(wall, GL_COMPILE)
glNormal(0, 0, 1)
glBegin(GL_QUADS)
rect_splitted(-1, 1, 1, -1, 30)
glEnd()
glEndList()
end
--Display
function GetFrame(frame_index, frame_time)
--Clear room
glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT)
--Moving view
glPushMatrix()
glRotate(frame_index, 0, 1, 0)
--Set light
glPushMatrix()
glTranslate(0, 0.8, -0.2)
glColor(1, 1, 0)
gluSphere(quad, 0.03, 20, 20)
glLight(GL_LIGHT0, GL_POSITION, {0, 0, 0, 1})
glPopMatrix()
glEnable(GL_LIGHTING)
--Walls
glColor(1, 1, 1)
glEnable(GL_TEXTURE_2D)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VIDEO_WIDTH, VIDEO_HEIGHT, 0, GL_RGBA, LoadFrame()) --Back
glPushMatrix()
glTranslate(0, 0, -1)
glCallList(wall)
glPopMatrix()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, USERDATA[1]:Info().width, USERDATA[1]:Info().height, 0, GL_RGBA, USERDATA[1]:LoadFrame(frame_index)) --Front
glPushMatrix()
glTranslate(0, 0, 1)
glRotate(180, 0, 1, 0)
glCallList(wall)
glPopMatrix()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, USERDATA[2]:Info().width, USERDATA[2]:Info().height, 0, GL_RGBA, USERDATA[2]:LoadFrame(frame_index)) --Left
glPushMatrix()
glTranslate(-1, 0, 0)
glRotate(90, 0, 1, 0)
glCallList(wall)
glPopMatrix()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, USERDATA[3]:Info().width, USERDATA[3]:Info().height, 0, GL_RGBA, USERDATA[3]:LoadFrame(frame_index)) --Right
glPushMatrix()
glTranslate(1, 0, 0)
glRotate(-90, 0, 1, 0)
glCallList(wall)
glPopMatrix()
glDisable(GL_TEXTURE_2D)
glPushMatrix() --Floor
glTranslate(0, -1, 0)
glRotate(-90, 1, 0, 0)
glCallList(wall)
glPopMatrix()
glPushMatrix() --Ceiling
glTranslate(0, 1, 0)
glRotate(90, 1, 0, 0)
glCallList(wall)
glPopMatrix()
--Draw to frame
glDisable(GL_LIGHTING)
glPopMatrix()
SaveFrameFromContext()
end
EmuAGR
14th December 2011, 21:55
FLuaG x64 v0.5: http://forum.doom9.org/showthread.php?p=1538264#post1538264
I'm getting used to compile this filter, maybe I'll be faster next time. ;)
Youka
1st January 2012, 16:10
See first (http://forum.doom9.org/showthread.php?t=161852) post:Video presentation (http://www.youtube.com/watch?v=mWKuA1V_Yug)Todo:
Lua functions
FFT
TGA loading & saving
Outline path utilities
Others
Examples: advanced karaoke and drawing
Documentation: extended + german version
tin3tin
2nd January 2012, 21:13
Wow. It must have been quite an amount of time you have spend on this. Thank you.
I hope that I some day will figure out how to do video transitions with it. :) I did it once in this (http://www.autoitscript.com/forum/topic/37385-opengl-plugin-update-20070831/) OpenGL AutoIt plugin. There are some nice examples and a manual. Maybe the commands aren't that different and those examples could be usefull in FLuaG too?
Btw. maybe you could change the path in 'Head.avs' to: LoadPlugin("..\..\Data\FLuaG.dll")?
Youka
3rd January 2012, 01:20
Btw. maybe you could change the path in 'Head.avs' to: LoadPlugin("..\..\Data\FLuaG.dll")?You mean LoadPlugin("..\data\FLuaG.dll"). Doesn't work (for me), because LoadPlugin just accepts the complete file path.
I did it once in this (http://www.autoitscript.com/forum/topic/37385-opengl-plugin-update-20070831/) OpenGL AutoIt plugin. There are some nice examples and a manual. Maybe the commands aren't that different and those examples could be usefull in FLuaG too?For FLuaG everyone can look for the mass of OpenGL tutorials on the web (excluding window initialization, isn't needed in FLuaG) and just write it in Lua, so there are tutorials.
Seems it's needed to include OpenGL & Lua teaching into FLuaG. When i have more time, i will create a video tutorial step-by-step.
Vol666
1st February 2012, 01:09
HI Youka
I want to set png logo on the video with Fade IO effect and the opportunity to set start time(frame) , duration and end frame.
Can you tell how should be look like the script with the FluaG?
Youka
1st February 2012, 06:16
logo.png
logo.avs
#LoadPlugin("...\FLuaG.dll")
#LOAD YOUR VIDEO
FLuaG(video = "logo.lua")
logo.lua
--Load logo into texture memory
local image = flLoadPNG("logo.png")
glBindTexture(GL_TEXTURE_2D, glGenTextures(1)[1])
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, image)
--Set OpenGL matrices for 2D rendering
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, VIDEO_WIDTH, VIDEO_HEIGHT, 0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
--Enable overlays with transparency
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
--Define fade times
local start = 0
local ends = 100
local infade = 30
local outfade = 30
--Set position
glTranslate(100, 100, 0)
--Rendering
function GetFrame(frame_index, frame_time)
--Limit rendering to wished frame range
if frame_index >= start and frame_index <= ends then
--Transfer clip frame to OpenGL framebuffer
LoadFrameToContext()
--Infade transparency
if frame_index <= start + infade then
local pct = 1 - ((start + infade - frame_index) / infade)
glColor(1, 1, 1, pct)
--Outfade transparency
elseif frame_index >= ends - outfade then
local pct = (ends - frame_index) / outfade
glColor(1, 1, 1, pct)
--Opaque
else
glColor(1, 1, 1, 1)
end
--Draw texture
glEnable(GL_TEXTURE_2D)
glBegin(GL_QUADS)
glTexCoord(0, 0); glVertex(0, 0)
glTexCoord(1, 0); glVertex(image.width, 0)
glTexCoord(1, 1); glVertex(image.width, image.height)
glTexCoord(0, 1); glVertex(0, image.height)
glEnd()
glDisable(GL_TEXTURE_2D)
--Transfer OpenGL framebuffer back to clip frame
SaveFrameFromContext()
end
end
Nevilne
1st February 2012, 13:41
Is it possible to call nvidia fxaa with fluag?
Youka
1st February 2012, 14:45
FLuaG supports OpenGL 2.1 + framebuffer + imaging, but FXAA is new, so the answer is no.
You can write the algorithm by your own as pixel shader. Read the whitepaper (http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf) of nvidia?
Youka
18th May 2012, 00:34
Currently i'm writing on a scenegraph-like engine for easier usage of FLuaG. It's just a test for me, but maybe it'll help less experienced, lazy programmers to create nice animations in Avisynth.
--Include engine
dofile("Scenegraph.lua")
--Create scene structure
local scene = GLScene(0, 0, VIDEO_WIDTH, VIDEO_HEIGHT)
local light_node = GLNode()
local text_node = GLNode()
local cube_node = GLNode()
local image_node = GLNode()
--Create scene objects
local cam = GLCamera("3D", 1000, 1)
local light = GLLight({0,100,300, 1})
local text_position = GLTransformation():translate(500,100,0)
local text_color = GLColor(1, 0.5, 0)
local text = GLText("Hello World!", "Arial", 80, true, true, 20)
local cube_rotation = GLTransformation()
local cube_position = GLTransformation():translate(300,200,0)
local cube_part1 = GLObject("Triangle fan", {
vertices = {
{-100,100,-100}, --Left-bottom-back
{-100,-100,-100}, --Left-top-back
{-100,-100,100}, --Left-top-front
{-100,100,100}, --Left-bottom-front
{100,100,100}, --Right-bottom-front
{100,100,-100}, --Right-bottom-back
{100,-100,-100}, --Right-top-back
{-100,-100,-100} --Left-top-back
},
colors = {
{0,0,1}, --Left-bottom-back: blue
{0,1,0} --Rest: green
}
})
local cube_part2 = GLObject("Triangle fan", {
vertices = {
{100,-100,100}, --Right-top-front
{-100,-100,100}, --Left-top-front
{-100,100,100}, --Left-bottom-front
{100,100,100}, --Right-bottom-front
{100,100,-100}, --Right-bottom-back
{100,-100,-100}, --Right-top-back
{-100,-100,-100}, --Left-top-back
{-100,-100,100} --Left-top-front
},
colors = {
{1,0,0}, --Right-top-front: red
{0,1,0} --Rest: green
}
})
local panel_texture = GLTexture("firefox.png")
local panel_position = GLTransformation()
local panel = GLObject("Quads", {
vertices = {
{0,0},
{panel_texture:getwidth(),0},
{panel_texture:getwidth(), panel_texture:getheight()},
{0, panel_texture:getheight()}
},
tex_coords = {
{0,0},
{1,0},
{1,1},
{0,1}
}
})
--Build scene
scene:setcamera(cam)
scene:attach(image_node, "image")
scene:attach(cube_node, "cube")
scene:attach(light_node, "light")
image_node:attach(panel_position, "position")
image_node:attach(panel, "image")
panel:bindtexture(panel_texture)
cube_node:attach(cube_rotation, "transform_level2")
cube_node:attach(cube_position, "transform_level1")
cube_node:attach(cube_part1, "part1")
cube_node:attach(cube_part2, "part2")
light_node:attach(light, "light")
light_node:attach(text_node, "text")
text_node:attach(text_color, "color")
text_node:attach(text_position, "position")
text_node:attach(text, "text")
--Into render loop
VideoFilter(
function(frame_index, frame_time)
--Update scene objects
cube_rotation:reset():rotate(frame_index, frame_index, 0)
local pos = light:setposition({0,0,0,0})
pos[1] = frame_index * 5
light:setposition(pos)
panel_position:reset():translate(frame_index * 4,300,0)
--Render whole scene
scene:render()
end
)
http://img98.imageshack.us/img98/6205/testavssnapshot00042012.jpg
Youka
21st May 2012, 12:19
FLuaG on Github (https://github.com/Youka/FLuaG) now.
tin3tin
23rd May 2012, 06:01
Good to hear that you're making progress. :)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.