Humble script for creating the port's snapshots.
[AROS.git] / test / mesa / mesasimplerendering.c
blobeb9523a5593b7fe76fe4edfdae802b6654cac726
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/types.h>
7 #include <intuition/intuition.h>
8 #include <intuition/intuitionbase.h>
9 #include <intuition/screens.h>
10 #include <cybergraphx/cybergraphics.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
16 #include <proto/timer.h>
17 #include <devices/timer.h>
18 #include <proto/cybergraphics.h>
20 #include <GL/gla.h>
22 #include <stdio.h>
24 GLAContext glcont=NULL;
25 double angle = 0.0;
26 double angle_inc = 0.0;
27 BOOL finished = FALSE;
28 struct Window * win = NULL;
29 struct Device * TimerBase = NULL;
30 struct timerequest timereq;
31 struct MsgPort timeport;
32 struct Library * CyberGfxBase = NULL;
33 BOOL fullscreen = FALSE;
35 GLuint fragmentShader = 0;
36 GLuint vertexShader = 0;
37 GLuint shaderProgram = 0;
38 GLint angleLocation = 0;
41 PFNGLCREATESHADERPROC glCreateShader = NULL;
42 PFNGLSHADERSOURCEPROC glShaderSource = NULL;
43 PFNGLCOMPILESHADERPROC glCompileShader = NULL;
44 PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
45 PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
46 PFNGLATTACHSHADERPROC glAttachShader = NULL;
47 PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
48 PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
49 PFNGLUSEPROGRAMPROC glUseProgram = NULL;
50 PFNGLDETACHSHADERPROC glDetachShader = NULL;
51 PFNGLDELETESHADERPROC glDeleteShader = NULL;
52 PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
53 PFNGLUNIFORM1FPROC glUniform1f = NULL;
54 PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
56 const GLchar * fragmentShaderSource =
57 "uniform float angle;"
58 "void main()"
59 "{"
60 " vec4 v = vec4(gl_Color);"
61 " float intensity = abs(1.0f - (mod(angle, 1440.0f) / 720.0f));"
62 " v.b = v.b * intensity;"
63 " v.g = v.g * (1.0f - intensity);"
64 " gl_FragColor = v;"
65 "}";
67 const GLchar * vertexShaderSource =
68 "void main()"
69 "{ "
70 " gl_FrontColor = gl_Color;"
71 " gl_Position = ftransform();"
72 "}";
75 #define RAND_COL 1.0f
76 #define DEGREES_PER_SECOND 180.0
77 #define USE_PERSPECTIVE 1
79 void prepare_shader_program()
81 #define BUFFER_LEN 2048
82 char buffer[BUFFER_LEN] = {0};
83 int len;
85 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
86 glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
87 glCompileShader(fragmentShader);
88 glGetShaderInfoLog(fragmentShader, BUFFER_LEN, &len, buffer);
89 printf("Fragment shader compile output: %s\n", buffer);
91 vertexShader = glCreateShader(GL_VERTEX_SHADER);
92 glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
93 glCompileShader(vertexShader);
94 glGetShaderInfoLog(vertexShader, BUFFER_LEN, &len, buffer);
95 printf("Vertex shader compile output: %s\n", buffer);
97 shaderProgram = glCreateProgram();
98 glAttachShader(shaderProgram, vertexShader);
99 glAttachShader(shaderProgram, fragmentShader);
100 glLinkProgram(shaderProgram);
101 glGetProgramInfoLog(shaderProgram, BUFFER_LEN, &len, buffer);
102 printf("Shader program compile output: %s\n", buffer);
104 #undef BUFFER_LEN
107 void cleanup_shader_program()
109 glUseProgram(0);
110 glDetachShader(shaderProgram, fragmentShader);
111 glDetachShader(shaderProgram, vertexShader);
112 glDeleteShader(fragmentShader);
113 glDeleteShader(vertexShader);
114 glDeleteProgram(shaderProgram);
117 void render_face()
119 glBegin(GL_QUADS);
120 glColor4f(RAND_COL , 0.0, RAND_COL, 0.3);
121 glVertex3f(-0.25, -0.25, 0.0);
122 glColor4f(0, RAND_COL, RAND_COL, 0.3);
123 glVertex3f(-0.25, 0.25, 0.0);
124 glColor4f(0 , 0, 0, 0.3);
125 glVertex3f(0.25, 0.25, 0.0);
126 glColor4f(RAND_COL , RAND_COL, 0, 0.3);
127 glVertex3f(0.25, -0.25, 0.0);
128 glEnd();
132 void render_cube()
134 glPushMatrix();
135 glRotatef(0.0, 0.0, 1.0, 0.0);
136 glTranslatef(0.0, 0.0, 0.25);
137 render_face();
138 glPopMatrix();
141 glPushMatrix();
142 glRotatef(90.0, 0.0, 1.0, 0.0);
143 glTranslatef(0.0, 0.0, 0.25);
144 render_face();
145 glPopMatrix();
147 glPushMatrix();
148 glRotatef(180.0, 0.0, 1.0, 0.0);
149 glTranslatef(0.0, 0.0, 0.25);
150 render_face();
151 glPopMatrix();
153 glPushMatrix();
154 glRotatef(270.0, 0.0, 1.0, 0.0);
155 glTranslatef(0.0, 0.0, 0.25);
156 render_face();
157 glPopMatrix();
159 glPushMatrix();
160 glRotatef(90.0, 1.0, 0.0, 0.0);
161 glTranslatef(0.0, 0.0, 0.25);
162 render_face();
163 glPopMatrix();
165 glPushMatrix();
166 glRotatef(-90.0, 1.0, 0.0, 0.0);
167 glTranslatef(0.0, 0.0, 0.25);
168 render_face();
169 glPopMatrix();
172 void render_triangle()
174 glBegin(GL_TRIANGLES);
175 glColor4f(1.0, 0.0, 0.0, 1.0);
176 glVertex3f(-0.25, -0.25, 0.0);
177 glColor4f(0.0, 1.0, 0.0, 1.0);
178 glVertex3f(-0.25, 0.25, 0.0);
179 glColor4f(0.0, 0.0, 1.0, 1.0);
180 glVertex3f( 0.25, 0.25, 0.0);
181 glEnd();
184 void render()
186 glLoadIdentity();
187 glClearColor(0.3, 0.3, 0.3, 1.0);
188 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
189 glCullFace(GL_BACK);
190 glDepthFunc(GL_LESS);
191 glEnable(GL_DEPTH_TEST);
192 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
193 glEnable(GL_BLEND);
195 angle += angle_inc;
196 glUniform1f(angleLocation, angle);
198 #if USE_PERSPECTIVE == 1
199 glTranslatef(0.0, 0.0, -6.0);
200 #endif
201 glPushMatrix();
202 glRotatef(angle, 0.0, 1.0, 0.0);
203 glTranslatef(0.0, 0.0, 0.25);
204 glRotatef(angle, 1.0, 0.0, 1.0);
205 render_cube();
206 glPopMatrix();
208 glDisable(GL_BLEND);
209 glDisable(GL_DEPTH_TEST);
211 glASwapBuffers(glcont);
214 #define VISIBLE_WIDTH 300
215 #define VISIBLE_HEIGHT 300
217 static void initextensions()
219 glCreateShader = (PFNGLCREATESHADERPROC)glAGetProcAddress("glCreateShader");
220 glShaderSource = (PFNGLSHADERSOURCEPROC)glAGetProcAddress("glShaderSource");
221 glCompileShader = (PFNGLCOMPILESHADERPROC)glAGetProcAddress("glCompileShader");
222 glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glAGetProcAddress("glGetShaderInfoLog");
223 glCreateProgram = (PFNGLCREATEPROGRAMPROC)glAGetProcAddress("glCreateProgram");
224 glAttachShader = (PFNGLATTACHSHADERPROC)glAGetProcAddress("glAttachShader");
225 glLinkProgram = (PFNGLLINKPROGRAMPROC)glAGetProcAddress("glLinkProgram");
226 glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glAGetProcAddress("glGetProgramInfoLog");
227 glUseProgram = (PFNGLUSEPROGRAMPROC)glAGetProcAddress("glUseProgram");
228 glDetachShader = (PFNGLDETACHSHADERPROC)glAGetProcAddress("glDetachShader");
229 glDeleteShader = (PFNGLDELETESHADERPROC)glAGetProcAddress("glDeleteShader");
230 glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glAGetProcAddress("glDeleteProgram");
231 glUniform1f = (PFNGLUNIFORM1FPROC)glAGetProcAddress("glUniform1f");
232 glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glAGetProcAddress("glGetUniformLocation");
235 void initmesa()
237 struct TagItem attributes [ 14 ]; /* 14 should be more than enough :) */
238 int i = 0;
239 GLfloat h = 0.0f;
241 attributes[i].ti_Tag = GLA_Window; attributes[i++].ti_Data = (IPTR)win;
242 attributes[i].ti_Tag = GLA_Left; attributes[i++].ti_Data = win->BorderLeft;
243 attributes[i].ti_Tag = GLA_Top; attributes[i++].ti_Data = win->BorderTop;
244 attributes[i].ti_Tag = GLA_Bottom; attributes[i++].ti_Data = win->BorderBottom;
245 attributes[i].ti_Tag = GLA_Right; attributes[i++].ti_Data = win->BorderRight;
247 // double buffer ?
248 attributes[i].ti_Tag = GLA_DoubleBuf; attributes[i++].ti_Data = GL_TRUE;
250 // RGB(A) Mode ?
251 attributes[i].ti_Tag = GLA_RGBMode; attributes[i++].ti_Data = GL_TRUE;
253 /* Stencil/Accum */
254 attributes[i].ti_Tag = GLA_NoStencil; attributes[i++].ti_Data = GL_TRUE;
255 attributes[i].ti_Tag = GLA_NoAccum; attributes[i++].ti_Data = GL_TRUE;
257 // done...
258 attributes[i].ti_Tag = TAG_DONE;
260 glcont = glACreateContext(attributes);
261 if (glcont)
263 glAMakeCurrent(glcont);
264 h = (GLfloat)VISIBLE_HEIGHT / (GLfloat)VISIBLE_WIDTH ;
266 glViewport(0, 0, (GLint) VISIBLE_WIDTH, (GLint) VISIBLE_HEIGHT);
267 #if USE_PERSPECTIVE == 1
268 glMatrixMode(GL_PROJECTION);
269 glLoadIdentity();
270 glFrustum(-1.0, 1.0, -h, h, 5.0, 200.0);
271 glMatrixMode(GL_MODELVIEW);
272 #endif
273 initextensions();
274 prepare_shader_program();
275 glUseProgram(shaderProgram);
276 angleLocation = glGetUniformLocation(shaderProgram, "angle");
278 else
279 finished = TRUE; /* Failure. Stop */
282 void deinitmesa()
284 if (glcont)
286 cleanup_shader_program();
287 glADestroyContext(glcont);
291 static int init_timerbase()
293 timeport.mp_Node.ln_Type = NT_MSGPORT;
294 timeport.mp_Node.ln_Pri = 0;
295 timeport.mp_Node.ln_Name = NULL;
296 timeport.mp_Flags = PA_IGNORE;
297 timeport.mp_SigTask = FindTask(NULL);
298 timeport.mp_SigBit = 0;
299 NEWLIST(&timeport.mp_MsgList);
301 timereq.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
302 timereq.tr_node.io_Message.mn_Node.ln_Pri = 0;
303 timereq.tr_node.io_Message.mn_Node.ln_Name = NULL;
304 timereq.tr_node.io_Message.mn_ReplyPort = &timeport;
305 timereq.tr_node.io_Message.mn_Length = sizeof (timereq);
307 if(OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)&timereq,0) == 0)
309 TimerBase = (struct Device *)timereq.tr_node.io_Device;
310 return 1;
312 else
314 return 0;
319 static void deinit_timerbase()
321 if (TimerBase != NULL)
322 CloseDevice((struct IORequest *)&timereq);
326 void HandleIntuiMessages(void)
328 struct IntuiMessage *msg;
330 while((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
332 switch(msg->Class)
334 case IDCMP_CLOSEWINDOW:
335 finished = TRUE;
336 break;
337 case IDCMP_VANILLAKEY:
338 if (msg->Code == 27 /* ESC */) finished = TRUE;
339 break;
341 ReplyMsg((struct Message *)msg);
346 #define ARG_FULLSCREEN 0
347 #define NUM_ARGS 1
349 STATIC CONST_STRPTR TEMPLATE=(CONST_STRPTR) "FULLSCREEN/S";
350 static struct RDArgs *myargs;
351 static IPTR args[NUM_ARGS];
353 void get_arguments(void)
355 if((myargs = ReadArgs(TEMPLATE, args, NULL)))
357 fullscreen = (BOOL)args[ARG_FULLSCREEN];
358 FreeArgs(myargs);
363 ** Open a simple window using OpenWindowTagList()
365 int main(void)
367 ULONG fps = 0;
368 // ULONG exitcounter = 0;
369 TEXT title[100];
370 struct Screen * pubscreen = NULL;
371 struct Screen * customscreen = NULL;
372 LONG modeid;
374 struct timeval tv;
375 UQUAD lastmicrosecs = 0L;
376 UQUAD currmicrosecs = 0L;
377 UQUAD fpsmicrosecs = 0L;
379 get_arguments();
381 init_timerbase();
383 GetSysTime(&tv);
384 lastmicrosecs = tv.tv_secs * 1000000 + tv.tv_micro;
385 fpsmicrosecs = lastmicrosecs;
387 if (fullscreen)
389 CyberGfxBase = OpenLibrary("cybergraphics.library", 0L);
391 modeid = BestCModeIDTags(CYBRBIDTG_NominalWidth, VISIBLE_WIDTH,
392 CYBRBIDTG_NominalHeight, VISIBLE_HEIGHT,
393 TAG_DONE);
395 customscreen = OpenScreenTags(NULL,
396 SA_Type, CUSTOMSCREEN,
397 SA_DisplayID, modeid,
398 SA_Width, VISIBLE_WIDTH,
399 SA_Height, VISIBLE_HEIGHT,
400 SA_ShowTitle, FALSE,
401 SA_Quiet, TRUE,
402 TAG_DONE);
404 win = OpenWindowTags(NULL,
405 WA_Left, 0,
406 WA_Top, 200,
407 WA_InnerWidth, VISIBLE_WIDTH,
408 WA_InnerHeight, VISIBLE_HEIGHT,
409 WA_CustomScreen, (IPTR)customscreen,
410 WA_Flags, WFLG_ACTIVATE | WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_RMBTRAP,
411 WA_IDCMP, IDCMP_VANILLAKEY,
412 TAG_DONE);
414 else
416 if ((pubscreen = LockPubScreen(NULL)) == NULL) return 1;
418 win = OpenWindowTags(0,
419 WA_Title, (IPTR)"MesaSimpleRendering",
420 WA_PubScreen, pubscreen,
421 WA_CloseGadget, TRUE,
422 WA_DragBar, TRUE,
423 WA_DepthGadget, TRUE,
424 WA_Left, 50,
425 WA_Top, 200,
426 WA_InnerWidth, VISIBLE_WIDTH,
427 WA_InnerHeight, VISIBLE_HEIGHT,
428 WA_Activate, TRUE,
429 WA_RMBTrap, TRUE,
430 WA_SimpleRefresh, TRUE,
431 WA_NoCareRefresh, TRUE,
432 WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW,
433 TAG_DONE);
435 UnlockPubScreen(NULL, pubscreen);
438 initmesa();
439 // finished = TRUE;
440 while(!finished)
442 GetSysTime(&tv);
443 currmicrosecs = tv.tv_secs * 1000000 + tv.tv_micro;
445 if (currmicrosecs - fpsmicrosecs > 1000000)
447 /* FPS counting is naive! */
448 fpsmicrosecs += 1000000;
449 sprintf(title, "MesaSimpleRendering, FPS: %d", (int)fps);
450 SetWindowTitles(win, title, (UBYTE *)~0L);
451 fps = 0;
454 angle_inc = ((double)(currmicrosecs - lastmicrosecs) / 1000000.0) * DEGREES_PER_SECOND;
455 lastmicrosecs = currmicrosecs;
457 fps++;
458 render();
459 HandleIntuiMessages();
460 // exitcounter++;
461 // Delay(10);
462 // if (exitcounter > 0) finished = TRUE;
465 deinitmesa();
467 deinit_timerbase();
469 CloseWindow(win);
471 if (customscreen) CloseScreen(customscreen);
473 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
475 return 0;