Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //g++ rgb_pbo2.cpp opengl/glad.c -o rgb_pbo2 -lglfw -ldl -lGL -I./include
- #include <glad/glad.h>
- #include <GLFW/glfw3.h>
- #include <iostream>
- #include <vector>
- #include <cstring> // For memcpy
- #include <string>
- // Define window width and height for easy resolution control
- const int WINDOW_WIDTH = 1920;
- const int WINDOW_HEIGHT = 1080;
- // Define the number of pre-created patches
- const int NUM_PATCHES = 10000;
- // Pre-created patches
- struct RGBPatch {
- int x_offset; // X position of the patch in the texture
- int y_offset; // Y position of the patch in the texture
- int width; // Width of the patch
- int height; // Height of the patch
- };
- // Patches container
- std::vector<RGBPatch> patches;
- // Vertex Shader Source Code
- const char* vertexShaderSource = R"(
- #version 330 core
- layout(location = 0) in vec2 aPos;
- layout(location = 1) in vec2 aTex;
- out vec2 TexCoord;
- void main() {
- gl_Position = vec4(aPos, 0.0, 1.0);
- TexCoord = aTex;
- }
- )";
- // Fragment Shader Source Code
- const char* fragmentShaderSource = R"(
- #version 330 core
- in vec2 TexCoord;
- out vec4 FragColor;
- uniform sampler2D tex;
- void main() {
- FragColor = texture(tex, TexCoord);
- }
- )";
- // Utility function to compile a shader
- GLuint compileShader(GLenum type, const char* source) {
- GLuint shader = glCreateShader(type);
- glShaderSource(shader, 1, &source, nullptr);
- glCompileShader(shader);
- int success;
- char infoLog[512];
- glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(shader, 512, nullptr, infoLog);
- std::cerr << "ERROR: Shader Compilation Failed\n" << infoLog << std::endl;
- }
- return shader;
- }
- // Utility function to create a shader program
- GLuint createShaderProgram(const char* vertexSource, const char* fragmentSource) {
- GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexSource);
- GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
- GLuint program = glCreateProgram();
- glAttachShader(program, vertexShader);
- glAttachShader(program, fragmentShader);
- glLinkProgram(program);
- int success;
- char infoLog[512];
- glGetProgramiv(program, GL_LINK_STATUS, &success);
- if (!success) {
- glGetProgramInfoLog(program, 512, nullptr, infoLog);
- std::cerr << "ERROR: Shader Program Linking Failed\n" << infoLog << std::endl;
- }
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- return program;
- }
- // Pre-create 10,000 patches with random sizes and positions
- void preCreatePatches(int textureWidth, int textureHeight) {
- for (int i = 0; i < NUM_PATCHES; ++i) {
- RGBPatch patch;
- patch.width = 1 + (i % 100); // Width cycles between 1 and 100
- patch.height = 1 + ((i / 2) % 100); // Height cycles between 1 and 100
- patch.x_offset = i % (textureWidth - patch.width); // Offset cycles within bounds
- patch.y_offset = i % (textureHeight - patch.height); // Offset cycles within bounds
- patches.push_back(patch);
- }
- }
- int main() {
- // Initialize GLFW
- if (!glfwInit()) {
- std::cerr << "Failed to initialize GLFW" << std::endl;
- return -1;
- }
- // Set OpenGL version to 3.3 Core
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- // Create a window
- GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "OpenGL PBO RGB Patches", nullptr, nullptr);
- if (!window) {
- std::cerr << "Failed to create GLFW window" << std::endl;
- glfwTerminate();
- return -1;
- }
- glfwMakeContextCurrent(window);
- // Load OpenGL function pointers using GLAD
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- std::cerr << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
- // Set up the viewport
- glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
- // Compile and link the shader program
- GLuint shaderProgram = createShaderProgram(vertexShaderSource, fragmentShaderSource);
- // Define a fullscreen quad
- float quadVertices[] = {
- // Positions // Texture Coords
- -1.0f, -1.0f, 0.0f, 0.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
- -1.0f, 1.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f
- };
- // Create VAO and VBO for the quad
- GLuint VAO, VBO;
- glGenVertexArrays(1, &VAO);
- glGenBuffers(1, &VBO);
- glBindVertexArray(VAO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
- glEnableVertexAttribArray(1);
- // Create a texture
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- // Set texture parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- // Allocate storage for the texture
- int textureWidth = WINDOW_WIDTH;
- int textureHeight = WINDOW_HEIGHT;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
- // Create PBO
- GLuint pbo;
- glGenBuffers(1, &pbo);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
- glBufferData(GL_PIXEL_UNPACK_BUFFER, textureWidth * textureHeight * 3, nullptr, GL_STREAM_DRAW);
- // Unbind the PBO
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- // Pre-create patches
- preCreatePatches(textureWidth, textureHeight);
- // Desired frame time for 60 FPS
- const double frameTime = 1.0 / 60.0;
- // FPS calculation variables
- double lastTime = glfwGetTime();
- int frameCount = 0;
- // Initialize color counter
- unsigned char colorValue = 0;
- // Main render loop
- while (!glfwWindowShouldClose(window)) {
- // Start frame time
- double frameStartTime = glfwGetTime();
- // Update the single color for this frame
- // colorValue = (colorValue + 3) % 256;
- colorValue = 120;
- // Bind the PBO for updating
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
- unsigned char* pboMemory = (unsigned char*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
- for (const auto& patch : patches) {
- memset(pboMemory + (patch.y_offset * textureWidth + patch.x_offset) * 3, colorValue, patch.width * patch.height * 3);
- }
- glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
- // Bind the texture and update it using the PBO
- glBindTexture(GL_TEXTURE_2D, texture);
- // Perform GPU-GPU copies using glTexSubImage2D
- int currentOffset = 0;
- for (const auto& patch : patches) {
- currentOffset = (patch.y_offset * textureWidth + patch.x_offset) * 3;
- glTexSubImage2D(GL_TEXTURE_2D, 0, patch.x_offset, patch.y_offset, patch.width, patch.height, GL_RGB, GL_UNSIGNED_BYTE, (void*)currentOffset);
- }
- // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
- // Clear the screen
- glClear(GL_COLOR_BUFFER_BIT);
- // Bind the shader program and texture
- glUseProgram(shaderProgram);
- glBindTexture(GL_TEXTURE_2D, texture);
- // Render the quad
- glBindVertexArray(VAO);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- // Unbind the PBO
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- // Swap buffers and poll events
- glfwSwapBuffers(window);
- glfwPollEvents();
- // Increment frame count
- frameCount++;
- // Calculate FPS every second and update the window title
- double currentTime = glfwGetTime();
- if (currentTime - lastTime >= 1.0) {
- std::string title = "OpenGL PBO RGB Patches - FPS: " + std::to_string(frameCount);
- glfwSetWindowTitle(window, title.c_str());
- frameCount = 0;
- lastTime = currentTime;
- }
- // Cap the frame rate to 60 FPS
- // double frameEndTime = glfwGetTime();
- // double elapsedTime = frameEndTime - frameStartTime;
- // if (elapsedTime < frameTime) {
- // glfwWaitEventsTimeout(frameTime - elapsedTime);
- // }
- }
- // Clean up
- glDeleteBuffers(1, &pbo);
- glDeleteVertexArrays(1, &VAO);
- glDeleteBuffers(1, &VBO);
- glDeleteTextures(1, &texture);
- glDeleteProgram(shaderProgram);
- glfwTerminate();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement