render all PDF pages v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Wed, 27 Dec 2023 12:11:27 +0100
branchv_0
changeset 31 ed3caeea978a
parent 30 02972f051744
child 32 711d3d781143
render all PDF pages
OHP3D.cpp
Texture.cpp
Texture.h
--- 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));
 		}
--- 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);
+}
--- 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;