Advertisement
Guest User

Untitled

a guest
Jan 31st, 2025
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.96 KB | None | 0 0
  1. //g++ rgb_pbo2.cpp opengl/glad.c -o rgb_pbo2 -lglfw -ldl -lGL -I./include
  2. #include <glad/glad.h>
  3. #include <GLFW/glfw3.h>
  4. #include <iostream>
  5. #include <vector>
  6. #include <cstring> // For memcpy
  7. #include <string>
  8.  
  9. // Define window width and height for easy resolution control
  10. const int WINDOW_WIDTH = 1920;
  11. const int WINDOW_HEIGHT = 1080;
  12.  
  13. // Define the number of pre-created patches
  14. const int NUM_PATCHES = 10000;
  15.  
  16. // Pre-created patches
  17. struct RGBPatch {
  18.     int x_offset;  // X position of the patch in the texture
  19.     int y_offset;  // Y position of the patch in the texture
  20.     int width;     // Width of the patch
  21.     int height;    // Height of the patch
  22. };
  23.  
  24. // Patches container
  25. std::vector<RGBPatch> patches;
  26.  
  27. // Vertex Shader Source Code
  28. const char* vertexShaderSource = R"(
  29. #version 330 core
  30. layout(location = 0) in vec2 aPos;
  31. layout(location = 1) in vec2 aTex;
  32.  
  33. out vec2 TexCoord;
  34.  
  35. void main() {
  36.    gl_Position = vec4(aPos, 0.0, 1.0);
  37.    TexCoord = aTex;
  38. }
  39. )";
  40.  
  41. // Fragment Shader Source Code
  42. const char* fragmentShaderSource = R"(
  43. #version 330 core
  44. in vec2 TexCoord;
  45. out vec4 FragColor;
  46.  
  47. uniform sampler2D tex;
  48.  
  49. void main() {
  50.    FragColor = texture(tex, TexCoord);
  51. }
  52. )";
  53.  
  54. // Utility function to compile a shader
  55. GLuint compileShader(GLenum type, const char* source) {
  56.     GLuint shader = glCreateShader(type);
  57.     glShaderSource(shader, 1, &source, nullptr);
  58.     glCompileShader(shader);
  59.  
  60.     int success;
  61.     char infoLog[512];
  62.     glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  63.     if (!success) {
  64.         glGetShaderInfoLog(shader, 512, nullptr, infoLog);
  65.         std::cerr << "ERROR: Shader Compilation Failed\n" << infoLog << std::endl;
  66.     }
  67.  
  68.     return shader;
  69. }
  70.  
  71. // Utility function to create a shader program
  72. GLuint createShaderProgram(const char* vertexSource, const char* fragmentSource) {
  73.     GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexSource);
  74.     GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
  75.    
  76.     GLuint program = glCreateProgram();
  77.     glAttachShader(program, vertexShader);
  78.     glAttachShader(program, fragmentShader);
  79.     glLinkProgram(program);
  80.  
  81.     int success;
  82.     char infoLog[512];
  83.     glGetProgramiv(program, GL_LINK_STATUS, &success);
  84.     if (!success) {
  85.         glGetProgramInfoLog(program, 512, nullptr, infoLog);
  86.         std::cerr << "ERROR: Shader Program Linking Failed\n" << infoLog << std::endl;
  87.     }
  88.  
  89.     glDeleteShader(vertexShader);
  90.     glDeleteShader(fragmentShader);
  91.  
  92.     return program;
  93. }
  94.  
  95. // Pre-create 10,000 patches with random sizes and positions
  96. void preCreatePatches(int textureWidth, int textureHeight) {
  97.     for (int i = 0; i < NUM_PATCHES; ++i) {
  98.         RGBPatch patch;
  99.         patch.width = 1 + (i % 100);  // Width cycles between 1 and 100
  100.         patch.height = 1 + ((i / 2) % 100);  // Height cycles between 1 and 100
  101.         patch.x_offset = i % (textureWidth - patch.width);  // Offset cycles within bounds
  102.         patch.y_offset = i % (textureHeight - patch.height);  // Offset cycles within bounds
  103.         patches.push_back(patch);
  104.     }
  105. }
  106.  
  107. int main() {
  108.     // Initialize GLFW
  109.     if (!glfwInit()) {
  110.         std::cerr << "Failed to initialize GLFW" << std::endl;
  111.         return -1;
  112.     }
  113.  
  114.     // Set OpenGL version to 3.3 Core
  115.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  116.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  117.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  118.  
  119.     // Create a window
  120.     GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "OpenGL PBO RGB Patches", nullptr, nullptr);
  121.     if (!window) {
  122.         std::cerr << "Failed to create GLFW window" << std::endl;
  123.         glfwTerminate();
  124.         return -1;
  125.     }
  126.     glfwMakeContextCurrent(window);
  127.  
  128.     // Load OpenGL function pointers using GLAD
  129.     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
  130.         std::cerr << "Failed to initialize GLAD" << std::endl;
  131.         return -1;
  132.     }
  133.  
  134.     // Set up the viewport
  135.     glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  136.  
  137.     // Compile and link the shader program
  138.     GLuint shaderProgram = createShaderProgram(vertexShaderSource, fragmentShaderSource);
  139.  
  140.     // Define a fullscreen quad
  141.     float quadVertices[] = {
  142.         // Positions   // Texture Coords
  143.         -1.0f, -1.0f,  0.0f, 0.0f,
  144.          1.0f, -1.0f,  1.0f, 0.0f,
  145.         -1.0f,  1.0f,  0.0f, 1.0f,
  146.          1.0f,  1.0f,  1.0f, 1.0f
  147.     };
  148.  
  149.     // Create VAO and VBO for the quad
  150.     GLuint VAO, VBO;
  151.     glGenVertexArrays(1, &VAO);
  152.     glGenBuffers(1, &VBO);
  153.  
  154.     glBindVertexArray(VAO);
  155.     glBindBuffer(GL_ARRAY_BUFFER, VBO);
  156.     glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
  157.  
  158.     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
  159.     glEnableVertexAttribArray(0);
  160.     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
  161.     glEnableVertexAttribArray(1);
  162.  
  163.     // Create a texture
  164.     GLuint texture;
  165.     glGenTextures(1, &texture);
  166.     glBindTexture(GL_TEXTURE_2D, texture);
  167.  
  168.     // Set texture parameters
  169.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  170.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  171.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  172.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  173.  
  174.     // Allocate storage for the texture
  175.     int textureWidth = WINDOW_WIDTH;
  176.     int textureHeight = WINDOW_HEIGHT;
  177.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
  178.  
  179.     // Create PBO
  180.     GLuint pbo;
  181.     glGenBuffers(1, &pbo);
  182.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
  183.     glBufferData(GL_PIXEL_UNPACK_BUFFER, textureWidth * textureHeight * 3, nullptr, GL_STREAM_DRAW);
  184.  
  185.     // Unbind the PBO
  186.     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  187.  
  188.     // Pre-create patches
  189.     preCreatePatches(textureWidth, textureHeight);
  190.  
  191.     // Desired frame time for 60 FPS
  192.     const double frameTime = 1.0 / 60.0;
  193.  
  194.     // FPS calculation variables
  195.     double lastTime = glfwGetTime();
  196.     int frameCount = 0;
  197.  
  198.     // Initialize color counter
  199.     unsigned char colorValue = 0;
  200.  
  201.     // Main render loop
  202.     while (!glfwWindowShouldClose(window)) {
  203.         // Start frame time
  204.         double frameStartTime = glfwGetTime();
  205.  
  206.         // Update the single color for this frame
  207.         // colorValue = (colorValue + 3) % 256;
  208.         colorValue = 120;
  209.  
  210.         // Bind the PBO for updating
  211.         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
  212.         unsigned char* pboMemory = (unsigned char*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
  213.  
  214.         for (const auto& patch : patches) {
  215.             memset(pboMemory + (patch.y_offset * textureWidth + patch.x_offset) * 3, colorValue, patch.width * patch.height * 3);
  216.         }
  217.         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
  218.  
  219.         // Bind the texture and update it using the PBO
  220.         glBindTexture(GL_TEXTURE_2D, texture);
  221.  
  222.             // Perform GPU-GPU copies using glTexSubImage2D
  223.         int currentOffset = 0;
  224.         for (const auto& patch : patches) {
  225.             currentOffset = (patch.y_offset * textureWidth + patch.x_offset) * 3;
  226.             glTexSubImage2D(GL_TEXTURE_2D, 0, patch.x_offset, patch.y_offset, patch.width, patch.height, GL_RGB, GL_UNSIGNED_BYTE, (void*)currentOffset);
  227.         }
  228.  
  229.         // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
  230.  
  231.         // Clear the screen
  232.         glClear(GL_COLOR_BUFFER_BIT);
  233.  
  234.         // Bind the shader program and texture
  235.         glUseProgram(shaderProgram);
  236.         glBindTexture(GL_TEXTURE_2D, texture);
  237.  
  238.         // Render the quad
  239.         glBindVertexArray(VAO);
  240.         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  241.  
  242.         // Unbind the PBO
  243.         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  244.  
  245.         // Swap buffers and poll events
  246.         glfwSwapBuffers(window);
  247.         glfwPollEvents();
  248.  
  249.         // Increment frame count
  250.         frameCount++;
  251.  
  252.         // Calculate FPS every second and update the window title
  253.         double currentTime = glfwGetTime();
  254.         if (currentTime - lastTime >= 1.0) {
  255.             std::string title = "OpenGL PBO RGB Patches - FPS: " + std::to_string(frameCount);
  256.             glfwSetWindowTitle(window, title.c_str());
  257.             frameCount = 0;
  258.             lastTime = currentTime;
  259.         }
  260.  
  261.         // Cap the frame rate to 60 FPS
  262.         // double frameEndTime = glfwGetTime();
  263.         // double elapsedTime = frameEndTime - frameStartTime;
  264.         // if (elapsedTime < frameTime) {
  265.         //     glfwWaitEventsTimeout(frameTime - elapsedTime);
  266.         // }
  267.     }
  268.  
  269.     // Clean up
  270.     glDeleteBuffers(1, &pbo);
  271.     glDeleteVertexArrays(1, &VAO);
  272.     glDeleteBuffers(1, &VBO);
  273.     glDeleteTextures(1, &texture);
  274.     glDeleteProgram(shaderProgram);
  275.  
  276.     glfwTerminate();
  277.     return 0;
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement