commit d2664e2e784689b5ac2775c788d2aafb684b46bf
parent f5603085af570935531b0c18fe105ea6e8130d36
Author: Kyle Milz <kyle@0x30.net>
Date:   Mon,  9 Oct 2017 21:54:31 -0600
bin: deduplicate drawing code
- make citrun_gl and citrun_gltest use the same drawing code
- leave drawing code in gl_main.cc, add new gl.cc containing glfw code
- adds new object citrun::gl_main
Diffstat:
| M | bin/Jamfile |  |  | 5 | +++-- | 
| A | bin/gl.cc |  |  | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | bin/gl_main.cc |  |  | 131 | ++++++++++++++++++++++++++++--------------------------------------------------- | 
| A | bin/gl_main.h |  |  | 27 | +++++++++++++++++++++++++++ | 
| M | bin/gltest.cc |  |  | 89 | ++++++++++++++++++++----------------------------------------------------------- | 
5 files changed, 164 insertions(+), 153 deletions(-)
diff --git a/bin/Jamfile b/bin/Jamfile
@@ -61,6 +61,7 @@ GL_SRCS =
 	demo-shader.cc
 	gl_buffer.cc
 	gl_font.cc
+	gl_main.cc
 	gl_procfile.cc
 	gl_transunit.cc
 	gl_view.cc
@@ -73,7 +74,7 @@ Stringize demo_atlas_glsl.h :   demo_atlas.glsl ;
 Stringize demo_vshader_glsl.h : demo_vshader.glsl ;
 Stringize demo_fshader_glsl.h : demo_fshader.glsl ;
 
-ObjectC++Flags gl_main.cc gltest.cc $(GL_SRCS) : `pkg-config --cflags glfw3 glew freetype2` ;
+ObjectC++Flags gl.cc gltest.cc $(GL_SRCS) : `pkg-config --cflags glfw3 glew freetype2` ;
 
 LINKLIBS on citrun_gl += -lm $(GL_EXTRALIB) `pkg-config --libs glfw3 glew freetype2` ;
 LINKLIBS on citrun_gltest += -lm `pkg-config --libs glfw3 osmesa freetype2` ;
@@ -81,7 +82,7 @@ LINKLIBS on citrun_gltest += bin/glew-2.1.0/lib/libGLEW.a ;
 
 LinkLibraries citrun_gl citrun_gltest : gl_common libglyphy ;
 
-Main citrun_gl : gl_main.cc ;
+Main citrun_gl : gl.cc ;
 Main citrun_gltest : gltest.cc ;
 
 # Link with the c++ compiler so that the matching c++ runtime library gets added
diff --git a/bin/gl.cc b/bin/gl.cc
@@ -0,0 +1,65 @@
+#include <GL/glew.h>
+#include <GLFW/glfw3.h>
+#include <err.h>
+
+#include "gl_main.h"
+
+
+void
+keyboard_func(GLFWwindow *window, int key, int scancode, int action, int mods)
+{
+	//static_vu->keyboard_func(window, key, scancode, action, mods);
+}
+
+static void
+error_callback(int error, const char *desc)
+{
+	fprintf(stderr, "Error: %s\n", desc);
+}
+
+int
+main(int argc, char *argv[])
+{
+	GLFWwindow *window;
+
+	glfwSetErrorCallback(error_callback);
+
+	if (!glfwInit())
+		return 1;
+
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+	glfwWindowHint(GLFW_SRGB_CAPABLE, 1);
+
+	window = glfwCreateWindow(1600, 1200, "C It Run", NULL, NULL);
+	if (window == NULL) {
+		glfwTerminate();
+		return 1;
+	}
+
+	glfwSetKeyCallback(window, keyboard_func);
+
+	glfwMakeContextCurrent(window);
+	glfwSwapInterval(1);
+
+	GLenum glew_status = glewInit();
+	if (GLEW_OK != glew_status)
+		errx(1, "%s", glewGetErrorString(glew_status));
+	if (!glewIsSupported("GL_VERSION_2_0"))
+		errx(1, "No support for OpenGL 2.0 found");
+
+	citrun::gl_main main;
+
+	while (!glfwWindowShouldClose(window)) {
+
+		main.tick();
+
+		glfwSwapBuffers(window);
+		glfwPollEvents();
+	}
+
+	glfwDestroyWindow(window);
+	glfwTerminate();
+
+	return 0;
+}
diff --git a/bin/gl_main.cc b/bin/gl_main.cc
@@ -1,106 +1,69 @@
-#include <cmath>
-#include <GL/glew.h>
 #include <err.h>
-#include <iostream>
-#include <vector>
 
-#include "gl_buffer.h"
-#include "gl_font.h"
-#include "gl_procfile.h"
-#include "gl_view.h"
-#include "process_dir.h"
+#include "gl_main.h"
 
-#include <GLFW/glfw3.h>
+#if defined(__OpenBSD__)
+#define FONT_PATH "/usr/X11R6/lib/X11/fonts/TTF/DejaVuSansMono.ttf"
+#elif defined(__APPLE__)
+#define FONT_PATH "/Library/Fonts/Andale Mono.ttf"
+#elif defined(__gnu_linux__)
+#define FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"
+#elif defined(_WIN32)
+#define FONT_PATH ""
+#else
+#error "Font string not configured."
+#endif
 
-View *static_vu;
 
-void
-keyboard_func(GLFWwindow *window, int key, int scancode, int action, int mods)
-{
-	static_vu->keyboard_func(window, key, scancode, action, mods);
-}
-
-static void
-error_callback(int error, const char *desc)
-{
-	fprintf(stderr, "Error: %s\n", desc);
-}
-
-int
-main(int argc, char *argv[])
+citrun::gl_main::gl_main()
 {
-	GLFWwindow *window;
-
-	glfwSetErrorCallback(error_callback);
-
-	if (!glfwInit())
-		return 1;
-
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-	glfwWindowHint(GLFW_SRGB_CAPABLE, 1);
-
-	window = glfwCreateWindow(1600, 1200, "C It Run", NULL, NULL);
-	if (window == NULL) {
-		glfwTerminate();
-		return 1;
-	}
-
-	glfwSetKeyCallback(window, keyboard_func);
-
-	glfwMakeContextCurrent(window);
-	glfwSwapInterval(1);
-
-	GLenum glew_status = glewInit();
-	if (GLEW_OK != glew_status)
-		errx(1, "%s", glewGetErrorString(glew_status));
-	if (!glewIsSupported("GL_VERSION_2_0"))
-		errx(1, "No support for OpenGL 2.0 found");
-
-	ProcessDir m_pdir;
-	std::vector<GlProcessFile> drawables;
-
-	demo_glstate_t *st = demo_glstate_create();
-	GlBuffer buffer;
-
+	st = demo_glstate_create();
 	static_vu = new View(st);
-
-	demo_font_t *font = demo_font_create(demo_glstate_get_atlas(st));
-
+	font = new citrun::gl_font(FONT_PATH, demo_glstate_get_atlas(st));
 	static_vu->setup();
 
 	glyphy_point_t top_left = { 0, 0 };
 	buffer.move_to(&top_left);
-	buffer.add_text("waiting...", font, 1);
 
-	while (!glfwWindowShouldClose(window)) {
+	buffer.add_text("C It Run\n--------\n", *font, 3);
 
-		for (std::string &file_name : m_pdir.scan())
-			drawables.emplace_back(file_name, font);
+	buffer.add_text("Summary\n", *font, 2);
+	buffer.add_text("No programs have been run yet.\n", *font, 1);
+	buffer.add_text("Compile your program with the provided 'citrun_wrap' script.\n", *font, 1);
+	buffer.add_text("Then run your program to see it run here.\n", *font, 1);
+	buffer.add_text("\n", *font, 1);
 
-		glyphy_extents_t extents;
-		for (auto &i : drawables) {
-			glyphy_extents_t t = i.get_extents();
-			extents.max_x = std::max(extents.max_x, t.max_x);
-			extents.max_y = std::max(extents.max_y, t.max_y);
-			extents.min_x = std::min(extents.min_x, t.min_x);
-			extents.min_y = std::min(extents.min_y, t.min_y);
-		}
+	buffer.add_text("Controlling the Viewer\n", *font, 2);
+	buffer.add_text("The viewer can be moved around with the h/j/k/l keys.\n", *font, 1);
+	buffer.add_text("Use the +/- keys to zoom.", *font, 1);
 
-		// Set up view transforms
-		static_vu->display(extents);
+	buffer.extents(NULL, &extents);
+}
 
-		buffer.draw();
+void
+citrun::gl_main::tick()
+{
+	double x_offset = 0;
 
-		for (auto &i : drawables)
-			i.display();
+	for (std::string &file_name : m_pdir.scan()) {
+		buffer.clear();
+		drawables.emplace_back(file_name, *font, x_offset);
+		x_offset += 50. ;
+	}
 
-		glfwSwapBuffers(window);
-		glfwPollEvents();
+	for (auto &i : drawables) {
+		glyphy_extents_t t = i.get_extents();
+		extents.max_x = std::max(extents.max_x, t.max_x);
+		extents.max_y = std::max(extents.max_y, t.max_y);
+		extents.min_x = std::min(extents.min_x, t.min_x);
+		extents.min_y = std::min(extents.min_y, t.min_y);
 	}
 
-	glfwDestroyWindow(window);
-	glfwTerminate();
+	// Set up view transforms
+	static_vu->display(extents);
+
+	buffer.draw();
 
-	return 0;
+	for (auto &i : drawables)
+		i.display();
 }
diff --git a/bin/gl_main.h b/bin/gl_main.h
@@ -0,0 +1,27 @@
+#include <vector>
+
+#include "gl_buffer.h"		// citrun::gl_buffer
+#include "gl_font.h"		// citrun::gl_font
+#include "gl_procfile.h"	// citrun::gl_procfile
+#include "gl_view.h"
+#include "process_dir.h"	// citrun::process_dir
+
+
+namespace citrun {
+
+class gl_main {
+	citrun::gl_buffer	 buffer;
+	citrun::gl_font		*font;
+	citrun::process_dir	 m_pdir;
+
+	std::vector<citrun::gl_procfile> drawables;
+	demo_glstate_t		*st;
+	glyphy_extents_t	 extents;
+	View			*static_vu;
+public:
+	gl_main();
+	void tick();
+	View *get_static_vu() { return static_vu; };
+};
+
+} // namespace citrun
diff --git a/bin/gltest.cc b/bin/gltest.cc
@@ -1,63 +1,16 @@
 //
 // osdemo.c originally from Brian Paul, public domain.
 //
-#include <err.h>
-#include <GL/glew.h>
+#include <GL/glew.h>		// glewInit, glewIsSupported
 #define GLAPI extern
-#include <GL/osmesa.h>
-#include <stdio.h>
+#include <GL/osmesa.h>		// OSMesa{Context,CreateContext,MakeCurrent}
+#include <err.h>
+#include <stdio.h>		// fclose, fopen, fputc
 #include <stdlib.h>
 #include <string.h>
 
-#include "gl_buffer.h"
-#include "gl_font.h"
-#include "gl_procfile.h"
-#include "gl_view.h"
-#include "process_dir.h"
-
-
-static int Width = 400;
-static int Height = 400;
-
-static void
-render_image(void)
-{
-	ProcessDir m_pdir;
-	std::vector<GlProcessFile> drawables;
-
-	demo_glstate_t *st = demo_glstate_create();
-	GlBuffer text_buffer;
-
-	View *static_vu = new View(st);
-
-	demo_font_t *font = demo_font_create(demo_glstate_get_atlas(st));
+#include "gl_main.h"		// citrun::gl_main
 
-	static_vu->setup();
-
-	glyphy_point_t top_left = { 0, 0 };
-	text_buffer.move_to(&top_left);
-	text_buffer.add_text("waiting...", font, 1);
-
-	for (std::string &file_name : m_pdir.scan())
-		drawables.emplace_back(file_name, font);
-
-	glyphy_extents_t extents;
-	for (auto &i : drawables) {
-		glyphy_extents_t t = i.get_extents();
-		extents.max_x = std::max(extents.max_x, t.max_x);
-		extents.max_y = std::max(extents.max_y, t.max_y);
-		extents.min_x = std::min(extents.min_x, t.min_x);
-		extents.min_y = std::min(extents.min_y, t.min_y);
-	}
-
-	// Set up view transforms
-	static_vu->display(extents);
-
-	text_buffer.draw();
-
-	for (auto &i : drawables)
-		i.display();
-}
 
 static void
 write_targa(const char *filename, const GLubyte *buffer, int width, int height)
@@ -79,10 +32,10 @@ write_targa(const char *filename, const GLubyte *buffer, int width, int height)
       fputc (0x00, f);
       fputc (0x00, f);	/* Y-origin of Image	*/
       fputc (0x00, f);
-      fputc (Width & 0xff, f);      /* Image Width	*/
-      fputc ((Width>>8) & 0xff, f);
-      fputc (Height & 0xff, f);     /* Image Height	*/
-      fputc ((Height>>8) & 0xff, f);
+      fputc (width & 0xff, f);      /* Image Width	*/
+      fputc ((width>>8) & 0xff, f);
+      fputc (height & 0xff, f);     /* Image Height	*/
+      fputc ((height>>8) & 0xff, f);
       fputc (0x18, f);		/* Pixel Depth, 0x18 => 24 Bits	*/
       fputc (0x20, f);		/* Image Descriptor	*/
       fclose(f);
@@ -104,6 +57,8 @@ main(int argc, char *argv[])
 	OSMesaContext	 ctx;
 	void		*buffer;
 	char		*filename = NULL;
+	int		 width = 400;
+	int		 height = 400;
 
 	if (argc < 2) {
 		fprintf(stderr, "Usage:\n");
@@ -112,9 +67,12 @@ main(int argc, char *argv[])
 	}
 
 	filename = argv[1];
+	if (filename == NULL)
+		errx(0,"Specify a filename if you want to make an image file");
+
 	if (argc == 4) {
-		Width = atoi(argv[2]);
-		Height = atoi(argv[3]);
+		width = atoi(argv[2]);
+		height = atoi(argv[3]);
 	}
 
 	// Create an RGBA-mode context
@@ -128,11 +86,11 @@ main(int argc, char *argv[])
 		errx(1, "OSMesaCreateContext failed!");
 
 	// Allocate the image buffer
-	if ((buffer = malloc(Width * Height * 4 * sizeof(GLubyte))) == NULL)
+	if ((buffer = malloc(width * height * 4 * sizeof(GLubyte))) == NULL)
 		errx(1, "Alloc image buffer failed!");
 
 	// Bind the buffer to the context and make it current
-	if (!OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, Width, Height))
+	if (!OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, width, height))
 		errx(1, "OSMesaMakeCurrent failed!");
 
 	int z, s, a;
@@ -143,17 +101,14 @@ main(int argc, char *argv[])
 
 	GLenum glew_status = glewInit();
 	if (GLEW_OK != glew_status)
-		errx(1, "%s", glewGetErrorString(glew_status));
+		errx(1, "glewInit %s", glewGetErrorString(glew_status));
 	if (!glewIsSupported("GL_VERSION_2_0"))
 		errx(1, "No support for OpenGL 2.0 found");
 
-	render_image();
-
-	if (filename != NULL)
-		write_targa(filename, static_cast<const GLubyte *>(buffer), Width, Height);
-	else
-		printf("Specify a filename if you want to make an image file\n");
+	citrun::gl_main main;
+	main.tick();
 
+	write_targa(filename, static_cast<const GLubyte *>(buffer), width, height);
 	printf("all done\n");
 
 	free(buffer);