Shark.cpp
branchv_0
changeset 8 80ad08521091
parent 7 e6065118326f
child 9 53ba7e52c67c
equal deleted inserted replaced
7:e6065118326f 8:80ad08521091
    34 	XDestroyWindow(dpy, win);
    34 	XDestroyWindow(dpy, win);
    35 	XCloseDisplay(dpy);
    35 	XCloseDisplay(dpy);
    36 	// std::cerr << "~Shark()" << std::endl;
    36 	// std::cerr << "~Shark()" << std::endl;
    37 }
    37 }
    38 
    38 
       
    39 void Shark::setTitle(const std::string& suffix) {
       
    40 	std::stringstream title;
       
    41 	title << "ShaderShark";
       
    42 	if (suffix.size()) title << ": " << suffix.c_str();
       
    43 	XStoreName(dpy, win, title.str().c_str());
       
    44 	XFlush(dpy);
       
    45 }
       
    46 
    39 void Shark::run() {
    47 void Shark::run() {
    40 	dpy = XOpenDisplay(NULL);
    48 	dpy = XOpenDisplay(NULL);
    41 
    49 
    42 	if (dpy == NULL) throw std::logic_error("Unable to connect to X server");
    50 	if (dpy == NULL) throw std::logic_error("Unable to connect to X server");
    43 
    51 
    66 			dpy, parent, 0, 0, width, height, 0,
    74 			dpy, parent, 0, 0, width, height, 0,
    67 			vi->depth, InputOutput, vi->visual,
    75 			vi->depth, InputOutput, vi->visual,
    68 			CWColormap | CWEventMask, &swa);
    76 			CWColormap | CWEventMask, &swa);
    69 
    77 
    70 	XMapWindow(dpy, win);
    78 	XMapWindow(dpy, win);
    71 	XStoreName(dpy, win, "ShaderShark");
    79 	setTitle();
    72 	setX11PID(dpy, win);
    80 	setX11PID(dpy, win);
    73 	// XSetWindowBackground(dpy, win, 0) vs. glClearColor()
    81 	// XSetWindowBackground(dpy, win, 0) vs. glClearColor()
    74 
    82 
    75 	glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
    83 	glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
    76 	glXMakeCurrent(dpy, win, glc);
    84 	glXMakeCurrent(dpy, win, glc);
   115 
   123 
   116 	for (XEvent xev; keepRunningX11;) {
   124 	for (XEvent xev; keepRunningX11;) {
   117 		int epollEventCount = epoll.wait();
   125 		int epollEventCount = epoll.wait();
   118 		//std::cout << "trace: epoll.wait() = " << epollEventCount << std::endl;
   126 		//std::cout << "trace: epoll.wait() = " << epollEventCount << std::endl;
   119 		for (int epollEvent = 0; epollEvent < epollEventCount; epollEvent++) {
   127 		for (int epollEvent = 0; epollEvent < epollEventCount; epollEvent++) {
       
   128 			bool redraw = false;
   120 			if (epoll[epollEvent].data.fd == x11fd) {
   129 			if (epoll[epollEvent].data.fd == x11fd) {
   121 				if (!XPending(dpy)) {
   130 				if (!XPending(dpy)) {
   122 					// otherwise STDIN events are held until the first X11 event
   131 					// otherwise STDIN events are held until the first X11 event
   123 					logOutput << "trace: no pending X11 event" << std::endl;
   132 					logOutput << "trace: no pending X11 event" << std::endl;
   124 					break;
   133 					break;
   125 				}
   134 				}
   126 				XWindowAttributes gwa;
   135 				XWindowAttributes gwa;
   127 				XNextEvent(dpy, &xev);
   136 				XNextEvent(dpy, &xev);
   128 				bool redraw = false;
       
   129 
   137 
   130 				if (xev.type == Expose) {
   138 				if (xev.type == Expose) {
   131 					std::cout << "XEvent: Expose" << std::endl;
   139 					std::cout << "XEvent: Expose" << std::endl;
   132 					XGetWindowAttributes(dpy, win, &gwa);
   140 					XGetWindowAttributes(dpy, win, &gwa);
   133 					glViewport(0, 0, gwa.width, gwa.height);
   141 					glViewport(0, 0, gwa.width, gwa.height);
   191 					std::cout << "XEvent: DestroyNotify → finish" << std::endl;
   199 					std::cout << "XEvent: DestroyNotify → finish" << std::endl;
   192 					break;
   200 					break;
   193 				} else {
   201 				} else {
   194 					std::cout << "XEvent: type=" << xev.type << std::endl;
   202 					std::cout << "XEvent: type=" << xev.type << std::endl;
   195 				}
   203 				}
   196 
       
   197 				if (redraw) {
       
   198 					runShaders();
       
   199 					glXSwapBuffers(dpy, win);
       
   200 				}
       
   201 			} else if (epoll[epollEvent].data.fd == STDIN_FILENO) {
   204 			} else if (epoll[epollEvent].data.fd == STDIN_FILENO) {
   202 				int epollFD = epoll[epollEvent].data.fd;
   205 				int epollFD = epoll[epollEvent].data.fd;
   203 				logOutput << "other event: fd=" << epollFD << " data=";
   206 				logOutput << "other event: fd=" << epollFD << " data=";
   204 				for (char ch; read(epollFD, &ch, 1) > 0;) {
   207 				for (char ch; read(epollFD, &ch, 1) > 0;) {
   205 					std::stringstream msg;
   208 					std::stringstream msg;
   213 				logOutput << std::endl;
   216 				logOutput << std::endl;
   214 
   217 
   215 			} else if (epoll[epollEvent].data.fd == fileMonitor.getFD()) {
   218 			} else if (epoll[epollEvent].data.fd == fileMonitor.getFD()) {
   216 				std::cout << "FileMonitor event:" << std::endl;
   219 				std::cout << "FileMonitor event:" << std::endl;
   217 				for (FileEvent fe; fileMonitor.readEvent(fe);) {
   220 				for (FileEvent fe; fileMonitor.readEvent(fe);) {
   218 					std::cout << "   "
   221 					logOutput << "   "
   219 							<< " file: " << fe.fileName
   222 							<< " file=" << fe.fileName
   220 							<< " mask: " << fe.mask
   223 							<< " mask=" << fe.mask
   221 							<< std::endl;
   224 							<< std::endl;
       
   225 					try {
       
   226 						redraw |= reloadTexture(fe.fileName);
       
   227 						redraw |= reloadShader(fe.fileName);
       
   228 						setTitle();
       
   229 					} catch (const std::exception& e) {
       
   230 						setTitle("[ERROR]");
       
   231 						logOutput << "error while reloading '"
       
   232 								<< fe.fileName.c_str()
       
   233 								<< "': " << e.what() << std::endl;
       
   234 					}
   222 				}
   235 				}
   223 			} else {
   236 			} else {
   224 				logOutput
   237 				logOutput
   225 						<< "error: event on an unexpected FD: "
   238 						<< "error: event on an unexpected FD: "
   226 						<< epoll[epollEvent].data.fd
   239 						<< epoll[epollEvent].data.fd
   227 						<< std::endl;
   240 						<< std::endl;
       
   241 			}
       
   242 
       
   243 			if (redraw) {
       
   244 				runShaders();
       
   245 				glXSwapBuffers(dpy, win);
   228 			}
   246 			}
   229 		}
   247 		}
   230 	}
   248 	}
   231 }
   249 }
   232 
   250 
   368 		// glUniform1i(ProgAttr.jazz, jazz);
   386 		// glUniform1i(ProgAttr.jazz, jazz);
   369 		// checkError(&std::cerr);
   387 		// checkError(&std::cerr);
   370 	}
   388 	}
   371 }
   389 }
   372 
   390 
       
   391 bool Shark::reloadTexture(const std::string& fileName) {
       
   392 	for (const Configuration::Texture& tex : cfg.textures) {
       
   393 		if (tex.fileName == fileName) {
       
   394 			logOutput << "TODO: reload texture: " << fileName.c_str() << "\n";
       
   395 			return true;
       
   396 		}
       
   397 	}
       
   398 	return false;
       
   399 }
       
   400 
   373 std::shared_ptr<Program> Shark::loadShaders() {
   401 std::shared_ptr<Program> Shark::loadShaders() {
   374 	try {
   402 	try {
   375 		// Vertex Array Object (VAO)
   403 		// Vertex Array Object (VAO)
   376 		GLuint vao;
   404 		GLuint vao;
   377 		glGenVertexArrays(1, &vao);
   405 		glGenVertexArrays(1, &vao);
   410 
   438 
   411 			program->attachShader(*shader.get());
   439 			program->attachShader(*shader.get());
   412 			shaders.push_back(shader);
   440 			shaders.push_back(shader);
   413 			watchedFiles.push_back(fileMonitor.watch(fileName));
   441 			watchedFiles.push_back(fileMonitor.watch(fileName));
   414 			std::cerr << "GLSL loaded: " << fileName.c_str() << std::endl;
   442 			std::cerr << "GLSL loaded: " << fileName.c_str() << std::endl;
       
   443 			// We may detach and delete shaders,
       
   444 			// but our shaders are small, so we keep them for later reloading.
   415 		}
   445 		}
   416 
   446 
   417 		// GLSL compiler does very efficient / aggressive optimization.
   447 		// GLSL compiler does very efficient / aggressive optimization.
   418 		// Attributes and uniforms that are not used in the shader are deleted.
   448 		// Attributes and uniforms that are not used in the shader are deleted.
   419 		// And even if we e.g. read color from a texture and overwrite it,
   449 		// And even if we e.g. read color from a texture and overwrite it,
   439 		std::cerr << "Error while loading shaders: unknown" << std::endl;
   469 		std::cerr << "Error while loading shaders: unknown" << std::endl;
   440 	}
   470 	}
   441 	throw std::logic_error("GLSL: loadShaders() failed");
   471 	throw std::logic_error("GLSL: loadShaders() failed");
   442 }
   472 }
   443 
   473 
       
   474 bool Shark::reloadShader(const std::string& fileName) {
       
   475 	for (auto shader : shaders) {
       
   476 		if (shader->getFileName() == fileName) {
       
   477 			shader->update(MappedFile(fileName));
       
   478 			shaderProgram->link();
       
   479 			return true;
       
   480 		}
       
   481 	}
       
   482 	return false;
       
   483 }