# HG changeset patch # User František Kučera # Date 1703675487 -3600 # Node ID ed3caeea978abf37651cdad5a7c9916a16c0b4df # Parent 02972f05174473243b6405b0baa6d7a506498aff render all PDF pages diff -r 02972f051744 -r ed3caeea978a OHP3D.cpp --- a/OHP3D.cpp Wed Dec 27 10:34:12 2023 +0100 +++ b/OHP3D.cpp Wed Dec 27 12:11:27 2023 +0100 @@ -338,6 +338,9 @@ const float cSp = 0.05f; // camera speed const float aSp = 5.f; // angle speed + const float pSp = 1.8 * textures[0]->getRatio(); // page + // TODO: support pages with different ratios + // TODO: import original controls from the private prototype if (key.matches(XK_q, XK_Escape)) keepRunningX11 = false; else if (key.matches(XK_Left, XK_s)) ctx.turnLeft(aSp); @@ -352,8 +355,8 @@ else if (key.matches(XK_comma)) ctx.moveRight(cSp); else if (key.matches(XK_l)) ctx.moveUp(cSp); else if (key.matches(XK_period)) ctx.moveDown(cSp); - else if (key.matches(XK_j)) ctx.moveLeft(cSp * 5); - else if (key.matches(XK_k)) ctx.moveRight(cSp * 5); + else if (key.matches(XK_j)) ctx.moveLeft(pSp); + else if (key.matches(XK_k)) ctx.moveRight(pSp); else if (key.matches(XK_u)) ctx.moveLeft(cSp * 10); else if (key.matches(XK_i)) ctx.moveRight(cSp * 10); else if (key.matches(XK_x)) resetView(); @@ -474,11 +477,15 @@ glm::mat4 model = glm::mat4(1.0f); // identity matrix glUniformMatrix4fv(ProgAttr.uModel, 1, GL_FALSE, &model[0][0]); - // TODO: draw a rectangle for each texture - glUniform1f(ProgAttr.uTextureScale, textures[0]->getScale()); + for (int i = 0; i < textures.size(); i++) { + textures[i]->bind(); + glUniform1f(ProgAttr.uTextureScale, textures[i]->getScale()); + int pageVertices = 2 * 3; // see loadVertices() + glDrawArrays(GL_TRIANGLES, i*pageVertices, pageVertices); + // std::cerr << "GLSL: glDrawArrays() #" << i << std::endl; + } - glDrawArrays(GL_TRIANGLES, 0, 2 * 3); // see loadVertices() - std::cerr << "GLSL: glDrawArrays()" << std::endl; + std::cerr << "GLSL: glDrawArrays() " << textures.size() << "x" << std::endl; } void OHP3D::Impl::log(LogLevel level, std::string message) { @@ -492,50 +499,54 @@ } void OHP3D::Impl::loadVertices() { + std::vector vertices; for (int i = 0; i < textures.size(); i++) { std::shared_ptr tex = textures[i]; - // TODO: draw a rectangle for each texture GLfloat ratio = tex->getRatio(); - const std::vector vertices = { - // Vertex XYZ Texture XY - -0.80f * ratio, +0.80f, +0.0, /**/ 0.0, 0.0, - +0.80f * ratio, +0.80f, +0.0, /**/ 1.0, 0.0, - -0.80f * ratio, -0.80f, +0.0, /**/ 0.0, 1.0, + GLfloat offset = ratio * 1.8 * i; + const std::vector v = { + // Vertex XYZ Texture XY + -0.80f * ratio + offset, +0.80f, +0.0, /**/ 0.0, 0.0, + +0.80f * ratio + offset, +0.80f, +0.0, /**/ 1.0, 0.0, + -0.80f * ratio + offset, -0.80f, +0.0, /**/ 0.0, 1.0, - -0.80f * ratio, -0.80f, +0.0, /**/ 0.0, 1.0, - +0.80f * ratio, -0.80f, +0.0, /**/ 1.0, 1.0, - +0.80f * ratio, +0.80f, +0.0, /**/ 1.0, 0.0, + -0.80f * ratio + offset, -0.80f, +0.0, /**/ 0.0, 1.0, + +0.80f * ratio + offset, -0.80f, +0.0, /**/ 1.0, 1.0, + +0.80f * ratio + offset, +0.80f, +0.0, /**/ 1.0, 0.0, // see glDrawArrays(), where we set start offset and count }; - // Vertex data: - glVertexAttribPointer(ProgAttr.aVertexXYZ, 3, // vertex items - GL_FLOAT, GL_FALSE, 5 * sizeof (float), - (void*) 0); - glEnableVertexAttribArray(ProgAttr.aVertexXYZ); + // TODO: reduce copying + for (GLfloat f : v) vertices.push_back(f); + } - // Texture positions: - glVertexAttribPointer(ProgAttr.aTextureXY, 2, // texture items - GL_FLOAT, GL_FALSE, 5 * sizeof (float), - (void*) (3 * sizeof (float))); - glEnableVertexAttribArray(ProgAttr.aTextureXY); + // Vertex data: + glVertexAttribPointer(ProgAttr.aVertexXYZ, 3, // vertex items + GL_FLOAT, GL_FALSE, 5 * sizeof (float), + (void*) 0); + glEnableVertexAttribArray(ProgAttr.aVertexXYZ); - glBufferData(GL_ARRAY_BUFFER, - vertices.size() * sizeof (vertices[0]), - vertices.data(), - GL_STATIC_DRAW); - // GL_STATIC_DRAW: - // The vertex data will be uploaded once - // and drawn many times(e.g. the world). - // GL_DYNAMIC_DRAW: - // The vertex data will be created once, changed from - // time to time, but drawn many times more than that. - // GL_STREAM_DRAW: - // The vertex data will be uploaded once and drawn once. + // Texture positions: + glVertexAttribPointer(ProgAttr.aTextureXY, 2, // texture items + GL_FLOAT, GL_FALSE, 5 * sizeof (float), + (void*) (3 * sizeof (float))); + glEnableVertexAttribArray(ProgAttr.aTextureXY); - // see also glBindBuffer(GL_ARRAY_BUFFER, vbo); where we set current VBO - } + glBufferData(GL_ARRAY_BUFFER, + vertices.size() * sizeof (vertices[0]), + vertices.data(), + GL_STATIC_DRAW); + // GL_STATIC_DRAW: + // The vertex data will be uploaded once + // and drawn many times(e.g. the world). + // GL_DYNAMIC_DRAW: + // The vertex data will be created once, changed from + // time to time, but drawn many times more than that. + // GL_STREAM_DRAW: + // The vertex data will be uploaded once and drawn once. + + // see also glBindBuffer(GL_ARRAY_BUFFER, vbo); where we set current VBO } const std::string @@ -583,6 +594,7 @@ textures.push_back(std::make_shared( pageImage.width(), pageImage.height(), img, document.fileName)); + // textures.back()->setScale(8.); // TODO: fix scale and DPI log(LogLevel::INFO, " page " + std::to_string(i + 1) + "/" + std::to_string(limit)); } diff -r 02972f051744 -r ed3caeea978a Texture.cpp --- a/Texture.cpp Wed Dec 27 10:34:12 2023 +0100 +++ b/Texture.cpp Wed Dec 27 12:11:27 2023 +0100 @@ -94,3 +94,7 @@ glGenerateMipmap(GLT2D); checkError(&std::cerr); } + +void Texture::bind() { + glBindTexture(GL_TEXTURE_2D, impl->id); +} diff -r 02972f051744 -r ed3caeea978a Texture.h --- a/Texture.h Wed Dec 27 10:34:12 2023 +0100 +++ b/Texture.h Wed Dec 27 12:11:27 2023 +0100 @@ -41,6 +41,7 @@ GLfloat getScale() const; void setScale(GLfloat scale); void update(int width, int height, const Buffer& img); + void bind(); private: class Impl; Impl* impl;