rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@1
|
3 #include <math.h>
|
nuclear@0
|
4 #include <GL/glew.h>
|
nuclear@0
|
5 #include <GL/glut.h>
|
nuclear@0
|
6 #include "sdr.h"
|
nuclear@0
|
7
|
nuclear@0
|
8 int init(void);
|
nuclear@0
|
9 void cleanup(void);
|
nuclear@0
|
10 void disp(void);
|
nuclear@0
|
11 void reshape(int x, int y);
|
nuclear@1
|
12 void keydown(unsigned char key, int x, int y);
|
nuclear@1
|
13 void keyup(unsigned char key, int x, int y);
|
nuclear@0
|
14 void mouse(int bn, int st, int x, int y);
|
nuclear@0
|
15 void motion(int x, int y);
|
nuclear@0
|
16
|
nuclear@1
|
17 static int win_width = 1280, win_height = 800;
|
nuclear@1
|
18 static float win_aspect;
|
nuclear@1
|
19 static int mouse_x = 640, mouse_y = 400;
|
nuclear@0
|
20 static unsigned int prog_mbrot;
|
nuclear@0
|
21
|
nuclear@1
|
22 static float view_center[2] = {0.7, 0.0};
|
nuclear@1
|
23 static float view_scale = 1.2;
|
nuclear@1
|
24
|
nuclear@1
|
25
|
nuclear@0
|
26 int main(int argc, char **argv)
|
nuclear@0
|
27 {
|
nuclear@0
|
28 glutInit(&argc, argv);
|
nuclear@0
|
29 glutInitWindowSize(1280, 800);
|
nuclear@0
|
30 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
nuclear@0
|
31 glutCreateWindow("fractorb");
|
nuclear@0
|
32
|
nuclear@0
|
33 glutDisplayFunc(disp);
|
nuclear@0
|
34 glutReshapeFunc(reshape);
|
nuclear@1
|
35 glutKeyboardFunc(keydown);
|
nuclear@1
|
36 glutKeyboardUpFunc(keyup);
|
nuclear@0
|
37 glutMouseFunc(mouse);
|
nuclear@0
|
38 glutMotionFunc(motion);
|
nuclear@0
|
39
|
nuclear@0
|
40 if(init() == -1) {
|
nuclear@0
|
41 return 1;
|
nuclear@0
|
42 }
|
nuclear@0
|
43 atexit(cleanup);
|
nuclear@0
|
44
|
nuclear@0
|
45 glutMainLoop();
|
nuclear@0
|
46 return 0;
|
nuclear@0
|
47 }
|
nuclear@0
|
48
|
nuclear@0
|
49
|
nuclear@0
|
50 int init(void)
|
nuclear@0
|
51 {
|
nuclear@0
|
52 glewInit();
|
nuclear@0
|
53
|
nuclear@0
|
54 if(!(prog_mbrot = create_program_load("vertex.glsl", "mbrot.glsl"))) {
|
nuclear@0
|
55 return -1;
|
nuclear@0
|
56 }
|
nuclear@0
|
57 return 0;
|
nuclear@0
|
58 }
|
nuclear@0
|
59
|
nuclear@0
|
60 void cleanup(void)
|
nuclear@0
|
61 {
|
nuclear@0
|
62 free_program(prog_mbrot);
|
nuclear@0
|
63 }
|
nuclear@0
|
64
|
nuclear@1
|
65 void pixel_to_complex(float *res, float px, float py)
|
nuclear@1
|
66 {
|
nuclear@1
|
67 float u = (2.0 * px / win_width - 1.0) * win_aspect;
|
nuclear@1
|
68 float v = 2.0 * py / win_height - 1.0;
|
nuclear@1
|
69 res[0] = u * view_scale - view_center[0];
|
nuclear@1
|
70 res[1] = v * view_scale - view_center[1];
|
nuclear@1
|
71 }
|
nuclear@1
|
72
|
nuclear@0
|
73 void disp(void)
|
nuclear@0
|
74 {
|
nuclear@1
|
75 int i;
|
nuclear@1
|
76 float seed[2];
|
nuclear@1
|
77 static const float verts[][2] = {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}};
|
nuclear@1
|
78 static const float corners[][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
|
nuclear@1
|
79
|
nuclear@1
|
80 pixel_to_complex(seed, mouse_x, mouse_y);
|
nuclear@1
|
81
|
nuclear@1
|
82 set_uniform_float2(prog_mbrot, "seed", seed[0], seed[1]);
|
nuclear@1
|
83 set_uniform_float(prog_mbrot, "view_scale", view_scale);
|
nuclear@1
|
84 set_uniform_float2(prog_mbrot, "view_center", view_center[0], view_center[1]);
|
nuclear@0
|
85 glUseProgram(prog_mbrot);
|
nuclear@0
|
86
|
nuclear@0
|
87 glBegin(GL_QUADS);
|
nuclear@1
|
88 for(i=0; i<4; i++) {
|
nuclear@1
|
89 float bv[2];
|
nuclear@1
|
90 pixel_to_complex(bv, (win_width - 1) * corners[i][0], (win_height - 1) * corners[i][1]);
|
nuclear@1
|
91 glTexCoord2f(bv[0], bv[1]);
|
nuclear@1
|
92 glVertex2f(verts[i][0], verts[i][1]);
|
nuclear@1
|
93 }
|
nuclear@0
|
94 glEnd();
|
nuclear@0
|
95
|
nuclear@0
|
96 glutSwapBuffers();
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 void reshape(int x, int y)
|
nuclear@0
|
100 {
|
nuclear@0
|
101 glViewport(0, 0, x, y);
|
nuclear@0
|
102
|
nuclear@1
|
103 win_aspect = (float)x / (float)y;
|
nuclear@1
|
104 win_width = x;
|
nuclear@1
|
105 win_height = y;
|
nuclear@0
|
106 }
|
nuclear@0
|
107
|
nuclear@1
|
108 static int keystate[256];
|
nuclear@1
|
109
|
nuclear@1
|
110 void keydown(unsigned char key, int x, int y)
|
nuclear@0
|
111 {
|
nuclear@1
|
112 static int fullscreen;
|
nuclear@1
|
113 static int prev_width, prev_height;
|
nuclear@1
|
114
|
nuclear@1
|
115 switch(key) {
|
nuclear@1
|
116 case 27:
|
nuclear@0
|
117 exit(0);
|
nuclear@1
|
118
|
nuclear@1
|
119 case 'f':
|
nuclear@1
|
120 fullscreen = !fullscreen;
|
nuclear@1
|
121 if(fullscreen) {
|
nuclear@1
|
122 prev_width = win_width;
|
nuclear@1
|
123 prev_height = win_height;
|
nuclear@1
|
124 glutFullScreen();
|
nuclear@1
|
125 } else {
|
nuclear@1
|
126 glutReshapeWindow(prev_width, prev_height);
|
nuclear@1
|
127 }
|
nuclear@1
|
128 break;
|
nuclear@1
|
129
|
nuclear@1
|
130 default:
|
nuclear@1
|
131 break;
|
nuclear@0
|
132 }
|
nuclear@1
|
133 keystate[key] = 1;
|
nuclear@0
|
134 }
|
nuclear@0
|
135
|
nuclear@1
|
136 void keyup(unsigned char key, int x, int y)
|
nuclear@1
|
137 {
|
nuclear@1
|
138 keystate[key] = 0;
|
nuclear@1
|
139 }
|
nuclear@1
|
140
|
nuclear@1
|
141 static int prev_x, prev_y;
|
nuclear@1
|
142 static int bnstate[8];
|
nuclear@1
|
143
|
nuclear@0
|
144 void mouse(int bn, int st, int x, int y)
|
nuclear@0
|
145 {
|
nuclear@1
|
146 prev_x = x;
|
nuclear@1
|
147 prev_y = y;
|
nuclear@1
|
148 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN ? 1 : 0;
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 void motion(int x, int y)
|
nuclear@0
|
152 {
|
nuclear@1
|
153 int dx = x - prev_x;
|
nuclear@1
|
154 int dy = y - prev_y;
|
nuclear@1
|
155 prev_x = x;
|
nuclear@1
|
156 prev_y = y;
|
nuclear@1
|
157
|
nuclear@1
|
158 if(!(dx | dy)) return;
|
nuclear@1
|
159
|
nuclear@1
|
160 if(bnstate[0]) {
|
nuclear@1
|
161 if(keystate['s']) {
|
nuclear@1
|
162 mouse_x = x;
|
nuclear@1
|
163 mouse_y = y;
|
nuclear@1
|
164 } else if(keystate['z']) {
|
nuclear@1
|
165 float s = sqrt(view_scale);
|
nuclear@1
|
166 view_scale += dy * 0.01 * s;
|
nuclear@1
|
167 if(view_scale < 1e-8) view_scale = 1e-8;
|
nuclear@1
|
168 } else {
|
nuclear@1
|
169 float s = sqrt(view_scale);
|
nuclear@1
|
170 view_center[0] += 0.01 * dx * s;
|
nuclear@1
|
171 view_center[1] += 0.01 * dy * s;
|
nuclear@1
|
172 }
|
nuclear@1
|
173 glutPostRedisplay();
|
nuclear@1
|
174 }
|
nuclear@0
|
175 }
|