pouët.net

Polydraw

Polydraw
A opengl scripting tool

released on 2th january 2010

Some words about it
-------------------

I started this project two years ago, during winter 2007. I always dreamed about a tool that allow me to directly type opengl commands to try things without having to use a compiler. Same for pixel shaders. At that time I was really bored to have to start VC6, then download a opengl framework and spent time with libraries and linker errors in order to try something. Worst comes with pixel shaders and vertex shaders were intial framework is even bigger and debugging them is quite painful. 

Basically i needed this : 

- A script interpreter, fast enough to make opengl calls in realtime (something that runs at 8 fps for drawing a simple 3d cube will be totally useless)

- A interface that allow to type stuff in a window and have a quick preview of the result in another.

Unfortunaly the amount of work needed to write a code interpreter, debug it, and link all the stuff with opengl seems to be *enormous*. A that time I dont wanted to spent 6-12 months to develop a tool like this. 

Thats the reason i decided use the eval library written by Ken Silverman (http://advsys.net/ken) for the scripting part. This allow me to save a lot of time. The EVAL library is something really nice to use, fast and realiable.

In a few days, I had a tool fully working with almost all features I wanted. I use it for some my projects in the past and now I have decided to share it with the demoscene community. 

I have decided to provide the full source code (at least for the opengl/gui part). You can use this program and its source as you want as long as you respect two things:
1. You redistribute it free of charge (you are not allowed to modify/recompile this program and redistribute it as a commercial app).
2. You give me credit (adding a link to polydraw pouet page in readme.txt or my name/email should be enough) 

This demotool is provided "as is". I am not going to give support or implement new features on request. I am not responsible if it damages anything on your machine or if it make you lose data.


Some stuff I admit :

- the tool lacks of a proper UI interface. I know it could be a lot better, with a MDI interface, nice toolbars and all that stuff, but like said before I started this project for myself first and wanted quick results. Since source code is provided, someone can port this to a .NET winform platform or whatever he wanted.

- source code is really messy. I code this in a hurry and i first wanted results. I know some parts could be rewritten to be more efficient, use better naming convention, etc... I provide code so you can make changes if wanted or see how its done (eg: if you want to make same kind tool using this interpreter). I think it is better than dont releasing any source code at all with saying its "too messy" as an excuse.

Also :
I provided a series of samples. Theses are some stuff I have writted when having some free time. You can easily try them with clicking on render window then press 'L' then choosing the appropriate file.  Like source this is sometimes quite messy. Anyway, this provide a good way to see what this demotool is able to do.


I hope it will help some guys in 1k/4k intro development in and give some new ideas.
I like to know if this program is helpful for someone or if you make anything interesting with this.


Tigrou (tigrou.ind@gmail.com)

--------------------------------------------------------------

   Quick manual
--------------------------------------------------------------



Commands : (click on render window first, to make sure it have focus)
=========

L key : load project
S key : save project
ESC key : quickly exit program (usefull when program is trapped in a dead loop and consume most computer ressources, making alt-f4 or ctrl-alt-delete uneffective...)

Interface :
==========

the interface divided in six parts :

1. opengl render

   here you can see what you are doing :D

2. main code

   This code executed at each opengl frame. 

   Here is a list of available opengl commands (i dont give descriptions for basic ogl commands since you are supposed to know them) :

   glvertex

   glcolor

   glbegin 
      note: there is no constants so you have to enter the number directly 
      ex : glbegin(6) for glbegin(GL_QUADS);
   glend

   gltranslate

   glrotate

   glpushmatrix

   glpopmatrix

   glscale

   gltextcoord

   glcapture
      this allow to render a scene into a texture easily. 
      they are 4 textures available. first start at 0
      what glcapture() do is to prepare scene projection settings
      in order to render it to a texture
      ex: 
      glcapture()
      //draw some stuff
      glendcapture(0) //copy that stuff into texture 0 and clear the screen
   
      glquads(); //render the texture in 0 using glquads
                 // (you can use a pixel shader to modify the rendering)
   
   glcaptureend
      call it after glcapture in order to copy scene into texture. 
      it render scene using glcopytotexture then call glclear

   glbindtexture
      set active texture

   gltextdisable
      disable textures

   glulookat

   debug
      output a value to a console. you can output float only. 
      ex : 
      debug(6.0); 
      debug(some_variable*2.0);

   glquad
      draw a full quad on the screen (two triangles fullscreen).

   glmultmatrix

   glnormal

   glinewidth

   glalphaenable
      enable alpha

   glalphadisable
      disable alpha

   glsetshader
      set active shader program
      usefull when using multiples pixel shaders program. first pixel shader program is 0.
   

   you can get a timer using the "t" variable.
   this is accessible everywhere in the opengl script. 
   "t" is the number of milliseconds since first frame.
   
   for a complete non-opengl commands list, see "code" section.

3. pixel shader

   opengl pixel shader program can be written here.

   to create multiples pixel shaders separate each script by '@'
   ex : 
   pixel shader script 1
        ...
        ...
        ...
        ...
   end
   @
   pixel shader script 2
        ...
        ...
        ...
        ...
   end
   you can create as many as you want. only one vertex shader can be created.
   shader compile errors are printed in console

4. vertex shader
 
   same than pixel shader

5. sound

   to make the stuff complete, i have also added the possility to generate sound. This sound procedure is called each time needed to fill a sample in the audio buffer (that means 44100 times a second).

   (&l,&r)
   {
   
   }
   
   l variable is for left speaker, r for right speaker. l and r values are 16bit and should be between -32767 and 32767. Higher values will cause audio clipping.


6) console

use the console to see compilation errors (for sound, shaders and main opengl code).
this is also were all calls made with debug() function are printed.

code syntax
============

syntax is very similar to C. I think it should not be too difficult for someone who already learned C and opengl to use this.

Here is a copy/paste of the interpreter documentation from the EVAL library documentation :

---------------------------------------------------------------------------------

Currently supported operators, functions, and statements:

   Parenthesis: (), Arrays: [], Blocks: {}, Const strings: "", Literal '"': \"
          Assignment: = *= /= %= += -= ++ -- (only 1 allowed per statement)
   1-Param Operators: + - . 0 1 2 3 4 5 6 7 8 9 E PI NRND RND (variable names)
   2-Param Operators: ^ % * / + - < <= > >= == != && ||
   1-Param Functions: ABS ACOS ASIN ATAN ATN CEIL COS EXP FACT
                      FLOOR INT LOG SGN SIN SQRT TAN UNIT
   2-Param Functions: ATAN2 FMOD LOG MIN MAX POW
          Statements: IF(expr){codetrue}
                      IF(expr){codetrue}ELSE{codefalse}
                      DO{code}WHILE(expr);
                      WHILE(expr){code}
                      FOR(precode;expr;postcode){code}
                      GOTO label;
                      RETURN expr;
                      BREAK;
                      CONTINUE;
                      ENUM{name(=int),name(=int),...};
                      STATIC name[const/enum],name2[const/enum],name3,...;
                      label:
            Comments: // text (CR), /* text */

Syntax is similar to C syntax, with the following differences:

Variables & arrays:
 * Function and variable names are case insensitive
 * Type declarations are not allowed in the function body. All variables are
      assumed to be 'double'
 * The size of a static array declaration must be a constant or enum name
 * Strings cannot be in a variable yet. Only the direct form "" is supported
 * EVAL uses bounds checking for arrays (to protect EVALDRAW from crashing
      constantly). The algorithm depends on the array size:
     Power of 2: index is masked using bitwise 'and' causing wrap-around
           Else: out of bounds indices are changed to 0 before the read/write

Built-in functions:
 * PI is a built-in constant: 3.14159265358979323...
 * RND is a parameterless function returning a uniform random number [0..1)
 * NRND is a parameterless function returning a normal random number
      (mean = 0, standard deviation = 1)
 * '^' is a power operator (not an exclusive or). You can also use POW(,)
 * ATN is an alias for ATAN
 * SQR is an alias for SQRT
 * MIN&MAX are usually defined in C headers; here they are library functions
 * LOG supports both 1 and 2 parameter forms. The 2nd paramter is the base
 * INT rounds towards 0. Use FLOOR&CEIL to round towards -/+inf
 * SGN returns -1 for negative numbers, 1 for positive numbers, 0 for 0
 * UNIT returns 0 for negative numbers, 1 for positive numbers, .5 for 0
 * FACT doesn't exist in C. It calculates factorials using the gamma function

Misc.:
 * Switch statements are not yet supported
 * Array initializer lists (ex: static a[3] = {2,3,5};) not yet supported

Function style:
 * The main function must be at the top of the code and have no name
 * The last expression is the return value and doesn't need a ;
 * Return values are optional. If omitted, the function returns 0.0
 * For a 1-function script, the {} around the function body is optional. For a
      multi-function script, you must use {} around every function body.
 * Function parameters can be of type: double, double *, or char *.

   Function parameter syntax:
      kasm87 syntax: C/C++ syntax:               Description:
         a           double a                    pass-by-value variable
         &a          double &a                   pointer to double
         $a          char *a                     pointer to string
         a[4]        double a[4]                 pointer to array of doubles
         a()         double (*a)(double)         function pointer, 1 param
         a(,)        double (*a)(double,double)  function pointer, 2 params..
         a(,,)       double (*a)(double,double,double)
         a(&,)       double (*a)(double*,double)
         a($,)       double (*a)(char*)
         a($,.)      double (*a)(char*,...)
         a(,&,$)     double (*a)(double,double*,char*)
         a(,&,[8])   double (*a)(double,double*,double*)

   Inside function pointers:
      kasm87 syntax: C/C++ syntax: Description:
         (blank)     double        Standard pass-by-value double variable
         &           double *      Variable pointer; can't be used as array
         [#]         double *      Array pointer. Number is bounds protection.
         $           char *        String pointer
         .           ...           For printf:no type checking. Must be last.


---------------------------------------------------------------------------------