Dark Bit Factory & Gravity

GENERAL => Projects => Topic started by: taj on May 02, 2007

Title: Retired but...one more 1k
Post by: taj on May 02, 2007
Hi all,

I wrote another 1k. I had some time on my hands and it turned out to be one of my very best. It uses PS2.0, OGL,C and is an EXE (thanks Benny for help here).

http://www.pouet.net/prod.php?which=30589

http://www.intro-inferno.com/production.php?id=3551

Heres is the source:

Code: [Select]
// Chris Thornborrow (auld/sek/taj/copabars/fra/mess4u etc.)
// If you use this code please credit...blahblah
// Example OGL + shaders in 1k
// Requires crinkler - magnificent tool
// VS2005 modifications by benny!weltenkonstrukteur.de from dbf
//    Greets!

// NOTE: DX will beat this no problem at all due to OpenGL forced
// to import shader calls as variables..nontheless we dont need
// d3dxblahblah to be loaded on users machine.

#include <windows.h>
#include <GL/gl.h>
#include "glext.h"

// NOTE: in glsl it is legal to have a fragment shader without a vertex shader
//  Infact ATi/AMD  drivers allow this but unwisely forget to set up variables for
// the fragment shader - thus all GLSL programs must have a vertex shader :-(
// Thanks ATI/AMD

// This is prtty dirty...note we do not transform the rectangle but we do use
// glRotatef to pass in a value we can use to animate...avoids one more getProcAddress later
const GLchar *vsh="\
varying vec4 p;\
void main(){\
p=sin(gl_ModelViewMatrix[1]*9.0);\
gl_Position=gl_Vertex;\
}";

// an iterative function for colour
const GLchar *fsh="\
varying vec4 p;\
void main(){\
float r,t,j;\
vec4 v=gl_FragCoord/400.0-1.0;\
r=v.x*p.r;\
for(int j=0;j<7;j++){\
t=v.x+p.r*p.g;\
v.x=t*t-v.y*v.y+r;\
v.y=p.g*3.0*t*v.y+v.y;\
}\
gl_FragColor=vec4(mix(p,vec4(t),max(t,v.x)));\
}";
//p.g*3.0*t*v.y+i;\

typedef void (*GenFP)(void); // any function ptr type would do
static GenFP glFP[7];

const static char* glnames[]={
      "glCreateShader", "glCreateProgram", "glShaderSource", "glCompileShader",
      "glAttachShader", "glLinkProgram", "glUseProgram"
};

static void setShaders() {
int i;
   // 19. April 2007: "(GenFP) cast" added by benny!weltenkonstrukteur.de
   for (i=0; i<7; i++) glFP[i] = (GenFP)wglGetProcAddress(glnames[i]);

GLuint v = ((PFNGLCREATESHADERPROC)(glFP[0]))(GL_VERTEX_SHADER);
GLuint f = ((PFNGLCREATESHADERPROC)(glFP[0]))(GL_FRAGMENT_SHADER);
        GLuint p = ((PFNGLCREATEPROGRAMPROC)glFP[1])();

        ((PFNGLSHADERSOURCEPROC)glFP[2]) (v, 1, &vsh, NULL);
((PFNGLCOMPILESHADERPROC)glFP[3])(v);
((PFNGLSHADERSOURCEPROC)glFP[2]) (f, 1, &fsh, NULL);
((PFNGLCOMPILESHADERPROC)glFP[3])(f);

((PFNGLATTACHSHADERPROC)glFP[4])(p,v);
((PFNGLATTACHSHADERPROC)glFP[4])(p,f);

((PFNGLLINKPROGRAMPROC)glFP[5])(p);
((PFNGLUSEPROGRAMPROC) glFP[6])(p);
}


// force them to set everything to zero by making them static
static PIXELFORMATDESCRIPTOR pfd;
static DEVMODE dmScreenSettings;

void WINAPI WinMainCRTStartup()
{
   dmScreenSettings.dmSize=sizeof(dmScreenSettings);
   dmScreenSettings.dmPelsWidth = 1024;
   dmScreenSettings.dmPelsHeight= 768;
//   dmScreenSettings.dmBitsPerPel = 32;
// its risky to remove the flag and bits but probably safe on compo machine :-)
   dmScreenSettings.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT;
   ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN); 
   
   // minimal windows setup code for opengl 
   pfd.cColorBits = pfd.cDepthBits = 32;
   pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

// "HDC hDC" changed 19. April 2007 by benny!weltenkonstrukteur.de
    HDC hDC = GetDC( CreateWindow("edit", 0, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0) );

   SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &pfd) , &pfd );
   wglMakeCurrent ( hDC, wglCreateContext(hDC) );

   setShaders();
   ShowCursor(FALSE);

//**********************
// NOW THE MAIN LOOP...
//**********************

    // there is no depth test or clear screen...as we draw in order and cover
    // the whole area of the screen.
    do {
         //dodgy, no oglLoadIdentity- might break...
// change the first number to alter speed of intro...smaller is slower
// this is the fast version
         glRotatef(0.3f,1,1,1);
         // draw a single flat rectangle on screen...
glRecti(-1,-1,1,1);
         SwapBuffers(hDC);
    } while ( !GetAsyncKeyState(VK_ESCAPE) );   
}

Hope u like it.

Chris
Title: Re: Retired but...one more 1k
Post by: Paul on May 02, 2007
Thats awesome man:)
Really nice colors and movement, the middle speed is the best one according to me.
Title: Re: Retired but...one more 1k
Post by: benny! on May 02, 2007
I love it, Chris. It really rocks. Just awesome !!!

Karma for mentioning me :-) and for sharing code - you rule !!!
Title: Re: Retired but...one more 1k
Post by: rain_storm on May 02, 2007
all three didnt work on my PC just started up then seconds later crashed :( sorry dont have any details for the error just got one of those send error report to microsoft messages
Title: Re: Retired but...one more 1k
Post by: taj on May 03, 2007
Guys: thanks very much for nice comments. I had a free dsay and nothing to do at all, so inspired by Benny, I tried one more which came out nicly, even I like it. Thanks Benny.

Rain_storm, can you tell me what hardware/OS you have? There is no DX and no import by ordinal so in theory it works (ie Im not doing anything too dirty).

Chris
Title: Re: Retired but...one more 1k
Post by: mike_g on May 03, 2007
It wouldent work for me either, which was a shame since from the screenie it looked cool  :'( I expect thats because my graphics card dosent support shaders.
Title: Re: Retired but...one more 1k
Post by: taj on May 03, 2007
Mike_g,

and anyone else trying to  run this without shaders : it wont work. Shaders are a step function, I cant write a software fallback path I'm afraid.

Chris
Title: Re: Retired but...one more 1k
Post by: rain_storm on May 03, 2007
Windows XP SP2 (with directX 9)
celeron D (345) @ 3.3GHz
intel extreme grahics integrated into the motherboard

I think it is probably a shader issue its a real piety can those shaders be downloaded or are they a part of the graphics card hardware.
Title: Re: Retired but...one more 1k
Post by: Jim on May 03, 2007
Pixel shaders are part of the graphics hardware, there have been (at least) 4 revisions - 1.0, 1.1, 2.0, 3.0 - the newer your hardware the better supported they are.  2.0 is where most demos are targetted, and that has only recently been added to embedded (chipset) graphics solutions, so that might explain why it doesn't work for you.  Not much you can do except upgrade...  If you have an AGP or PCI Express slot on your board you can get something quite cheaply...

Jim
Title: Re: Retired but...one more 1k
Post by: Guard][an on May 04, 2007
nice
Title: Re: Retired but...one more 1k
Post by: Shockwave on May 04, 2007
Unfortunately I can't run it myself because of the PS, however it is lovely to see another release from you Chris, Karma up for sharing the source code, and thank you for spending some of your free time to create something for other people to enjoy!
Title: Re: Retired but...one more 1k
Post by: taj on May 05, 2007
Unfortunately I can't run it myself because of the PS, however it is lovely to see another release from you Chris, Karma up for sharing the source code, and thank you for spending some of your free time to create something for other people to enjoy!

I have holiday right now and its one of those lazy "at home" holidays. Benny inspired me to push a 1k exe out so I took the old mandelflow code, reworked it and hey presto.

http://in4k.untergrund.net/index.php?title=About_Flow2

Some more details. I guess you cant leave the scene except maybe by throwing your PC out of the window, I guess you just become inactive. Thanks to everyone for support - this 1k doesnt mean I'm "back" it just means I had a free day.

Chris

Title: Re: Retired but...one more 1k
Post by: rain_storm on May 05, 2007
Old habits die hard, I suppose
Title: Re: Retired but...one more 1k
Post by: Clanky on May 10, 2007
Nice!
Just wondering whether the graphics represent piano keys? Just looked as like they were the keys! lol.
Title: Re: Retired but...one more 1k
Post by: taj on May 11, 2007
CLANKY,

You think the same as me :-) I almost called it pianobrot. I'd like to say it was designed that way but in truth the shaders are so small that you search for an interesting effect in the 10-15 bytes you have or so left for colour. In writing my glsl 1ks I usually spend half a day just tweaking that one line of colour code!

