proj_plot
changeset 0:e467998dcc64
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 24 Jan 2015 16:36:34 +0200 |
parents | |
children | 64483c640a38 |
files | .hgignore Makefile README data/font.ttf main.cc |
diffstat | 5 files changed, 239 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Sat Jan 24 16:36:34 2015 +0200 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +^proj_plot$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Sat Jan 24 16:36:34 2015 +0200 2.3 @@ -0,0 +1,13 @@ 2.4 +src = $(wildcard *.cc) 2.5 +obj = $(src:.cc=.o) 2.6 +bin = proj_plot 2.7 + 2.8 +CXXFLAGS = -pedantic -Wall -g 2.9 +LDFLAGS = -lGL -lglut -lm -lvmath -ldrawtext 2.10 + 2.11 +$(bin): $(obj) 2.12 + $(CXX) -o $@ $(obj) $(LDFLAGS) 2.13 + 2.14 +.PHONY: clean 2.15 +clean: 2.16 + rm -f $(obj) $(bin)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/README Sat Jan 24 16:36:34 2015 +0200 3.3 @@ -0,0 +1,3 @@ 3.4 +dependencies: 3.5 +- libvmath: http://code.google.com/p/libvmath/ 3.6 +- libdrawtext: http://nuclear.mutantstargoat.com/sw/libdrawtext
4.1 Binary file data/font.ttf has changed
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/main.cc Sat Jan 24 16:36:34 2015 +0200 5.3 @@ -0,0 +1,219 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdlib.h> 5.6 +#include <stdarg.h> 5.7 +#include <assert.h> 5.8 +#include <GL/glut.h> 5.9 +#include <vmath/vmath.h> 5.10 +#include <drawtext.h> 5.11 + 5.12 +bool init(); 5.13 +void display(); 5.14 +void draw_grid(); 5.15 +void draw_label(const Vector2 &pos, const char *fmt, ...); 5.16 +void reshape(int x, int y); 5.17 +void keyb(unsigned char key, int x, int y); 5.18 +void keyb_up(unsigned char key, int x, int y); 5.19 +void mouse(int bn, int st, int x, int y); 5.20 +void motion(int x, int y); 5.21 +Vector2 screen_to_world(int x, int y); 5.22 + 5.23 +int win_xsz, win_ysz; 5.24 +float aspect; 5.25 + 5.26 +Matrix4x4 proj; 5.27 +Vector2 cur_point; 5.28 +bool cur_point_valid; 5.29 + 5.30 +bool keystate[256]; 5.31 +dtx_font *font; 5.32 +float pan[2], zoom = 1.0; 5.33 + 5.34 +int main(int argc, char **argv) 5.35 +{ 5.36 + glutInit(&argc, argv); 5.37 + glutInitWindowSize(1024, 768); 5.38 + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE); 5.39 + glutCreateWindow("Interactive projection diagram"); 5.40 + 5.41 + glutDisplayFunc(display); 5.42 + glutReshapeFunc(reshape); 5.43 + glutKeyboardFunc(keyb); 5.44 + glutKeyboardUpFunc(keyb_up); 5.45 + glutMouseFunc(mouse); 5.46 + glutMotionFunc(motion); 5.47 + 5.48 + if(!init()) { 5.49 + return 1; 5.50 + } 5.51 + 5.52 + glutMainLoop(); 5.53 + return 0; 5.54 +} 5.55 + 5.56 +bool init() 5.57 +{ 5.58 + if(!(font = dtx_open_font("data/font.ttf", 16))) { 5.59 + fprintf(stderr, "failed to open font\n"); 5.60 + return false; 5.61 + } 5.62 + 5.63 + glEnable(GL_MULTISAMPLE); 5.64 + proj.set_perspective(DEG_TO_RAD(60), 1, 0.5, 500.0); 5.65 + return true; 5.66 +} 5.67 + 5.68 +void display() 5.69 +{ 5.70 + glClear(GL_COLOR_BUFFER_BIT); 5.71 + 5.72 + glMatrixMode(GL_MODELVIEW); 5.73 + glLoadIdentity(); 5.74 + glTranslatef(-pan[0], -pan[1], 0); 5.75 + glScalef(zoom, zoom, zoom); 5.76 + 5.77 + draw_grid(); 5.78 + 5.79 + if(cur_point_valid) { 5.80 + glPointSize(7.0); 5.81 + glBegin(GL_POINTS); 5.82 + glColor3f(0.2, 1, 0.2); 5.83 + glVertex2f(cur_point.x, cur_point.y); 5.84 + glEnd(); 5.85 + 5.86 + glColor3f(0.15, 0.5, 0.15); 5.87 + draw_label(cur_point, "(%.2f, %.2f)", cur_point.x, cur_point.y); 5.88 + } 5.89 + 5.90 + glutSwapBuffers(); 5.91 + assert(glGetError() == GL_NO_ERROR); 5.92 +} 5.93 + 5.94 +#define LINE(x0, y0, x1, y1) (glVertex2f(x0, y0), glVertex2f(x1, y1)) 5.95 + 5.96 +void draw_grid() 5.97 +{ 5.98 + float ymin = -1; 5.99 + float ymax = 1; 5.100 + float xmin = -1; 5.101 + float xmax = 1; 5.102 + float ticksz = 0.015; 5.103 + 5.104 + glBegin(GL_LINES); 5.105 + glColor3f(1, 1, 1); 5.106 + LINE(0, -1, 0, 1); 5.107 + LINE(-1, 0, 1, 0); 5.108 + 5.109 + for(int i=1; i<11; i++) { 5.110 + for(int j=0; j<2; j++) { 5.111 + float x = (float)i / 10.0 * (j ? -1.0 : 1.0); 5.112 + 5.113 + glColor3f(0.15, 0.15, 0.15); 5.114 + LINE(x, ymin, x, ymax); 5.115 + LINE(xmin, x, xmax, x); 5.116 + 5.117 + glColor3f(0.4, 0.4, 0.4); 5.118 + LINE(x, -ticksz, x, ticksz); 5.119 + LINE(-ticksz, x, ticksz, x); 5.120 + } 5.121 + } 5.122 + glEnd(); 5.123 +} 5.124 + 5.125 +void draw_label(const Vector2 &pos, const char *fmt, ...) 5.126 +{ 5.127 + static char buf[512]; 5.128 + va_list ap; 5.129 + 5.130 + va_start(ap, fmt); 5.131 + vsnprintf(buf, sizeof buf - 1, fmt, ap); 5.132 + va_end(ap); 5.133 + 5.134 + glPushMatrix(); 5.135 + glTranslatef(pos.x + 0.01, pos.y + 0.01, 0); 5.136 + float s = 2.0 / (win_ysz * zoom); 5.137 + glScalef(s, s, s); 5.138 + 5.139 + dtx_string(buf); 5.140 + 5.141 + glPopMatrix(); 5.142 +} 5.143 + 5.144 +void reshape(int x, int y) 5.145 +{ 5.146 + win_xsz = x; 5.147 + win_ysz = y; 5.148 + aspect = (float)x / (float)y; 5.149 + 5.150 + glViewport(0, 0, x, y); 5.151 + 5.152 + glMatrixMode(GL_PROJECTION); 5.153 + glLoadIdentity(); 5.154 + glScalef(1.0 / aspect, 1.0, 1.0); 5.155 +} 5.156 + 5.157 +void keyb(unsigned char key, int x, int y) 5.158 +{ 5.159 + keystate[key] = 1; 5.160 + 5.161 + switch(key) { 5.162 + case 27: 5.163 + exit(0); 5.164 + } 5.165 +} 5.166 + 5.167 +void keyb_up(unsigned char key, int x, int y) 5.168 +{ 5.169 + keystate[key] = 0; 5.170 +} 5.171 + 5.172 +bool bnstate[16]; 5.173 +int prev_x, prev_y; 5.174 + 5.175 +void mouse(int bn, int st, int x, int y) 5.176 +{ 5.177 + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN; 5.178 + prev_x = x; 5.179 + prev_y = y; 5.180 + 5.181 + if(bn == GLUT_LEFT_BUTTON && st == GLUT_DOWN) { 5.182 + cur_point = screen_to_world(x, y); 5.183 + cur_point_valid = true; 5.184 + glutPostRedisplay(); 5.185 + } 5.186 +} 5.187 + 5.188 +void motion(int x, int y) 5.189 +{ 5.190 + float dx = 2.0 * aspect * (x - prev_x) / (float)win_xsz; 5.191 + float dy = 2.0 * (y - prev_y) / (float)win_ysz; 5.192 + prev_x = x; 5.193 + prev_y = y; 5.194 + 5.195 + if(bnstate[0]) { 5.196 + cur_point = screen_to_world(x, y); 5.197 + glutPostRedisplay(); 5.198 + } 5.199 + if(bnstate[1]) { 5.200 + pan[0] -= dx; 5.201 + pan[1] += dy; 5.202 + 5.203 + glutPostRedisplay(); 5.204 + } 5.205 + if(bnstate[2]) { 5.206 + zoom += dy; 5.207 + 5.208 + if(zoom < 1e-4) zoom = 1e-4; 5.209 + glutPostRedisplay(); 5.210 + } 5.211 +} 5.212 + 5.213 +Vector2 screen_to_world(int px, int py) 5.214 +{ 5.215 + float sx = 2.0 * aspect * (1.0 / zoom) / (float)win_xsz; 5.216 + float sy = 2.0 * (1.0 / zoom) / (float)win_ysz; 5.217 + 5.218 + float x = (float)px * sx - (aspect + pan[0]) / zoom; 5.219 + float y = (float)(win_ysz - py) * sy - (1.0 + pan[1]) / zoom; 5.220 + 5.221 + return Vector2(x, y); 5.222 +}