--- 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<GLfloat> vertices;
for (int i = 0; i < textures.size(); i++) {
std::shared_ptr<Texture> tex = textures[i];
- // TODO: draw a rectangle for each texture
GLfloat ratio = tex->getRatio();
- const std::vector<GLfloat> 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<GLfloat> 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<Texture>(
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));
}