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>
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>
20 AROSMesaContext glcont
=NULL
;
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;"
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);"
48 const GLchar
* vertexShaderSource
=
51 " gl_FrontColor = gl_Color;"
52 " gl_Position = ftransform();"
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};
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
);
88 void cleanup_shader_program()
91 glDetachShader(shaderProgram
, fragmentShader
);
92 glDetachShader(shaderProgram
, vertexShader
);
93 glDeleteShader(fragmentShader
);
94 glDeleteShader(vertexShader
);
95 glDeleteProgram(shaderProgram
);
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);
116 glRotatef(0.0, 0.0, 1.0, 0.0);
117 glTranslatef(0.0, 0.0, 0.25);
123 glRotatef(90.0, 0.0, 1.0, 0.0);
124 glTranslatef(0.0, 0.0, 0.25);
129 glRotatef(180.0, 0.0, 1.0, 0.0);
130 glTranslatef(0.0, 0.0, 0.25);
135 glRotatef(270.0, 0.0, 1.0, 0.0);
136 glTranslatef(0.0, 0.0, 0.25);
141 glRotatef(90.0, 1.0, 0.0, 0.0);
142 glTranslatef(0.0, 0.0, 0.25);
147 glRotatef(-90.0, 1.0, 0.0, 0.0);
148 glTranslatef(0.0, 0.0, 0.25);
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);
168 glClearColor(0.3, 0.3, 0.3, 1.0);
169 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
171 glDepthFunc(GL_LESS
);
172 glEnable(GL_DEPTH_TEST
);
173 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
177 glUniform1f(angleLocation
, angle
);
179 #if USE_PERSPECTIVE == 1
180 glTranslatef(0.0, 0.0, -6.0);
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);
190 glDisable(GL_DEPTH_TEST
);
192 AROSMesaSwapBuffers(glcont
);
195 #define VISIBLE_WIDTH 300
196 #define VISIBLE_HEIGHT 300
200 struct TagItem attributes
[ 14 ]; /* 14 should be more than enough :) */
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
;
211 attributes
[i
].ti_Tag
= AMA_DoubleBuf
; attributes
[i
++].ti_Data
= GL_TRUE
;
214 attributes
[i
].ti_Tag
= AMA_RGBMode
; attributes
[i
++].ti_Data
= GL_TRUE
;
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
;
221 attributes
[i
].ti_Tag
= TAG_DONE
;
223 glcont
= AROSMesaCreateContext(attributes
);
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
);
233 glFrustum(-1.0, 1.0, -h
, h
, 5.0, 200.0);
234 glMatrixMode(GL_MODELVIEW
);
236 prepare_shader_program();
237 glUseProgram(shaderProgram
);
238 angleLocation
= glGetUniformLocation(shaderProgram
, "angle");
241 finished
= TRUE
; /* Failure. Stop */
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
;
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
)))
296 case IDCMP_CLOSEWINDOW
:
299 case IDCMP_VANILLAKEY
:
300 if (msg
->Code
== 27 /* ESC */) finished
= TRUE
;
303 ReplyMsg((struct Message
*)msg
);
308 #define ARG_FULLSCREEN 0
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
];
325 ** Open a simple window using OpenWindowTagList()
330 // ULONG exitcounter = 0;
332 struct Screen
* pubscreen
= NULL
;
333 struct Screen
* customscreen
= NULL
;
337 UQUAD lastmicrosecs
= 0L;
338 UQUAD currmicrosecs
= 0L;
339 UQUAD fpsmicrosecs
= 0L;
346 lastmicrosecs
= tv
.tv_secs
* 1000000 + tv
.tv_micro
;
347 fpsmicrosecs
= lastmicrosecs
;
351 CyberGfxBase
= OpenLibrary("cybergraphics.library", 0L);
353 modeid
= BestCModeIDTags(CYBRBIDTG_NominalWidth
, VISIBLE_WIDTH
,
354 CYBRBIDTG_NominalHeight
, VISIBLE_HEIGHT
,
357 customscreen
= OpenScreenTags(NULL
,
358 SA_Type
, CUSTOMSCREEN
,
359 SA_DisplayID
, modeid
,
360 SA_Width
, VISIBLE_WIDTH
,
361 SA_Height
, VISIBLE_HEIGHT
,
366 win
= OpenWindowTags(NULL
,
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
,
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
,
385 WA_DepthGadget
, TRUE
,
388 WA_InnerWidth
, VISIBLE_WIDTH
,
389 WA_InnerHeight
, VISIBLE_HEIGHT
,
392 WA_SimpleRefresh
, TRUE
,
393 WA_NoCareRefresh
, TRUE
,
394 WA_IDCMP
, IDCMP_VANILLAKEY
| IDCMP_CLOSEWINDOW
,
397 UnlockPubScreen(NULL
, pubscreen
);
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", (int)fps
);
412 SetWindowTitles(win
, title
, (UBYTE
*)~0L);
416 angle_inc
= ((double)(currmicrosecs
- lastmicrosecs
) / 1000000.0) * DEGREES_PER_SECOND
;
417 lastmicrosecs
= currmicrosecs
;
421 HandleIntuiMessages();
424 // if (exitcounter > 0) finished = TRUE;
433 if (customscreen
) CloseScreen(customscreen
);
435 if (CyberGfxBase
) CloseLibrary(CyberGfxBase
);