Author Topic: Tiny, tiny OpenGL window and shader setup code  (Read 18628 times)

0 Members and 1 Guest are viewing this topic.

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Hi guys,

Well Ive done a few 1k frameworks over time but they were all done without crinkler in mind. Given this is the defacto standard for 4k and now 1k - it was time to update. After days of trial and error, mainly error, I got this to work on my Ati, XP machines. No guarantees on anything else :-) yet. Its all very dodgy, laregly shouldnt work, but it does.

First windowing code. The code opens a full screen window, and sets up opengl. It runs a loop waiting for escape key and even includes the swapbuffers. It uses DEVMOVE setup to open at any resolution but this can be removed if you think you dont need it.

Code: [Select]
#include < windows.h >
#include < GL/gl.h >

static PIXELFORMATDESCRIPTOR pfd={
0, // Size Of This Pixel Format Descriptor... BAD coding, nothing new, saves 6 bytes
1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};

static DEVMODE dmScreenSettings={
"",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT,
0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,1024,768,0,0,0,0,0,0,0,0,0,0
};

void WINAPI WinMainCRTStartup()
{
   ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN); 
   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) );
   ShowCursor(FALSE);
   do {
        // insert breakpoint winning 1k here
         SwapBuffers(hDC);
    } while ( !GetAsyncKeyState(VK_ESCAPE) );   
}


Next, shader code. Given two strings representing the vertex and pixel shaders, this routine is the smallest I could come up with under crinkler to create and bind the shader program.

Code: [Select]
static void setShaders(){
GLuint p,s;
  p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))();
  s = ((PFNGLCREATESHADERPROC)(wglGetProcAddress("glCreateShader")))(GL_VERTEX_SHADER);
  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &vsh, NULL);
  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);
  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);

  s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER);
  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &fsh, NULL);
  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);
  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);
   
  ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);
  ((PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"))(p);
}

They are useful for 1k and 4k coders, though I think OpenGl at 1k is not really competitive anymore.

Chris
http://sizecoding.blogspot.com/
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #1 on: October 25, 2007 »
This will surely come in handy thanks for putting this together. I'm off to try to get this up and runnin

Edit: Looks like this is not gonna be easy lotsa "cannot convert from const char [n] to WCHAR" should I be replacing some 0's with ""
« Last Edit: October 25, 2007 by rain_storm »

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #2 on: October 25, 2007 »
That's neat, need to do some tests  ;D

Btw, do you have a little shader program example for me to test my asm version and compare with your C program (sizes) ?


Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #3 on: October 26, 2007 »
Edit: Looks like this is not gonna be easy lotsa "cannot convert from const char [n] to WCHAR" should I be replacing some 0's with ""

OK as Jim said, thats a bit hopeful (the quotes) It works under VC Express but probably needs casting properly. Which version are you using rain? I'm sure this is easy to fix.

Chris
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #4 on: October 26, 2007 »
Visual Studio C++ 2005 Exress. I have been preatty much lost in the flood with C, so far I have only really managed to compile SDL based PE's but I find they are very big for what I need. This would be a great piece to strip apart as it gets a screen up and runnin in a few lines of code. Just getting past the compilation

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #5 on: October 26, 2007 »
"" is the correct initialiser, {0} might work too.
Quote
Edit: Looks like this is not gonna be easy lotsa "cannot convert from const char [n] to WCHAR" should I be replacing some 0's with ""
You need to turn off UNICODE
Project->Properties->Configuration Properties->General
and set Character Set to Use Multi-Byte Character Set.

Chris, I think it might be possible to save more bytes here
Place
Code: [Select]
#define WINVER 0x400
before you #include windows.h.
That would mean you could remove 8 0s off the end of the DEVMODE initialiser.
Basically that structure has grown in later versions of Windows, so various values of sizeof(dmScreenSettings) are valid.  You're just telling it you're building for NT4 compatibility.

Jim
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #6 on: October 27, 2007 »
It was a great idea Jim but the compressor just sees all those lovely zeroes and handles them nicely, so though your suggestion works nicely, it doesn't save bytes :-(. Shame.

Chris
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #7 on: October 27, 2007 »
Bah, I didn't even shrink the source code ;D

Jim
Challenge Trophies Won:

Offline benny!

  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4384
  • Karma: 228
  • in this place forever!
    • View Profile
    • bennyschuetz.com - mycroBlog
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #8 on: October 27, 2007 »
Looking good. Thanks for sharing. WIll have a closer look on it later on !!!
[ mycroBLOG - POUET :: whatever keeps us longing - for another breath of air - is getting rare ]

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #9 on: October 27, 2007 »
Another idea...
How about
Code: [Select]
DEVMODE devmode;
...
{
//get the current display mode
devmode.dmSize = sizeof(devmode);
EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
//modify any settings you like, if any
devmode.dmPelsWidth = 1024;
devmode.dmPelsWidth = 768;
//set the mode
ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN);
}
or even
Code: [Select]
EnumDisplaySettings(NULL,0,&devmode);
that's likely to get you 800x600x32@60Hz on XP

Tried these and the return looks nonsense - plus I just had to add dmSize = in there the make it work at all. :(
Jim
« Last Edit: October 27, 2007 by Jim »
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #10 on: October 27, 2007 »
Jim, basically thats how the framework looked before, I am switching to static declarations because its smaller than lines of code. Here is the code from before:
Code: [Select]
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = 1024;
dmScreenSettings.dmPelsHeight= 768;
dmScreenSettings.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT;
ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN);

