Advertisement
Guest User

Untitled

a guest
Feb 1st, 2025
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.83 KB | None | 0 0
  1. // g++ rgb_cell.cpp opengl/glad.c -o rgb_cell -lglfw -ldl -lGL -I./include
  2. #include <glad/glad.h>
  3. #include <GLFW/glfw3.h>
  4. #include <iostream>
  5. #include <vector>
  6. #include <map>
  7. #include <cstring> // For memset
  8. #include <algorithm> // For min and max
  9. #include <string> // For std::to_string
  10.  
  11. // Define window and texture dimensions
  12. const int WINDOW_WIDTH = 1920;
  13. const int WINDOW_HEIGHT = 1080;
  14.  
  15. // Define cell size for dividing the texture
  16. const int GRID_CELL_SIZE = 128;
  17.  
  18. // Define a patch structure
  19. struct RGBPatch {
  20.     int x_offset;  // X position of the patch in the texture
  21.     int y_offset;  // Y position of the patch in the texture
  22.     int width;     // Width of the patch
  23.     int height;    // Height of the patch
  24.     std::vector<unsigned char> data; // RGB data for the patch
  25. };
  26.  
  27. // Vertex Shader Source
  28. const char* vertexShaderSource = R"(
  29. #version 330 core
  30. layout(location = 0) in vec2 aPos;
  31. layout(location = 1) in vec2 aTexCoord;
  32.  
  33. out vec2 TexCoord;
  34.  
  35. void main() {
  36.    gl_Position = vec4(aPos, 0.0, 1.0);
  37.    TexCoord = aTexCoord;
  38. }
  39. )";
  40.  
  41. // Fragment Shader Source
  42. const char* fragmentShaderSource = R"(
  43. #version 330 core
  44. out vec4 FragColor;
  45.  
  46. in vec2 TexCoord;
  47.  
  48. uniform sampler2D texture1;
  49.  
  50. void main() {
  51.    FragColor = texture(texture1, TexCoord);
  52. }
  53. )";
  54.  
  55. // Create some patches
  56. void createPatches(std::vector<RGBPatch>& patches, int numPatches, int textureWidth, int textureHeight) {
  57.     for (int i = 0; i < numPatches; ++i) {
  58.         RGBPatch patch;
  59.         patch.width = 10 + (i % 20);  // Width between 10 and 30
  60.         patch.height = 10 + ((i + 5) % 15); // Height between 10 and 25
  61.         patch.x_offset = (i * 23) % (textureWidth - patch.width);
  62.         patch.y_offset = (i * 37) % (textureHeight - patch.height);
  63.  
  64.         // Generate RGB data for the patch
  65.         patch.data.resize(patch.width * patch.height * 3);
  66.         std::fill(patch.data.begin(), patch.data.end(), static_cast<unsigned char>((i * 5) % 256)); // Fill with a color
  67.         patches.push_back(patch);
  68.     }
  69. }
  70.  
  71. // Group patches into grid cells
  72. void groupPatchesIntoCells(std::map<std::pair<int, int>, std::vector<RGBPatch>>& gridCells,
  73.                            const std::vector<RGBPatch>& patches) {
  74.     for (const auto& patch : patches) {
  75.         // Calculate which cells this patch belongs to
  76.         int startCellX = patch.x_offset / GRID_CELL_SIZE;
  77.         int startCellY = patch.y_offset / GRID_CELL_SIZE;
  78.         int endCellX = (patch.x_offset + patch.width - 1) / GRID_CELL_SIZE;
  79.         int endCellY = (patch.y_offset + patch.height - 1) / GRID_CELL_SIZE;
  80.  
  81.         // Add the patch to all overlapping cells
  82.         for (int cellY = startCellY; cellY <= endCellY; ++cellY) {
  83.             for (int cellX = startCellX; cellX <= endCellX; ++cellX) {
  84.                 gridCells[{cellX, cellY}].push_back(patch);
  85.             }
  86.         }
  87.     }
  88. }
  89.  
  90. // Compile a shader
  91. GLuint compileShader(GLenum shaderType, const char* source) {
  92.     GLuint shader = glCreateShader(shaderType);
  93.     glShaderSource(shader, 1, &source, nullptr);
  94.     glCompileShader(shader);
  95.  
  96.     // Check for compilation errors
  97.     int success;
  98.     char infoLog[512];
  99.     glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  100.     if (!success) {
  101.         glGetShaderInfoLog(shader, 512, nullptr, infoLog);
  102.         std::cerr << "ERROR: Shader Compilation Failed\n" << infoLog << std::endl;
  103.     }
  104.     return shader;
  105. }
  106.  
  107. // Link shaders into a program
  108. GLuint createShaderProgram(const char* vertexSource, const char* fragmentSource) {
  109.     GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexSource);
  110.     GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
  111.  
  112.     GLuint program = glCreateProgram();
  113.     glAttachShader(program, vertexShader);
  114.     glAttachShader(program, fragmentShader);
  115.     glLinkProgram(program);
  116.  
  117.     // Check for linking errors
  118.     int success;
  119.     char infoLog[512];
  120.     glGetProgramiv(program, GL_LINK_STATUS, &success);
  121.     if (!success) {
  122.         glGetProgramInfoLog(program, 512, nullptr, infoLog);
  123.         std::cerr << "ERROR: Shader Linking Failed\n" << infoLog << std::endl;
  124.     }
  125.  
  126.     glDeleteShader(vertexShader);
  127.     glDeleteShader(fragmentShader);
  128.     return program;
  129. }
  130.  
  131. int main() {
  132.     if (!glfwInit()) {
  133.         std::cerr << "Failed to initialize GLFW" << std::endl;
  134.         return -1;
  135.     }
  136.  
  137.     GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Cell-Based Texture Updates", nullptr, nullptr);
  138.     if (!window) {
  139.         std::cerr << "Failed to create GLFW window" << std::endl;
  140.         glfwTerminate();
  141.         return -1;
  142.     }
  143.     glfwMakeContextCurrent(window);
  144.  
  145.     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
  146.         std::cerr << "Failed to initialize GLAD" << std::endl;
  147.         return -1;
  148.     }
  149.  
  150.     // Create a shader program
  151.     GLuint shaderProgram = createShaderProgram(vertexShaderSource, fragmentShaderSource);
  152.  
  153.     // Define fullscreen quad vertices and texture coordinates
  154.     float quadVertices[] = {
  155.         // Positions     // Texture Coords
  156.         -1.0f, -1.0f,    0.0f, 0.0f,  // Bottom-left
  157.          1.0f, -1.0f,    1.0f, 0.0f,  // Bottom-right
  158.         -1.0f,  1.0f,    0.0f, 1.0f,  // Top-left
  159.          1.0f,  1.0f,    1.0f, 1.0f   // Top-right
  160.     };
  161.  
  162.     // Create VAO and VBO
  163.     GLuint VAO, VBO;
  164.     glGenVertexArrays(1, &VAO);
  165.     glGenBuffers(1, &VBO);
  166.  
  167.     glBindVertexArray(VAO);
  168.  
  169.     glBindBuffer(GL_ARRAY_BUFFER, VBO);
  170.     glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
  171.  
  172.     // Position attribute
  173.     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
  174.     glEnableVertexAttribArray(0);
  175.  
  176.     // Texture coordinate attribute
  177.     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
  178.     glEnableVertexAttribArray(1);
  179.  
  180.     // Create a texture
  181.     GLuint texture;
  182.     glGenTextures(1, &texture);
  183.     glBindTexture(GL_TEXTURE_2D, texture);
  184.  
  185.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
  186.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  187.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  188.  
  189.     // Generate patches
  190.     std::vector<RGBPatch> patches;
  191.     createPatches(patches, 1000, WINDOW_WIDTH, WINDOW_HEIGHT);
  192.  
  193.     // FPS calculation variables
  194.     double previousTime = glfwGetTime();
  195.     int frameCount = 0;
  196.  
  197.     // Main render loop
  198.     unsigned char colorValue = 0;
  199.     while (!glfwWindowShouldClose(window)) {
  200.         // Increment the color value for dynamic updates
  201.         colorValue = (colorValue + 1) % 256;
  202.  
  203.         // Update patch colors dynamically
  204.         for (auto& patch : patches) {
  205.             std::fill(patch.data.begin(), patch.data.end(), colorValue);
  206.         }
  207.  
  208.         // Group patches into grid cells
  209.         std::map<std::pair<int, int>, std::vector<RGBPatch>> gridCells;
  210.         groupPatchesIntoCells(gridCells, patches);
  211.  
  212.         // Update each cell
  213.         for (const auto& [cell, cellPatches] : gridCells) {
  214.             // Calculate the bounding box for this cell
  215.             int minX = cell.first * GRID_CELL_SIZE;
  216.             int minY = cell.second * GRID_CELL_SIZE;
  217.             int maxX = minX + GRID_CELL_SIZE;
  218.             int maxY = minY + GRID_CELL_SIZE;
  219.  
  220.             // Adjust the bounding box based on the patches in this cell
  221.             for (const auto& patch : cellPatches) {
  222.                 minX = std::min(minX, patch.x_offset);
  223.                 minY = std::min(minY, patch.y_offset);
  224.                 maxX = std::max(maxX, patch.x_offset + patch.width);
  225.                 maxY = std::max(maxY, patch.y_offset + patch.height);
  226.             }
  227.  
  228.             int updateWidth = maxX - minX;
  229.             int updateHeight = maxY - minY;
  230.  
  231.             // Allocate a buffer for the cell's affected region
  232.             std::vector<unsigned char> cellBuffer(updateWidth * updateHeight * 3, 0);
  233.  
  234.             // Fill the buffer with patch data
  235.             for (const auto& patch : cellPatches) {
  236.                 for (int y = 0; y < patch.height; ++y) {
  237.                     for (int x = 0; x < patch.width; ++x) {
  238.                         int patchIndex = (y * patch.width + x) * 3;
  239.                         int cellIndex = ((patch.y_offset - minY + y) * updateWidth + (patch.x_offset - minX + x)) * 3;
  240.  
  241.                         cellBuffer[cellIndex + 0] = patch.data[patchIndex + 0]; // Red
  242.                         cellBuffer[cellIndex + 1] = patch.data[patchIndex + 1]; // Green
  243.                         cellBuffer[cellIndex + 2] = patch.data[patchIndex + 2]; // Blue
  244.                     }
  245.                 }
  246.             }
  247.  
  248.             // Update the texture for this cell
  249.             glTexSubImage2D(GL_TEXTURE_2D, 0, minX, minY, updateWidth, updateHeight, GL_RGB, GL_UNSIGNED_BYTE, cellBuffer.data());
  250.         }
  251.  
  252.         // Render the texture
  253.         glClear(GL_COLOR_BUFFER_BIT);
  254.         glUseProgram(shaderProgram);
  255.         glBindVertexArray(VAO);
  256.         glBindTexture(GL_TEXTURE_2D, texture);
  257.         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  258.  
  259.         // Calculate FPS
  260.         double currentTime = glfwGetTime();
  261.         frameCount++;
  262.         if (currentTime - previousTime >= 1.0) {
  263.             int fps = frameCount;
  264.             frameCount = 0;
  265.             previousTime = currentTime;
  266.  
  267.             // Update window title with FPS
  268.             std::string title = "Cell-Based Texture Updates - FPS: " + std::to_string(fps);
  269.             glfwSetWindowTitle(window, title.c_str());
  270.         }
  271.  
  272.         // Swap buffers and poll events
  273.         glfwSwapBuffers(window);
  274.         glfwPollEvents();
  275.     }
  276.  
  277.     // Cleanup
  278.     glDeleteBuffers(1, &VBO);
  279.     glDeleteVertexArrays(1, &VAO);
  280.     glDeleteTextures(1, &texture);
  281.     glDeleteProgram(shaderProgram);
  282.  
  283.     glfwTerminate();
  284.     return 0;
  285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement