Advertisement
bekovski

temp2

Jan 15th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.84 KB | None | 0 0
  1. #include "pch.h"
  2.  
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <thread>
  6.  
  7. #include <Kore/IO/FileReader.h>
  8. #include <Kore/Math/Core.h>
  9. #include <Kore/System.h>
  10. #include <Kore/Input/Keyboard.h>
  11. #include <Kore/Input/Mouse.h>
  12. #include <Kore/Graphics1/Image.h>
  13. #include <Kore/Graphics4/Graphics.h>
  14. #include <Kore/Graphics4/PipelineState.h>
  15. #include <Kore/Threads/Thread.h>
  16. #include <Kore/Threads/Mutex.h>
  17. #include "Memory.h"
  18. #include "ObjLoader.h"
  19.  
  20. #include <vector>
  21. #include <new>
  22.  
  23. using namespace Kore;
  24.  
  25. class MeshData {
  26. public:
  27.     MeshData(const char* meshFile, const Graphics4::VertexStructure& structure) {
  28.         mesh = loadObj(meshFile);
  29.  
  30.         vertexBuffer = new Graphics4::VertexBuffer(mesh->numVertices, structure);
  31.         float* vertices = vertexBuffer->lock();
  32.         for (int i = 0; i < mesh->numVertices; ++i) {
  33.             vertices[i * 8 + 0] = mesh->vertices[i * 8 + 0];
  34.             vertices[i * 8 + 1] = mesh->vertices[i * 8 + 1];
  35.             vertices[i * 8 + 2] = mesh->vertices[i * 8 + 2];
  36.             vertices[i * 8 + 3] = mesh->vertices[i * 8 + 3];
  37.             vertices[i * 8 + 4] = 1.0f - mesh->vertices[i * 8 + 4];
  38.             vertices[i * 8 + 5] = mesh->vertices[i * 8 + 5];
  39.             vertices[i * 8 + 6] = mesh->vertices[i * 8 + 6];
  40.             vertices[i * 8 + 7] = mesh->vertices[i * 8 + 7];
  41.         }
  42.         vertexBuffer->unlock();
  43.  
  44.         indexBuffer = new Graphics4::IndexBuffer(mesh->numFaces * 3);
  45.         int* indices = indexBuffer->lock();
  46.         for (int i = 0; i < mesh->numFaces * 3; i++) {
  47.             indices[i] = mesh->indices[i];
  48.         }
  49.         indexBuffer->unlock();
  50.     }
  51.  
  52.     Graphics4::VertexBuffer* vertexBuffer;
  53.     Graphics4::IndexBuffer* indexBuffer;
  54.     Mesh* mesh;
  55. };
  56.  
  57. class MeshObject {
  58. public:
  59.     MeshObject(MeshData* mesh, Graphics4::Texture* image, vec3 position) : mesh(mesh), image(image) {
  60.         M = mat4::Translation(position.x(), position.y(), position.z());
  61.     }
  62.  
  63.     void render(Graphics4::TextureUnit tex) {
  64.         Graphics4::setTexture(tex, image);
  65.         Graphics4::setVertexBuffer(*mesh->vertexBuffer);
  66.         Graphics4::setIndexBuffer(*mesh->indexBuffer);
  67.         Graphics4::drawIndexedVertices();
  68.     }
  69.  
  70.     void setTexture(Graphics4::Texture* tex) {
  71.         image = tex;
  72.     }
  73.  
  74.     Graphics4::Texture* getTexture() {
  75.         return image;
  76.     }
  77.  
  78.     mat4 M;
  79. private:
  80.     MeshData* mesh;
  81.     Graphics4::Texture* image;
  82. };
  83.  
  84. namespace {
  85.     const int width = 1024;
  86.     const int height = 768;
  87.     double startTime;
  88.     Graphics4::Shader* vertexShader;
  89.     Graphics4::Shader* fragmentShader;
  90.     Graphics4::PipelineState* pipeline;
  91.  
  92.     // null terminated array of MeshObject pointers
  93.     MeshObject** objects;
  94.  
  95.     // The view projection matrix aka the camera
  96.     mat4 P;
  97.     mat4 V;
  98.  
  99.     vec3 position;
  100.     bool up = false, down = false, left = false, right = false;
  101.  
  102.     Thread* streamingThread;
  103.     Mutex streamMutex;
  104.  
  105.     // uniform locations - add more as you see fit
  106.     Graphics4::TextureUnit tex;
  107.     Graphics4::ConstantLocation pLocation;
  108.     Graphics4::ConstantLocation vLocation;
  109.     Graphics4::ConstantLocation mLocation;
  110.  
  111.     float angle;
  112.  
  113.     char* images;
  114.     bool* imageLoaded;
  115.     Graphics4::Image* imgs = (Graphics4::Image*)images;
  116.  
  117.     void loadImageAsyncHelper(Graphics4::Image* img, const char* filename, bool& loaded) {
  118.         if (!loaded) {
  119.             new(img) Graphics4::Image(filename, true);
  120.             loaded = true;
  121.         }
  122.     }
  123.  
  124.     // load image if it hasn't been loaded yet
  125.     void loadImageAsync(Graphics4::Image* img, const char* filename, bool& loaded) {
  126.         std::thread t1([&]() {
  127.             loadImageAsyncHelper(img, filename, loaded);
  128.         });
  129.         t1.join();
  130.     }
  131.  
  132.     void stream(void*) {
  133.         for (;;) {
  134.             // to use a mutex, create a Mutex variable and call Create to initialize the mutex (see main()). Then you can use Lock/Unlock.
  135.             streamMutex.Lock();
  136.  
  137.             // load darmstadt.jpg files for near boxes
  138.             // reload darmstadt.jpg for every box, pretend that every box has a different texture (I don't want to upload 100 images though)
  139.             // feel free to create more versions of darmstadt.jpg at different sizes
  140.             // always use less than 1 million pixels of texture data (the example code uses 100 16x16 textures - that's 25600 pixels, darmstadt.jpg is 512x512 aka 262144 pixels)
  141.  
  142.             // Beware, neither OpenGL nor Direct3D is thread safe - you can't just create a Texture in a second thread. But you can create a Kore::Image
  143.             // in another thread, access its pixels in the main thread and put them in a Kore::Texture using lock/unlock.
  144.  
  145.             // first get the position of every box
  146.             // TODO: only consider those boxes that are visible to the camera
  147.             std::vector<vec3> temp;
  148.             for (int y = 0; y < 10; ++y) {
  149.                 for (int x = 0; x < 10; ++x) {
  150.                     // 0.. 99
  151.                     MeshObject** current = &objects[y * 10 + x];
  152.                     mat4 M = (*current)->M;
  153.                     vec3 currentPos(M.get(0, 3), M.get(1, 3), M.get(2, 3));
  154.                     if (currentPos.z() > position.z())   // TODO: not sufficient to filter out non-visible boxes
  155.                         temp.push_back(currentPos);
  156.                 }
  157.             }
  158.  
  159.             // now sort them by their distance to the camera position
  160.             struct distance_to_position {
  161.                 inline bool operator() (const vec3& objPosition1, const vec3& objPosition2) {
  162.                     float dist1 = position.distance(objPosition1);
  163.                     float dist2 = position.distance(objPosition2);
  164.  
  165.                     return dist1 < dist2;
  166.                 }
  167.             };
  168.             std::sort(temp.begin(), temp.end(), distance_to_position());
  169.  
  170.             // the closest boxes get high resolution: 3 * 512^2 = 786432
  171.             std::vector<vec3> nearestBoxes;
  172.             nearestBoxes.push_back(temp[0]);
  173.             nearestBoxes.push_back(temp[1]);
  174.             nearestBoxes.push_back(temp[2]);
  175.  
  176.             // meidum resolution: 2 * 256^2 = 131072
  177.             std::vector<vec3> second_nearestBoxes;
  178.             second_nearestBoxes.push_back(temp[3]);
  179.             second_nearestBoxes.push_back(temp[4]);
  180.             // second_nearestBoxes.push_back(temp[5]);
  181.  
  182.             // small resolution: 3 * 128^2 = 49152
  183.             std::vector<vec3> third_nearestBoxes;
  184.             third_nearestBoxes.push_back(temp[5]);
  185.             third_nearestBoxes.push_back(temp[6]);  // 6 and 7 are not visible to the camera
  186.             third_nearestBoxes.push_back(temp[7]);
  187.  
  188.  
  189.             // 100 - 8 = 92 * 16^2 = 23552
  190.             // total: 3*512^2 + 2*256^2 + 3*128^2 + 92*16^2 = 990208 < 1 million pixels
  191.             /*Graphics4::Image* imgs = (Graphics4::Image*)images;*/
  192.             for (int y = 0; y < 10; ++y) {
  193.                 for (int x = 0; x < 10; ++x) {
  194.                     MeshObject** current = &objects[y * 10 + x];
  195.                     mat4 M = (*current)->M;
  196.                     vec3 currentPos(M.get(0, 3), M.get(1, 3), M.get(2, 3));
  197.  
  198.                     // if close (at most 3? using 4 of these already over 1 million pixels)
  199.                     if (std::find(nearestBoxes.begin(), nearestBoxes.end(), currentPos) != nearestBoxes.end()) {
  200.                         //if (imageLoaded[y * 10 + x]) { // Graphic is already loaded
  201.                         //  (*current)->setTexture(new Graphics4::Texture(imgs[y * 10 + x].data, imgs[y * 10 + x].width, imgs[y * 10 + x].height,
  202.                         //      imgs[y * 10 + x].dataSize, imgs[y * 10 + x].format, imgs[y * 10 + x].readable));
  203.                         //}
  204.                         //else { // Start loading thread
  205.                         //  loadImageAsync(&imgs[y * 10 + x], "darmstadt.jpg", imageLoaded[y * 10 + x]);
  206.                         //}
  207.  
  208.                         //(*current)->setTexture(new Graphics4::Texture("darmstadt.jpg", true));
  209.                     }
  210.                     else if (std::find(second_nearestBoxes.begin(), second_nearestBoxes.end(), currentPos) != second_nearestBoxes.end()) {
  211.                         //if (imageLoaded[y * 10 + x + 100]) { // Graphic is already loaded
  212.                         //  (*current)->setTexture(new Graphics4::Texture(imgs[y * 10 + x + 100].data, imgs[y * 10 + x + 100].width, imgs[y * 10 + x + 100].height,
  213.                         //      imgs[y * 10 + x + 100].dataSize, imgs[y * 10 + x + 100].format, imgs[y * 10 + x + 100].readable));
  214.                         //}
  215.                         //else { // Start loading thread
  216.                         //  loadImageAsync(&imgs[y * 10 + x + 100], "darmstadtmedium.jpg", imageLoaded[y * 10 + x + 100]);
  217.                         //}
  218.  
  219.                         //(*current)->setTexture(new Graphics4::Texture("darmstadtmedium.jpg", true));
  220.                     }
  221.                     else if (std::find(third_nearestBoxes.begin(), third_nearestBoxes.end(), currentPos) != third_nearestBoxes.end()) {
  222.                         //if (imageLoaded[y * 10 + x + 200]) { // Graphic is already loaded
  223.                         //  (*current)->setTexture(new Graphics4::Texture(imgs[y * 10 + x + 200].data, imgs[y * 10 + x + 200].width, imgs[y * 10 + x + 200].height,
  224.                         //      imgs[y * 10 + x + 200].dataSize, imgs[y * 10 + x + 200].format, imgs[y * 10 + x + 200].readable));
  225.                         //}
  226.                         //else { // Start loading thread
  227.                         //  loadImageAsync(&imgs[y * 10 + x + 200], "darmstadtsmall.jpg", imageLoaded[y * 10 + x + 200]);
  228.                         //}
  229.  
  230.                         //(*current)->setTexture(new Graphics4::Texture("darmstadtsmall.jpg", true));
  231.                     }
  232.                     else {
  233.                         //if (imageLoaded[y * 10 + x + 300]) { // Graphic is already loaded
  234.                         //  (*current)->setTexture(new Graphics4::Texture(imgs[y * 10 + x + 300].data, imgs[y * 10 + x + 300].width, imgs[y * 10 + x + 300].height,
  235.                         //      imgs[y * 10 + x + 300].dataSize, imgs[y * 10 + x + 300].format, imgs[y * 10 + x + 300].readable));
  236.                         //}
  237.                         //else { // Start loading thread
  238.                         //  loadImageAsync(&imgs[y * 10 + x + 300], "darmstadtmini.png", imageLoaded[y * 10 + x + 300]);
  239.                         //}
  240.  
  241.                         if (imageLoaded[y * 10 + x + 300]) {
  242.                             u8* texPointer = (*current)->getTexture()->lock();
  243.                             // memcpy(pointer, darmstadt16.data, (size_t) (darmstadt16.width * darmstadt16.height * darmstadt16.sizeOf(darmstadt16.format))); // use low res texture
  244.                             Graphics1::Image* imgPointer = &imgs[y * 10 + x + 300];
  245.                             memcpy(texPointer, imgPointer->data, (size_t)(imgPointer->width * imgPointer->height * imgPointer->sizeOf(imgPointer->format)));
  246.                             (*current)->getTexture()->unlock();
  247.                         }
  248.  
  249.                         //(*current)->setTexture(new Graphics4::Texture("darmstadtmini.png", true));
  250.                     }
  251.                 }
  252.             }
  253.  
  254.             streamMutex.Unlock();
  255.         }
  256.     }
  257.  
  258.     void update() {
  259.         float t = (float)(System::time() - startTime);
  260.  
  261.         const float speed = 0.1f;
  262.         if (up) position.z() += speed;
  263.         if (down) position.z() -= speed;
  264.         if (left) position.x() -= speed;
  265.         if (right) position.x() += speed;
  266.  
  267.         Graphics4::begin();
  268.         Graphics4::clear(Graphics4::ClearColorFlag | Graphics4::ClearDepthFlag, 0xff9999FF, 1.0f);
  269.  
  270.         Graphics4::setPipeline(pipeline);
  271.  
  272.  
  273.         // set the camera
  274.         P = mat4::Perspective(pi / 4.0f, (float)width / (float)height, 0.1f, 100);
  275.         V = mat4::lookAt(position, vec3(0, 0, 1000), vec3(0, 1, 0));
  276.         Graphics4::setMatrix(pLocation, P);
  277.         Graphics4::setMatrix(vLocation, V);
  278.  
  279.  
  280.         angle = t;
  281.  
  282.  
  283.         //objects[0]->M = mat4::RotationY(angle) * mat4::RotationZ(Kore::pi / 4.0f);
  284.  
  285.         for (int y = 0; y < 10; ++y) {
  286.             for (int x = 0; x < 10; ++x) {
  287.                 MeshObject** current = &objects[y * 10 + x];
  288.                 mat4 M = (*current)->M;
  289.                 vec3 currentPos(M.get(0, 3), M.get(1, 3), M.get(2, 3));
  290.  
  291.                 if (!imageLoaded[y * 10 + x + 300]) {
  292.                     loadImageAsync(&imgs[y * 10 + x + 300], "darmstadtmini.png", imageLoaded[y * 10 + x + 300]);
  293.                 }
  294.             }
  295.         }
  296.  
  297.         // iterate the MeshObjects
  298.         MeshObject** current = &objects[0];
  299.         while (*current != nullptr) {
  300.             // set the model matrix
  301.             Graphics4::setMatrix(mLocation, (*current)->M);
  302.  
  303.             (*current)->render(tex);
  304.             ++current;
  305.         }
  306.  
  307.         Graphics4::end();
  308.         Graphics4::swapBuffers();
  309.     }
  310.  
  311.     void mouseMove(int windowId, int x, int y, int movementX, int movementY) {
  312.  
  313.     }
  314.  
  315.     void mousePress(int windowId, int button, int x, int y) {
  316.  
  317.     }
  318.  
  319.     void mouseRelease(int windowId, int button, int x, int y) {
  320.  
  321.     }
  322.  
  323.     void keyDown(KeyCode code) {
  324.         switch (code) {
  325.         case KeyLeft:
  326.             left = true;
  327.             break;
  328.         case KeyRight:
  329.             right = true;
  330.             break;
  331.         case KeyUp:
  332.             up = true;
  333.             break;
  334.         case KeyDown:
  335.             down = true;
  336.             break;
  337.         }
  338.     }
  339.  
  340.     void keyUp(KeyCode code) {
  341.         switch (code) {
  342.         case KeyLeft:
  343.             left = false;
  344.             break;
  345.         case KeyRight:
  346.             right = false;
  347.             break;
  348.         case KeyUp:
  349.             up = false;
  350.             break;
  351.         case KeyDown:
  352.             down = false;
  353.             break;
  354.         }
  355.     }
  356.  
  357.  
  358.     void init() {
  359.         images = (char*)malloc(400 * sizeof(Graphics4::Image)); // allocate memory for four versions of the image
  360.         imageLoaded = new bool[400];                            // boolean array to save if image was already loaded
  361.         for (int i = 0; i < 400; i++)
  362.             imageLoaded[i] = false;
  363.  
  364.         FileReader vs("shader.vert");
  365.         FileReader fs("shader.frag");
  366.         vertexShader = new Graphics4::Shader(vs.readAll(), vs.size(), Graphics4::VertexShader);
  367.         fragmentShader = new Graphics4::Shader(fs.readAll(), fs.size(), Graphics4::FragmentShader);
  368.  
  369.         // This defines the structure of your Vertex Buffer
  370.         Graphics4::VertexStructure structure;
  371.         structure.add("pos", Graphics4::Float3VertexData);
  372.         structure.add("tex", Graphics4::Float2VertexData);
  373.         structure.add("nor", Graphics4::Float3VertexData);
  374.  
  375.  
  376.         pipeline = new Graphics4::PipelineState;
  377.         pipeline->inputLayout[0] = &structure;
  378.         pipeline->inputLayout[1] = nullptr;
  379.         pipeline->vertexShader = vertexShader;
  380.         pipeline->fragmentShader = fragmentShader;
  381.         pipeline->depthMode = Graphics4::ZCompareLess;
  382.         pipeline->depthWrite = true;
  383.         pipeline->compile();
  384.  
  385.         tex = pipeline->getTextureUnit("tex");
  386.         pLocation = pipeline->getConstantLocation("P");
  387.         vLocation = pipeline->getConstantLocation("V");
  388.         mLocation = pipeline->getConstantLocation("M");
  389.  
  390.         objects = new MeshObject*[101];
  391.         for (int i = 0; i < 101; ++i) objects[i] = nullptr;
  392.  
  393.         MeshData* mesh = new MeshData("box.obj", structure);
  394.         for (int y = 0; y < 10; ++y) {
  395.             for (int x = 0; x < 10; ++x) {
  396.                 objects[y * 10 + x] = new MeshObject(mesh, new Graphics4::Texture("darmstadtmini.png", true), vec3((x - 5.0f) * 10, 0, (y - 5.0f) * 10));
  397.             }
  398.         }
  399.  
  400.         angle = 0.0f;
  401.  
  402.         Graphics4::setTextureAddressing(tex, Graphics4::U, Graphics4::Repeat);
  403.         Graphics4::setTextureAddressing(tex, Graphics4::V, Graphics4::Repeat);
  404.     }
  405. }
  406.  
  407. int kore(int argc, char** argv) {
  408.  
  409.  
  410.     Kore::System::init("Exercise 10", width, height);
  411.  
  412.     Memory::init();
  413.     init();
  414.  
  415.     Kore::System::setCallback(update);
  416.  
  417.     startTime = System::time();
  418.  
  419.     Keyboard::the()->KeyDown = keyDown;
  420.     Keyboard::the()->KeyUp = keyUp;
  421.     Mouse::the()->Move = mouseMove;
  422.     Mouse::the()->Press = mousePress;
  423.     Mouse::the()->Release = mouseRelease;
  424.  
  425.     streamMutex.Create();
  426.     Kore::threadsInit();
  427.     streamingThread = Kore::createAndRunThread(stream, nullptr);
  428.  
  429.     Kore::System::start();
  430.  
  431.     return 0;
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement