153 updateCameraFrontAndUp(); |
154 updateCameraFrontAndUp(); |
154 } |
155 } |
155 |
156 |
156 } initialCtx, ctx; |
157 } initialCtx, ctx; |
157 |
158 |
158 class Texture { |
|
159 public: |
|
160 GLuint id; |
|
161 std::string fileName; |
|
162 int width; |
|
163 int height; |
|
164 |
|
165 GLfloat getRatio() const { |
|
166 return (GLfloat) width / (GLfloat) height; |
|
167 } |
|
168 }; |
|
169 |
|
170 Display* dpy; |
159 Display* dpy; |
171 Window win; |
160 Window win; |
172 XVisualInfo* vi; |
161 XVisualInfo* vi; |
173 GLXContext glc; |
162 GLXContext glc; |
174 |
163 |
175 FileMonitor fileMonitor; |
164 FileMonitor fileMonitor; |
176 std::vector<WatchedFile> watchedFiles; |
165 std::vector<WatchedFile> watchedFiles; |
177 ImageLoader imageLoader; |
166 ImageLoader imageLoader; |
178 std::vector<std::shared_ptr<Shader>> shaders; |
167 std::vector<std::shared_ptr<Shader>> shaders; |
179 std::shared_ptr<Program> shaderProgram; |
168 std::shared_ptr<Program> shaderProgram; |
180 std::vector<Texture> textures; |
169 std::vector<std::shared_ptr<Texture>> textures; |
181 |
170 |
182 Configuration cfg; |
171 Configuration cfg; |
183 std::ostream& logOutput = std::cerr; |
172 std::ostream& logOutput = std::cerr; |
184 |
173 |
185 Impl(Configuration cfg) : cfg(cfg) { |
174 Impl(Configuration cfg) : cfg(cfg) { |
190 void runShaders(); |
179 void runShaders(); |
191 Window getRootWindow(Window defaultValue); |
180 Window getRootWindow(Window defaultValue); |
192 void log(LogLevel level, std::string message); |
181 void log(LogLevel level, std::string message); |
193 int setNonBlocking(int fd); |
182 int setNonBlocking(int fd); |
194 void loadVertices(); |
183 void loadVertices(); |
195 Texture loadTexture(const std::string& fileName); |
|
196 void updateTexture(Texture& tex, const Buffer& file); |
|
197 bool reloadTexture(const std::string& fileName); |
184 bool reloadTexture(const std::string& fileName); |
198 void loadTextures(); |
185 void loadTextures(); |
199 std::shared_ptr<Program> loadShaders(); |
186 std::shared_ptr<Program> loadShaders(); |
200 bool reloadShader(const std::string& fileName); |
187 bool reloadShader(const std::string& fileName); |
201 void setTitle(const std::string& suffix = ""); |
188 void setTitle(const std::string& suffix = ""); |
206 Shark::Shark(const Configuration& configuration) : |
193 Shark::Shark(const Configuration& configuration) : |
207 impl(new Impl(configuration)) { |
194 impl(new Impl(configuration)) { |
208 } |
195 } |
209 |
196 |
210 Shark::~Shark() { |
197 Shark::~Shark() { |
211 // TODO: more SBRM |
198 impl->textures.clear(); |
212 impl->shaders.clear(); |
199 impl->shaders.clear(); |
213 impl->shaderProgram = nullptr; |
200 impl->shaderProgram = nullptr; |
214 XFree(impl->vi); |
201 XFree(impl->vi); |
215 // for (auto page : pdfTextures) glDeleteTextures(1, &page.texture); |
|
216 glXMakeCurrent(impl->dpy, None, NULL); |
202 glXMakeCurrent(impl->dpy, None, NULL); |
217 glXDestroyContext(impl->dpy, impl->glc); |
203 glXDestroyContext(impl->dpy, impl->glc); |
218 XDestroyWindow(impl->dpy, impl->win); |
204 XDestroyWindow(impl->dpy, impl->win); |
219 XCloseDisplay(impl->dpy); |
205 XCloseDisplay(impl->dpy); |
220 delete impl; |
206 delete impl; |
496 return fd; |
482 return fd; |
497 } |
483 } |
498 |
484 |
499 void Shark::Impl::loadVertices() { |
485 void Shark::Impl::loadVertices() { |
500 for (int i = 0; i < textures.size(); i++) { |
486 for (int i = 0; i < textures.size(); i++) { |
501 const Texture& tex = textures[i]; |
487 std::shared_ptr<Texture> tex = textures[i]; |
502 GLfloat ratio = tex.getRatio(); |
488 GLfloat ratio = tex->getRatio(); |
503 const std::vector<GLfloat> vertices = { |
489 const std::vector<GLfloat> vertices = { |
504 // Vertex XYZ Texture XY |
490 // Vertex XYZ Texture XY |
505 -0.80f * ratio, +0.80f, +0.0, /**/ 0.0, 0.0, |
491 -0.80f * ratio, +0.80f, +0.0, /**/ 0.0, 0.0, |
506 +0.80f * ratio, +0.80f, +0.0, /**/ 1.0, 0.0, |
492 +0.80f * ratio, +0.80f, +0.0, /**/ 1.0, 0.0, |
507 -0.80f * ratio, -0.80f, +0.0, /**/ 0.0, 1.0, |
493 -0.80f * ratio, -0.80f, +0.0, /**/ 0.0, 1.0, |
553 + " in order to use defaults" |
539 + " in order to use defaults" |
554 " or specify textures and shaders as parameters"); |
540 " or specify textures and shaders as parameters"); |
555 } |
541 } |
556 } |
542 } |
557 |
543 |
558 Shark::Impl::Texture Shark::Impl::loadTexture(const std::string& fileName) { |
|
559 Texture tex; |
|
560 tex.fileName = fileName; |
|
561 MappedFile file(tex.fileName); |
|
562 updateTexture(tex, file); |
|
563 return tex; |
|
564 } |
|
565 |
|
566 void Shark::Impl::updateTexture(Texture& tex, const Buffer& file) { |
|
567 std::shared_ptr<ImageLoader::ImageBuffer> img(imageLoader.loadImage(file)); |
|
568 |
|
569 tex.width = img->width; |
|
570 tex.height = img->height; |
|
571 |
|
572 glGenTextures(1, &tex.id); |
|
573 glBindTexture(GL_TEXTURE_2D, tex.id); |
|
574 auto GLT2D = GL_TEXTURE_2D; |
|
575 glTexImage2D(GLT2D, 0, GL_RGBA, |
|
576 tex.width, tex.height, |
|
577 0, GL_RGBA, GL_UNSIGNED_BYTE, |
|
578 img->getData()); |
|
579 glTexParameteri(GLT2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
|
580 glTexParameteri(GLT2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
|
581 glTexParameteri(GLT2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
582 glTexParameteri(GLT2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
|
583 glGenerateMipmap(GLT2D); |
|
584 std::cerr << "loadTexture(\"" << tex.fileName.c_str() << "\", " |
|
585 << tex.width << ", " << tex.height << ") = " << tex.id << std::endl; |
|
586 checkError(&std::cerr); |
|
587 } |
|
588 |
|
589 void Shark::Impl::loadTextures() { |
544 void Shark::Impl::loadTextures() { |
590 // Load default texture if there is no configured: |
545 // Load default texture if there is no configured: |
591 if (cfg.textures.empty()) |
546 if (cfg.textures.empty()) |
592 cfg.textures.push_back({getDefaultFile("textures/default.png")}); |
547 cfg.textures.push_back({getDefaultFile("textures/default.png")}); |
593 |
548 |
594 for (const Configuration::Texture& tex : cfg.textures) { |
549 for (const Configuration::Texture& tex : cfg.textures) { |
595 textures.push_back(loadTexture(tex.fileName)); |
550 std::shared_ptr<ImageLoader::ImageBuffer> |
|
551 img(imageLoader.loadImage(MappedFile(tex.fileName))); |
|
552 textures.push_back(std::make_shared<Texture>( |
|
553 img->width, img->height, *img, tex.fileName)); |
596 watchedFiles.push_back(fileMonitor.watch(tex.fileName)); |
554 watchedFiles.push_back(fileMonitor.watch(tex.fileName)); |
597 // TODO: review texture loading and binding |
555 // TODO: review texture loading and binding |
598 // works even without this - default texture |
556 // works even without this - default texture |
599 // glUniform1i(ProgAttr.jazz, jazz); |
557 // glUniform1i(ProgAttr.jazz, jazz); |
600 // checkError(&std::cerr); |
558 // checkError(&std::cerr); |
601 } |
559 } |
602 } |
560 } |
603 |
561 |
604 bool Shark::Impl::reloadTexture(const std::string& fileName) { |
562 bool Shark::Impl::reloadTexture(const std::string& fileName) { |
605 for (Texture& tex : textures) { |
563 for (std::shared_ptr<Texture> tex : textures) { |
606 if (tex.fileName == fileName) { |
564 if (tex->getFileName() == fileName) { |
607 updateTexture(tex, MappedFile(fileName)); |
565 std::shared_ptr<ImageLoader::ImageBuffer> |
|
566 img(imageLoader.loadImage(MappedFile(fileName))); |
|
567 tex->update(img->width, img->height, *img); |
608 loadVertices(); |
568 loadVertices(); |
609 return true; |
569 return true; |
610 } |
570 } |
611 } |
571 } |
612 return false; |
572 return false; |