The truth is doing GLSL shaders in 1k is a bit like having a small suitcase, filling it with everything you need, then discovering your shoes dont fit and no matter how hard you try, you cant close the case. DX is the better choice at 1k :-(. Assembler helps for sure too (~10% which is huge at 1k).

MIX(v1,v2,v3) is a cool glsl command, it smoothly blends one vector (colour) with another, and the blendfactor is the third value. This is how the white is belnded with the inner colours. This I used on its own in mandelflow

 http://www.intro-inferno.com/production.php?id=2062

The trick with the piano effect was realising suddenly that if I use a discontinuous function as the blend factor (v3) I might get a double of effect of smooth blending then a break to some other look and feel. Hence the piano around the edges.

MIX(v1,v2,max(a,b))  <- max gives a discontinuous function

It was then a matter of putting every variable I had into that equation until something cool popped out (thats the squeezing your shoes in bit ;-)).
Hmmm I just noiticed the last line of code:
gl_FragColor=vec4(mix(p,vec4(t),max(t,v.x)));
Can be written
gl_FragColor=mix(p,vec4(t),max(t,v.x));
so maybe I could squeeze the shoes in too. I hate it when the "obvious" escapes you until *after* release.

Chris



Title: Re: Retired but...one more 1k
Post by: Clanky on May 11, 2007
Just one question:
   Is this using dot product multiplication? Or am I wrong? lol
gl_FragColor = vec4(mix(p, vec4(t), max(t, v.x)))

gl_FragColor = mix(p, vec4(t), max(t, v.x))

Yea. Sometimes in yabasic. lol... I get the same way! But, not as the way you do. I just struggle to get the gfx looking good lol.
Title: Re: Retired but...one more 1k
Post by: taj on May 11, 2007
CLANKY,

mix(a,b,c) = a*c + b(1-c)

So not dot product, for which in GLSL would be

dot(a,b)

Chris
Title: Re: Retired but...one more 1k
Post by: ninogenio on May 11, 2007
so i take it glsl`s vec4 function is quite expensive in terms of exe size taj?
Title: Re: Retired but...one more 1k
Post by: taj on May 11, 2007
Nino,

well all glsl "code" is really a string. Its not compiled until you run the program! In other words the part of your code that is the shader is the text of the code itself.
eg
const char *vsh="varying vec4 p;void main(){p=gl_ModelViewMatrix[3];gl_Position=gl_Vertex;}";

which looks just like a string declaration in C is a shader program.

At run time this is passed to a series of command something like:
declare this shader (string)
compile this shader
link this shader with other shaders
attach the compiled code to a program
run the program

Its almost the same thing as you taking a text file, compiling and linking it! Infcat most people not worried about size coding store their shaders in seperate text files which are read when the program runs.

This means that vec4() is around 6 bytes v-e-c-4-(-). Tiny. Of course it may compress (strings do). But then again, by not using it you could put s-i-n-(-) elsewhere and get a better effect for example. Or create an animation by multiplying one variable by another. Once you get shaders up and running they are incredibly small (or can be). 

To illustrate look at this:
Code: [Select]
const GLchar *vsh="varying vec4 p;void main(){p=gl_ModelViewMatrix[3];gl_Position=gl_Vertex;}";
const GLchar *fsh="\
varying vec4 p;\
void main(){vec4 d,v;float t=0.0;d=gl_FragCoord/400.0-1.0;d.y+=sin(p.z*5.0);\
do{t+=0.01;v=fract(p+0.5+t*d);}while(t<8.0&&length(v.xyz-0.5)<0.6);\
gl_FragColor=(v-0.5)+t/2.0;}";

Given a rectangle covering the screen, and that shader, produces an animation like the on in the picture (some of us know as "lattice"). Of course I never finished the colours or lighting so you have to use some imagination, nontheless the code is tiny.

The part that goes:

do{t+=0.01;v=fract(p+0.5+t*d);}while(t<8.0&&length(v.xyz-0.5)<0.6);\

is actually doing this ray-marching in a grid of spheres. The eye position is animated, there is
a test for going too far and there is a test that if we leave the intersecting spheres, we hit a wall.

So, raycasting using ray marching a complex curved surface in 1 line of code.

Shaders are damn powerful and may even beat assembler for size!!!

Chris
Title: Re: Retired but...one more 1k
Post by: ninogenio on May 12, 2007
great and cheers taj k+,

this is going to really help me take my first steps into shaders.

great screenshot btw
Title: Re: Retired but...one more 1k
Post by: Rbz on May 20, 2007
Oh, I wanna be retired too!  :clap:
Title: Re: Retired but...one more 1k
Post by: Rbz on June 10, 2007
@Chris: I know that you like comparisons between C and ASM, so here is your 1k recoded to ASM, one with opengl32 IBO (984 bytes) and the second without IBO (994 bytes)

What you do in 40 bytes ?   :||
Title: Re: Retired but...one more 1k
Post by: taj on June 10, 2007
@Chris: I know that you like comparisons between C and ASM, so here is your 1k recoded to ASM, one with opengl32 IBO (984 bytes) and the second without IBO (994 bytes)

What you do in 40 bytes ?   :||


IN C or asm ;-)???

Seriously this is interesting because it begins to put bounds on asm v c in terms of %age. Well done man, have some Karma. Its clear that for size coders, asm has the size advantage for sure *once* the algorithm etc are worked out. My main complaint about asm is that most coders jump to it before optimising what they can otherwise and that somehow in the scene is "better".

Hmmm I'm drunk, whats FBO? Frame buffer object?

Chris
Title: Re: Retired but...one more 1k
Post by: Rbz on June 10, 2007
Quote
...My main complaint about asm is that most coders jump to it before optimising what they can otherwise and that somehow in the scene is "better".
Very true...

Quote
Hmmm I'm drunk, whats FBO? Frame buffer object?
Oh yeah, you're really drunk  ;) 

IBO - Import By Ordinal
Title: Re: Retired but...one more 1k
Post by: taj on June 10, 2007
Quote
Hmmm I'm drunk, whats FBO? Frame buffer object?
Oh yeah, you're really drunk  ;) 

IBO - Import By Ordinal


Hahaha, blind too.
Title: Re: Retired but...one more 1k
Post by: taj on June 10, 2007
Aaagh just realised, 40 bytes ... in a shader , my god thats a LOT!!!
Oh man I better learn asm :-(

Chris
(or send you my C programs and do joint releases :-)
Title: Re: Retired but...one more 1k
Post by: Shockwave on June 10, 2007
Quote
...My main complaint about asm is that most coders jump to it before optimising what they can otherwise and that somehow in the scene is "better".

Who gives a fuck about the scene anyway? :) Half of the scene is rotten anyway, only friends are important.
Title: Re: Retired but...one more 1k
Post by: taj on June 10, 2007
Quote
...My main complaint about asm is that most coders jump to it before optimising what they can otherwise and that somehow in the scene is "better".

Who gives a fuck about the scene anyway? :) Half of the scene is rotten anyway, only friends are important.


But but but, what if your freinds are sceners ??? Does not compute!!!
 
Title: Re: Retired but...one more 1k
Post by: Shockwave on June 10, 2007
Half the scene is rotten :) Half is nice.  :cheers:
Title: Re: Retired but...one more 1k
Post by: Rbz on June 12, 2007
Aaagh just realised, 40 bytes ... in a shader , my god thats a LOT!!!
Oh man I better learn asm :-(
I found more two bytes (982)  :P

Quote
(or send you my C programs and do joint releases :-)
If you have something to kick mentor butt, count with me!
Title: Re: Retired but...one more 1k
Post by: Shockwave on June 13, 2007
You two would totally rule if you teamed up.