This is much bigger than the static version I've just published.

Chris
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #11 on: October 28, 2007 »
The idea was to not have a static declaration at all (takes up no space) and to make it a valid structure using EnumDisplayMode - on it's own, that would be smaller, but there's too much set up, as we both noticed :(

Jim
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #12 on: October 28, 2007 »
That's neat, need to do some tests  ;D

Btw, do you have a little shader program example for me to test my asm version and compare with your C program (sizes) ?


Rbraz, I forgot this earlier.. I'll post something tonight.

Chris
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #13 on: October 28, 2007 »
Rbraz,

heres some example code for you. Its more or less the best I can do :-(. Size, crinkler flags etc in code...let me know what you get. It will be a good test of VC++ v hand coding.

For others, this is the smallest oldskool tunnel effect I can do in shaders. Its pretty small (the shader). IF ati drivers didnt break without a vertex shader I could do better. Oh well.

Code: [Select]
// Chris Thornborrow (auld)
// New crinkler optimised OpenGL 1k + shader framework.
// Sets screen size, loads vertex and fragment shader
// also exitProcess for some Nvidia and Vista machines
// Example shader included...

// /CRINKLER /COMPMODE:SLOW /HASHSIZE:200 /HASHTRIES:50 /ORDERTRIES:6000
// 915 bytes with VC++ Express
// Oldskool tunnel effect...but without real timer

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

///////////////////////////////////////////////////////////////////
// WINDOWING
#define SCREENX 1024
#define SCREENY 768

static PIXELFORMATDESCRIPTOR pfd={
0, // Size Of This Pixel Format Descriptor... BAD coding, nothing new, saves 6 bytes
1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0
};

static DEVMODE dmScreenSettings={
"",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT,
0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,SCREENX,SCREENY,0,0,0,0,0,0,0,0,0,0
};

const char *vsh="varying vec4 v;void main(){v=ftransform();gl_Position=gl_Vertex;}";
const char *fsh="varying vec4 v;void main(){float t=length(v.xy);gl_FragColor=vec4(cos(4./t+v.z)*t);}";

void setShader() {
GLuint p,s;
    p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))();
    s = ((PFNGLCREATESHADERPROC)(wglGetProcAddress("glCreateShader")))(GL_VERTEX_SHADER);
  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &vsh, NULL);
          ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);
          ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);
    s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER);
  ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &fsh, NULL);
  ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s);
  ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s);
  ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p);
  ((PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"))(p);
}

void WINAPI WinMainCRTStartup()
{
   ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN); 
   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) );
   ShowCursor(FALSE);
   setShader();
   do {
glTranslatef(0,0,0.5f);
glRects(-1,-1,1,1);
         SwapBuffers(hDC);
    } while ( !GetAsyncKeyState(VK_ESCAPE) );   
   ExitProcess(0);
}
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #14 on: October 29, 2007 »
Ok, I got it down to 895 bytes, using your crinkler parameters.

I didn't have tried your new way to initialize shaders (setShader()), I will try it later to see how much bytes I can get.

Anyway, sometimes 20 bytes can be helpful  :)

Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #15 on: October 30, 2007 »
Yeah I agree rbraz - 20 bytes in shaders is actually quite a lot of help. Given you havent tried the new shader code too...thats probably another 20. So I'd guess 40 in all. Thats a lot at of advantage at 1k.

Now we have to wait for mentor to release his new 1k compressor ...

Chris
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #16 on: November 04, 2007 »
Yes, you are right, I've recoded it using your new shader setup and now it compress to 877 bytes.

This is annoying because the other code have less lines and looks "smart" but it is not what crinkler likes :)
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #17 on: November 04, 2007 »
Rbraz,

FYI iq of rgba gave me a D3D version of a 1k framework which with minimal shader comes in at 835 bytes. So its something like (for shaders using Crinkler):

OGL in C : 900
OGL in asm : 870
D3D in C: 830
D3D in asm: ??? 800???

D3D doesnt need the vertex shader and doesnt need to import shader commands but is a little heavier to initialise than OGL. Getting values into the shader is also easier with D3D.

Time to learn HLSL I guess: its a bigger advantage than learning asm!

Chris

Challenge Trophies Won:

Offline p01

  • Atari ST
  • ***
  • Posts: 158
  • Karma: 51
    • View Profile
    • www.p01.org
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #18 on: November 05, 2007 »
Dunno if this is relevant to pixel shaders and all the malarkey, but have any of you looked at t-time by Peci^Scoopex ? it displays a teapot OpenGL primitive in 256b.

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Tiny, tiny OpenGL window and shader setup code
« Reply #19 on: November 05, 2007 »
Dunno if this is relevant to pixel shaders and all the malarkey, but have any of you looked at t-time by Peci^Scoopex ? it displays a teapot OpenGL primitive in 256b.

P01, yes this is a great trick. I looked into this quite hard. Unfortunately its a real trick and unstable (see all the "it doesnt work here" comments). Also reading his seminar notes, it seems that it is limited in use...though to be honest I cant figure out why.

Chris
« Last Edit: November 05, 2007 by chris »
Challenge Trophies Won: