00001
00013
00014
00015 #if defined(USE_GL_2)
00016 #define GL_GLEXT_PROTOTYPES 1
00017 #define GL3_PROTOTYPES 1
00018 #endif
00019 #include "plotter_sdl.h"
00020 #include <SDL.h>
00021 #include <SDL_opengl.h>
00022
00023
00024 enum {
00025 SCREEN_WIDTH = 640,
00026 SCREEN_HEIGHT = 480,
00027 };
00028
00029
00030 typedef struct
00031 {
00032 GLfloat x;
00033 GLfloat y;
00034 } vector_t;
00035
00036
00037 static SDL_Surface *screen_ = NULL;
00038 static vector_t *points_ = NULL;
00039 static size_t max_points_size_ = 0;
00040 static size_t points_size_ = 0;
00041 static double draw_magnify_ = 0.1;
00042
00043
00044 static void opengl_initialize(void)
00045 {
00046 int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
00047
00048
00049 int rgb_size[3];
00050 switch (bpp) {
00051 case 8:
00052 rgb_size[0] = 3;
00053 rgb_size[1] = 3;
00054 rgb_size[2] = 2;
00055 break;
00056
00057 case 15:
00058 case 16:
00059 rgb_size[0] = 5;
00060 rgb_size[1] = 5;
00061 rgb_size[2] = 5;
00062 break;
00063
00064 default:
00065 rgb_size[0] = 8;
00066 rgb_size[1] = 8;
00067 rgb_size[2] = 8;
00068 break;
00069 }
00070 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]);
00071 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]);
00072 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]);
00073 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
00074 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00075
00076 }
00077
00078
00079 static void opengl_setup(void)
00080 {
00081 glPushAttrib(GL_ENABLE_BIT);
00082 glDisable(GL_DEPTH_TEST);
00083 glDisable(GL_CULL_FACE);
00084 glEnable(GL_TEXTURE_2D);
00085 glEnable(GL_BLEND);
00086 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00087
00088 glViewport(-1, -1, +1, +1);
00089 glMatrixMode(GL_PROJECTION);
00090 glLoadIdentity();
00091
00092 glOrtho(-1.0, +1.0, -1.0, +1.0, -10.0, +10.0);
00093
00094 glMatrixMode(GL_MODELVIEW);
00095 glLoadIdentity();
00096
00097 glEnable(GL_DEPTH_TEST);
00098 glDepthFunc(GL_LESS);
00099 glShadeModel(GL_SMOOTH);
00100 }
00101
00102
00103 static void draw_points(void)
00104 {
00105
00106 #if !defined(USE_GL_2)
00107 size_t i;
00108
00109 glBegin(GL_POINTS);
00110 for (i = 0; i < points_size_; ++i) {
00111 glVertex2i(points_[i].x, points_[i].y);
00112 }
00113 glEnd();
00114
00115 points_size_ = 0;
00116
00117 #else
00118 int memory_size = points_size * sizeof(points[0]);
00119
00120 glEnableClientState(GL_VERTEX_ARRAY);
00121 glEnableClientState(GL_COLOR_ARRAY);
00122
00123 glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
00124 glBufferData(GL_ARRAY_BUFFER, memory_size, points, GL_STATIC_DRAW);
00125
00126 glInterleavedArrays(GL_V2F, 0, NULL);
00127 glDrawArrays(GL_POINTS, 0, points_size);
00128 glBindBuffer(GL_ARRAY_BUFFER, 0);
00129
00130 glDisableClientState(GL_COLOR_ARRAY);
00131 glDisableClientState(GL_VERTEX_ARRAY);
00132
00133 points_size = 0;
00134 #endif
00135 }
00136
00137
00138 static void enter2D(void)
00139 {
00140 glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
00141
00142 glMatrixMode(GL_PROJECTION);
00143 glPushMatrix();
00144 glLoadIdentity();
00145
00146 glOrtho(0.0, SCREEN_WIDTH - 1.0, 0.0, SCREEN_HEIGHT - 1.0, 0.0, 1.0);
00147
00148 glMatrixMode(GL_MODELVIEW);
00149 glPushMatrix();
00150 glLoadIdentity();
00151
00152 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00153
00154 glTranslatef(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0.0);
00155 }
00156
00157
00158 bool plotter_initialize(int data_size)
00159 {
00160 points_ = malloc(data_size * sizeof(vector_t));
00161 if (!points_) {
00162 return false;
00163 }
00164 max_points_size_ = data_size;
00165
00166 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
00167 printf("SDL_Init: %s\n", SDL_GetError());
00168 return false;
00169 }
00170
00171
00172 opengl_initialize();
00173 screen_ = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_OPENGL);
00174 if (!screen_) {
00175 return false;
00176 }
00177 opengl_setup();
00178
00179
00180 glPointSize(2.0);
00181 #if defined(USE_GL_2)
00182 glGenBuffers(1, &buffer_id);
00183 #endif
00184 enter2D();
00185
00186
00187
00188
00189 return true;
00190 }
00191
00192
00193 void plotter_terminate(void)
00194 {
00195 SDL_Quit();
00196 }
00197
00198
00199 void plotter_clear(void)
00200 {
00201 glClearColor(0x00, 0x00, 0x00, 0xff);
00202 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00203 }
00204
00205
00206 void plotter_swap(void)
00207 {
00208
00209 draw_points();
00210
00211 SDL_GL_SwapBuffers();
00212 }
00213
00214
00215 void plotter_set_color(unsigned char r, unsigned g, unsigned b)
00216 {
00217
00218 draw_points();
00219
00220 glColor3f(r / 255.0, g / 255.0, b / 255.0);
00221 }
00222
00223
00224 void plotter_plot(float x, float y)
00225 {
00226 if (points_size_ >= max_points_size_) {
00227 return;
00228 }
00229
00230 points_[points_size_].x = draw_magnify_ * x;
00231 points_[points_size_].y = draw_magnify_ * y;
00232 ++points_size_;
00233 }
00234
00235
00236 bool plotter_is_quit(void)
00237 {
00238 bool is_quit = false;
00239 int magnify = 0;
00240
00241 SDL_Event event;
00242 while (SDL_PollEvent(&event)) {
00243 switch (event.type) {
00244
00245 case SDL_QUIT:
00246 is_quit = true;
00247 break;
00248
00249 case SDL_KEYDOWN:
00250 if ((event.key.keysym.sym == SDLK_q) ||
00251 (event.key.keysym.sym == SDLK_F4)) {
00252 is_quit = true;
00253 }
00254 if (event.key.keysym.sym == SDLK_COMMA) {
00255 --magnify;
00256 }
00257 if (event.key.keysym.sym == SDLK_PERIOD) {
00258 ++magnify;
00259 }
00260 break;
00261
00262 case SDL_MOUSEBUTTONDOWN:
00263 if (event.button.button == SDL_BUTTON_WHEELUP) {
00264 --magnify;
00265 } else if (event.button.button == SDL_BUTTON_WHEELDOWN) {
00266 ++magnify;
00267 }
00268 break;
00269 }
00270 }
00271
00272
00273 while (magnify < 0) {
00274 draw_magnify_ *= 0.90;
00275 ++magnify;
00276 }
00277 while (magnify > 0) {
00278 draw_magnify_ *= 1.10;
00279 --magnify;
00280 }
00281 if (draw_magnify_ < 0.001) {
00282 draw_magnify_ = 0.001;
00283 } else if (draw_magnify_ > 10.0) {
00284 draw_magnify_ = 10.0;
00285 }
00286
00287 return is_quit;
00288 }