2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
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>
24 GLAContext glcont
=NULL
;
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;"
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);"
67 const GLchar
* vertexShaderSource
=
70 " gl_FrontColor = gl_Color;"
71 " gl_Position = ftransform();"
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};
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
);
107 void cleanup_shader_program()
110 glDetachShader(shaderProgram
, fragmentShader
);
111 glDetachShader(shaderProgram
, vertexShader
);
112 glDeleteShader(fragmentShader
);
113 glDeleteShader(vertexShader
);
114 glDeleteProgram(shaderProgram
);
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);
135 glRotatef(0.0, 0.0, 1.0, 0.0);
136 glTranslatef(0.0, 0.0, 0.25);
142 glRotatef(90.0, 0.0, 1.0, 0.0);
143 glTranslatef(0.0, 0.0, 0.25);
148 glRotatef(180.0, 0.0, 1.0, 0.0);
149 glTranslatef(0.0, 0.0, 0.25);
154 glRotatef(270.0, 0.0, 1.0, 0.0);
155 glTranslatef(0.0, 0.0, 0.25);
160 glRotatef(90.0, 1.0, 0.0, 0.0);
161 glTranslatef(0.0, 0.0, 0.25);
166 glRotatef(-90.0, 1.0, 0.0, 0.0);
167 glTranslatef(0.0, 0.0, 0.25);
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);
187 glClearColor(0.3, 0.3, 0.3, 1.0);
188 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
190 glDepthFunc(GL_LESS
);
191 glEnable(GL_DEPTH_TEST
);
192 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
196 glUniform1f(angleLocation
, angle
);
198 #if USE_PERSPECTIVE == 1
199 glTranslatef(0.0, 0.0, -6.0);
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);
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");
237 struct TagItem attributes
[ 14 ]; /* 14 should be more than enough :) */
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
;
248 attributes
[i
].ti_Tag
= GLA_DoubleBuf
; attributes
[i
++].ti_Data
= GL_TRUE
;
251 attributes
[i
].ti_Tag
= GLA_RGBMode
; attributes
[i
++].ti_Data
= GL_TRUE
;
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
;
258 attributes
[i
].ti_Tag
= TAG_DONE
;
260 glcont
= glACreateContext(attributes
);
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
);
270 glFrustum(-1.0, 1.0, -h
, h
, 5.0, 200.0);
271 glMatrixMode(GL_MODELVIEW
);
274 prepare_shader_program();
275 glUseProgram(shaderProgram
);
276 angleLocation
= glGetUniformLocation(shaderProgram
, "angle");
279 finished
= TRUE
; /* Failure. Stop */
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
;
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
)))
334 case IDCMP_CLOSEWINDOW
:
337 case IDCMP_VANILLAKEY
:
338 if (msg
->Code
== 27 /* ESC */) finished
= TRUE
;
341 ReplyMsg((struct Message
*)msg
);
346 #define ARG_FULLSCREEN 0
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
];
363 ** Open a simple window using OpenWindowTagList()
368 // ULONG exitcounter = 0;
370 struct Screen
* pubscreen
= NULL
;
371 struct Screen
* customscreen
= NULL
;
375 UQUAD lastmicrosecs
= 0L;
376 UQUAD currmicrosecs
= 0L;
377 UQUAD fpsmicrosecs
= 0L;
384 lastmicrosecs
= tv
.tv_secs
* 1000000 + tv
.tv_micro
;
385 fpsmicrosecs
= lastmicrosecs
;
389 CyberGfxBase
= OpenLibrary("cybergraphics.library", 0L);
391 modeid
= BestCModeIDTags(CYBRBIDTG_NominalWidth
, VISIBLE_WIDTH
,
392 CYBRBIDTG_NominalHeight
, VISIBLE_HEIGHT
,
395 customscreen
= OpenScreenTags(NULL
,
396 SA_Type
, CUSTOMSCREEN
,
397 SA_DisplayID
, modeid
,
398 SA_Width
, VISIBLE_WIDTH
,
399 SA_Height
, VISIBLE_HEIGHT
,
404 win
= OpenWindowTags(NULL
,
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
,
416 if ((pubscreen
= LockPubScreen(NULL
)) == NULL
) return 1;
418 win
= OpenWindowTags(0,
419 WA_Title
, (IPTR
)"GLSimpleRendering",
420 WA_PubScreen
, pubscreen
,
421 WA_CloseGadget
, TRUE
,
423 WA_DepthGadget
, TRUE
,
426 WA_InnerWidth
, VISIBLE_WIDTH
,
427 WA_InnerHeight
, VISIBLE_HEIGHT
,
430 WA_SimpleRefresh
, TRUE
,
431 WA_NoCareRefresh
, TRUE
,
432 WA_IDCMP
, IDCMP_VANILLAKEY
| IDCMP_CLOSEWINDOW
,
435 UnlockPubScreen(NULL
, pubscreen
);
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
, "GLSimpleRendering, FPS: %d", (int)fps
);
450 SetWindowTitles(win
, title
, (UBYTE
*)~0L);
454 angle_inc
= ((double)(currmicrosecs
- lastmicrosecs
) / 1000000.0) * DEGREES_PER_SECOND
;
455 lastmicrosecs
= currmicrosecs
;
459 HandleIntuiMessages();
462 // if (exitcounter > 0) finished = TRUE;
471 if (customscreen
) CloseScreen(customscreen
);
473 if (CyberGfxBase
) CloseLibrary(CyberGfxBase
);