- Set a default PCM volume so that something can be heard when driver is
[AROS.git] / test / mesa / mesasimplerendering.c
blob346d2ee3837d403878e36b366e481ba82537f521
1 #include <exec/types.h>
2 #include <intuition/intuition.h>
3 #include <intuition/intuitionbase.h>
4 #include <intuition/screens.h>
5 #include <cybergraphx/cybergraphics.h>
7 #include <proto/exec.h>
8 #include <proto/dos.h>
9 #include <proto/intuition.h>
11 #include <proto/timer.h>
12 #include <devices/timer.h>
13 #include <proto/cybergraphics.h>
15 #define GL_GLEXT_PROTOTYPES
16 #include <GL/arosmesa.h>
18 #include <stdio.h>
20 AROSMesaContext glcont=NULL;
21 double angle = 0.0;
22 double angle_inc = 0.0;
23 BOOL finished = FALSE;
24 struct Window * win = NULL;
25 struct Device * TimerBase = NULL;
26 struct timerequest timereq;
27 struct MsgPort timeport;
28 struct Library * CyberGfxBase = NULL;
29 BOOL fullscreen = FALSE;
31 GLuint fragmentShader = 0;
32 GLuint vertexShader = 0;
33 GLuint shaderProgram = 0;
34 GLint angleLocation = 0;
37 const GLchar * fragmentShaderSource =
38 "uniform float angle;"
39 "void main()"
40 "{"
41 " vec4 v = vec4(gl_Color);"
42 " float intensity = abs(1.0f - (mod(angle, 1440.0f) / 720.0f));"
43 " v.b = v.b * intensity;"
44 " v.g = v.g * (1.0f - intensity);"
45 " gl_FragColor = v;"
46 "}";
48 const GLchar * vertexShaderSource =
49 "void main()"
50 "{ "
51 " gl_FrontColor = gl_Color;"
52 " gl_Position = ftransform();"
53 "}";
56 #define RAND_COL 1.0f
57 #define DEGREES_PER_SECOND 180.0
58 #define USE_PERSPECTIVE 1
60 void prepare_shader_program()
62 #define BUFFER_LEN 2048
63 char buffer[BUFFER_LEN] = {0};
64 int len;
66 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
67 glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
68 glCompileShader(fragmentShader);
69 glGetShaderInfoLog(fragmentShader, BUFFER_LEN, &len, buffer);
70 printf("Fragment shader compile output: %s\n", buffer);
72 vertexShader = glCreateShader(GL_VERTEX_SHADER);
73 glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
74 glCompileShader(vertexShader);
75 glGetShaderInfoLog(vertexShader, BUFFER_LEN, &len, buffer);
76 printf("Vertex shader compile output: %s\n", buffer);
78 shaderProgram = glCreateProgram();
79 glAttachShader(shaderProgram, vertexShader);
80 glAttachShader(shaderProgram, fragmentShader);
81 glLinkProgram(shaderProgram);
82 glGetProgramInfoLog(shaderProgram, BUFFER_LEN, &len, buffer);
83 printf("Shader program compile output: %s\n", buffer);
85 #undef BUFFER_LEN
88 void cleanup_shader_program()
90 glUseProgram(0);
91 glDetachShader(shaderProgram, fragmentShader);
92 glDetachShader(shaderProgram, vertexShader);
93 glDeleteShader(fragmentShader);
94 glDeleteShader(vertexShader);
95 glDeleteProgram(shaderProgram);
98 void render_face()
100 glBegin(GL_QUADS);
101 glColor4f(RAND_COL , 0.0, RAND_COL, 0.3);
102 glVertex3f(-0.25, -0.25, 0.0);
103 glColor4f(0, RAND_COL, RAND_COL, 0.3);
104 glVertex3f(-0.25, 0.25, 0.0);
105 glColor4f(0 , 0, 0, 0.3);
106 glVertex3f(0.25, 0.25, 0.0);
107 glColor4f(RAND_COL , RAND_COL, 0, 0.3);
108 glVertex3f(0.25, -0.25, 0.0);
109 glEnd();
113 void render_cube()
115 glPushMatrix();
116 glRotatef(0.0, 0.0, 1.0, 0.0);
117 glTranslatef(0.0, 0.0, 0.25);
118 render_face();
119 glPopMatrix();
122 glPushMatrix();
123 glRotatef(90.0, 0.0, 1.0, 0.0);
124 glTranslatef(0.0, 0.0, 0.25);
125 render_face();
126 glPopMatrix();
128 glPushMatrix();
129 glRotatef(180.0, 0.0, 1.0, 0.0);
130 glTranslatef(0.0, 0.0, 0.25);
131 render_face();
132 glPopMatrix();
134 glPushMatrix();
135 glRotatef(270.0, 0.0, 1.0, 0.0);
136 glTranslatef(0.0, 0.0, 0.25);
137 render_face();
138 glPopMatrix();
140 glPushMatrix();
141 glRotatef(90.0, 1.0, 0.0, 0.0);
142 glTranslatef(0.0, 0.0, 0.25);
143 render_face();
144 glPopMatrix();
146 glPushMatrix();
147 glRotatef(-90.0, 1.0, 0.0, 0.0);
148 glTranslatef(0.0, 0.0, 0.25);
149 render_face();
150 glPopMatrix();
153 void render_triangle()
155 glBegin(GL_TRIANGLES);
156 glColor4f(1.0, 0.0, 0.0, 1.0);
157 glVertex3f(-0.25, -0.25, 0.0);
158 glColor4f(0.0, 1.0, 0.0, 1.0);
159 glVertex3f(-0.25, 0.25, 0.0);
160 glColor4f(0.0, 0.0, 1.0, 1.0);
161 glVertex3f( 0.25, 0.25, 0.0);
162 glEnd();
165 void render()
167 glLoadIdentity();
168 glClearColor(0.3, 0.3, 0.3, 1.0);
169 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
170 glCullFace(GL_BACK);
171 glDepthFunc(GL_LESS);
172 glEnable(GL_DEPTH_TEST);
173 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
174 glEnable(GL_BLEND);
176 angle += angle_inc;
177 glUniform1f(angleLocation, angle);
179 #if USE_PERSPECTIVE == 1
180 glTranslatef(0.0, 0.0, -6.0);
181 #endif
182 glPushMatrix();
183 glRotatef(angle, 0.0, 1.0, 0.0);
184 glTranslatef(0.0, 0.0, 0.25);
185 glRotatef(angle, 1.0, 0.0, 1.0);
186 render_cube();
187 glPopMatrix();
189 glDisable(GL_BLEND);
190 glDisable(GL_DEPTH_TEST);
192 AROSMesaSwapBuffers(glcont);
195 #define VISIBLE_WIDTH 300
196 #define VISIBLE_HEIGHT 300
198 void initmesa()
200 struct TagItem attributes [ 14 ]; /* 14 should be more than enough :) */
201 int i = 0;
202 GLfloat h = 0.0f;
204 attributes[i].ti_Tag = AMA_Window; attributes[i++].ti_Data = (IPTR)win;
205 attributes[i].ti_Tag = AMA_Left; attributes[i++].ti_Data = win->BorderLeft;
206 attributes[i].ti_Tag = AMA_Top; attributes[i++].ti_Data = win->BorderTop;
207 attributes[i].ti_Tag = AMA_Bottom; attributes[i++].ti_Data = win->BorderBottom;
208 attributes[i].ti_Tag = AMA_Right; attributes[i++].ti_Data = win->BorderRight;
210 // double buffer ?
211 attributes[i].ti_Tag = AMA_DoubleBuf; attributes[i++].ti_Data = GL_TRUE;
213 // RGB(A) Mode ?
214 attributes[i].ti_Tag = AMA_RGBMode; attributes[i++].ti_Data = GL_TRUE;
216 /* Stencil/Accum */
217 attributes[i].ti_Tag = AMA_NoStencil; attributes[i++].ti_Data = GL_TRUE;
218 attributes[i].ti_Tag = AMA_NoAccum; attributes[i++].ti_Data = GL_TRUE;
220 // done...
221 attributes[i].ti_Tag = TAG_DONE;
223 glcont = AROSMesaCreateContext(attributes);
224 if (glcont)
226 AROSMesaMakeCurrent(glcont);
227 h = (GLfloat)VISIBLE_HEIGHT / (GLfloat)VISIBLE_WIDTH ;
229 glViewport(0, 0, (GLint) VISIBLE_WIDTH, (GLint) VISIBLE_HEIGHT);
230 #if USE_PERSPECTIVE == 1
231 glMatrixMode(GL_PROJECTION);
232 glLoadIdentity();
233 glFrustum(-1.0, 1.0, -h, h, 5.0, 200.0);
234 glMatrixMode(GL_MODELVIEW);
235 #endif
236 prepare_shader_program();
237 glUseProgram(shaderProgram);
238 angleLocation = glGetUniformLocation(shaderProgram, "angle");
240 else
241 finished = TRUE; /* Failure. Stop */
244 void deinitmesa()
246 if (glcont)
248 cleanup_shader_program();
249 AROSMesaDestroyContext(glcont);
253 static int init_timerbase()
255 timeport.mp_Node.ln_Type = NT_MSGPORT;
256 timeport.mp_Node.ln_Pri = 0;
257 timeport.mp_Node.ln_Name = NULL;
258 timeport.mp_Flags = PA_IGNORE;
259 timeport.mp_SigTask = FindTask(NULL);
260 timeport.mp_SigBit = 0;
261 NEWLIST(&timeport.mp_MsgList);
263 timereq.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
264 timereq.tr_node.io_Message.mn_Node.ln_Pri = 0;
265 timereq.tr_node.io_Message.mn_Node.ln_Name = NULL;
266 timereq.tr_node.io_Message.mn_ReplyPort = &timeport;
267 timereq.tr_node.io_Message.mn_Length = sizeof (timereq);
269 if(OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)&timereq,0) == 0)
271 TimerBase = (struct Device *)timereq.tr_node.io_Device;
272 return 1;
274 else
276 return 0;
281 static void deinit_timerbase()
283 if (TimerBase != NULL)
284 CloseDevice((struct IORequest *)&timereq);
288 void HandleIntuiMessages(void)
290 struct IntuiMessage *msg;
292 while((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
294 switch(msg->Class)
296 case IDCMP_CLOSEWINDOW:
297 finished = TRUE;
298 break;
299 case IDCMP_VANILLAKEY:
300 if (msg->Code == 27 /* ESC */) finished = TRUE;
301 break;
303 ReplyMsg((struct Message *)msg);
308 #define ARG_FULLSCREEN 0
309 #define NUM_ARGS 1
311 STATIC CONST_STRPTR TEMPLATE=(CONST_STRPTR) "FULLSCREEN/S";
312 static struct RDArgs *myargs;
313 static IPTR args[NUM_ARGS];
315 void get_arguments(void)
317 if((myargs = ReadArgs(TEMPLATE, args, NULL)))
319 fullscreen = (BOOL)args[ARG_FULLSCREEN];
320 FreeArgs(myargs);
325 ** Open a simple window using OpenWindowTagList()
327 int main(void)
329 ULONG fps = 0;
330 // ULONG exitcounter = 0;
331 TEXT title[100];
332 struct Screen * pubscreen = NULL;
333 struct Screen * customscreen = NULL;
334 LONG modeid;
336 struct timeval tv;
337 UQUAD lastmicrosecs = 0L;
338 UQUAD currmicrosecs = 0L;
339 UQUAD fpsmicrosecs = 0L;
341 get_arguments();
343 init_timerbase();
345 GetSysTime(&tv);
346 lastmicrosecs = tv.tv_secs * 1000000 + tv.tv_micro;
347 fpsmicrosecs = lastmicrosecs;
349 if (fullscreen)
351 CyberGfxBase = OpenLibrary("cybergraphics.library", 0L);
353 modeid = BestCModeIDTags(CYBRBIDTG_NominalWidth, VISIBLE_WIDTH,
354 CYBRBIDTG_NominalHeight, VISIBLE_HEIGHT,
355 TAG_DONE);
357 customscreen = OpenScreenTags(NULL,
358 SA_Type, CUSTOMSCREEN,
359 SA_DisplayID, modeid,
360 SA_Width, VISIBLE_WIDTH,
361 SA_Height, VISIBLE_HEIGHT,
362 SA_ShowTitle, FALSE,
363 SA_Quiet, TRUE,
364 TAG_DONE);
366 win = OpenWindowTags(NULL,
367 WA_Left, 0,
368 WA_Top, 200,
369 WA_InnerWidth, VISIBLE_WIDTH,
370 WA_InnerHeight, VISIBLE_HEIGHT,
371 WA_CustomScreen, (IPTR)customscreen,
372 WA_Flags, WFLG_ACTIVATE | WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_RMBTRAP,
373 WA_IDCMP, IDCMP_VANILLAKEY,
374 TAG_DONE);
376 else
378 if ((pubscreen = LockPubScreen(NULL)) == NULL) return 1;
380 win = OpenWindowTags(0,
381 WA_Title, (IPTR)"MesaSimpleRendering",
382 WA_PubScreen, pubscreen,
383 WA_CloseGadget, TRUE,
384 WA_DragBar, TRUE,
385 WA_DepthGadget, TRUE,
386 WA_Left, 50,
387 WA_Top, 200,
388 WA_InnerWidth, VISIBLE_WIDTH,
389 WA_InnerHeight, VISIBLE_HEIGHT,
390 WA_Activate, TRUE,
391 WA_RMBTrap, TRUE,
392 WA_SimpleRefresh, TRUE,
393 WA_NoCareRefresh, TRUE,
394 WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW,
395 TAG_DONE);
397 UnlockPubScreen(NULL, pubscreen);
400 initmesa();
401 // finished = TRUE;
402 while(!finished)
404 GetSysTime(&tv);
405 currmicrosecs = tv.tv_secs * 1000000 + tv.tv_micro;
407 if (currmicrosecs - fpsmicrosecs > 1000000)
409 /* FPS counting is naive! */
410 fpsmicrosecs += 1000000;
411 sprintf(title, "MesaSimpleRendering, FPS: %d", fps);
412 SetWindowTitles(win, title, (UBYTE *)~0L);
413 fps = 0;
416 angle_inc = ((double)(currmicrosecs - lastmicrosecs) / 1000000.0) * DEGREES_PER_SECOND;
417 lastmicrosecs = currmicrosecs;
419 fps++;
420 render();
421 HandleIntuiMessages();
422 // exitcounter++;
423 // Delay(10);
424 // if (exitcounter > 0) finished = TRUE;
427 deinitmesa();
429 deinit_timerbase();
431 CloseWindow(win);
433 if (customscreen) CloseScreen(customscreen);
435 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
437 return 0;