diff options
Diffstat (limited to 'src/renderer.cpp')
| -rw-r--r-- | src/renderer.cpp | 148 |
1 files changed, 64 insertions, 84 deletions
| diff --git a/src/renderer.cpp b/src/renderer.cpp index b0421e3..6c8a88a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
| @@ -5,6 +5,13 @@ | |||
| 5 | #include <cstdio> | 5 | #include <cstdio> |
| 6 | #include <cstring> | 6 | #include <cstring> |
| 7 | #include "mapview.h" | 7 | #include "mapview.h" |
| 8 | #include <cstdlib> | ||
| 9 | |||
| 10 | // include stb_image | ||
| 11 | #define STB_IMAGE_IMPLEMENTATION | ||
| 12 | #define STBI_ONLY_PNG | ||
| 13 | #define STBI_ONLY_BMP | ||
| 14 | #include "stb_image.h" | ||
| 8 | 15 | ||
| 9 | static bool rendererInitialized = false; | 16 | static bool rendererInitialized = false; |
| 10 | 17 | ||
| @@ -120,83 +127,19 @@ GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) | |||
| 120 | return ProgramID; | 127 | return ProgramID; |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 123 | GLuint loadBMP_custom(const char * imagepath){ | 130 | void flipImageData(unsigned char* data, int width, int height, int comps) |
| 124 | 131 | { | |
| 125 | printf("Reading image %s\n", imagepath); | 132 | unsigned char* data_copy = (unsigned char*) malloc(width*height*comps*sizeof(unsigned char)); |
| 126 | 133 | memcpy(data_copy, data, width*height*comps); | |
| 127 | // Data read from the header of the BMP file | 134 | |
| 128 | unsigned char header[54]; | 135 | int row_size = width * comps; |
| 129 | unsigned int dataPos; | 136 | |
| 130 | unsigned int imageSize; | 137 | for (int i=0;i<height;i++) |
| 131 | unsigned int width, height; | 138 | { |
| 132 | // Actual RGB data | 139 | memcpy(data + (row_size*i), data_copy + (row_size*(height-i-1)), row_size); |
| 133 | unsigned char * data; | 140 | } |
| 134 | 141 | ||
| 135 | // Open the file | 142 | free(data_copy); |
| 136 | FILE * file = fopen(imagepath,"rb"); | ||
| 137 | if (!file) {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;} | ||
| 138 | |||
| 139 | // Read the header, i.e. the 54 first bytes | ||
| 140 | |||
| 141 | // If less than 54 bytes are read, problem | ||
| 142 | if ( fread(header, 1, 54, file)!=54 ){ | ||
| 143 | printf("Not a correct BMP file\n"); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | // A BMP files always begins with "BM" | ||
| 147 | if ( header[0]!='B' || header[1]!='M' ){ | ||
| 148 | printf("Not a correct BMP file\n"); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | // Make sure this is a 24bpp file | ||
| 152 | if ( *(int*)&(header[0x1E])!=0 ) {printf("Not a correct BMP file\n"); return 0;} | ||
| 153 | if ( *(int*)&(header[0x1C])!=24 ) {printf("Not a correct BMP file\n"); return 0;} | ||
| 154 | |||
| 155 | // Read the information about the image | ||
| 156 | dataPos = *(int*)&(header[0x0A]); | ||
| 157 | imageSize = *(int*)&(header[0x22]); | ||
| 158 | width = *(int*)&(header[0x12]); | ||
| 159 | height = *(int*)&(header[0x16]); | ||
| 160 | |||
| 161 | // Some BMP files are misformatted, guess missing information | ||
| 162 | if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component | ||
| 163 | if (dataPos==0) dataPos=54; // The BMP header is done that way | ||
| 164 | |||
| 165 | // Create a buffer | ||
| 166 | data = new unsigned char [imageSize]; | ||
| 167 | |||
| 168 | // Read the actual data from the file into the buffer | ||
| 169 | fread(data,1,imageSize,file); | ||
| 170 | |||
| 171 | // Everything is in memory now, the file wan be closed | ||
| 172 | fclose (file); | ||
| 173 | |||
| 174 | // Create one OpenGL texture | ||
| 175 | GLuint textureID; | ||
| 176 | glGenTextures(1, &textureID); | ||
| 177 | |||
| 178 | // "Bind" the newly created texture : all future texture functions will modify this texture | ||
| 179 | glBindTexture(GL_TEXTURE_2D, textureID); | ||
| 180 | |||
| 181 | // Give the image to OpenGL | ||
| 182 | glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); | ||
| 183 | |||
| 184 | // OpenGL has now copied the data. Free our own version | ||
| 185 | delete [] data; | ||
| 186 | |||
| 187 | // Poor filtering, or ... | ||
| 188 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 189 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 190 | |||
| 191 | // ... nice trilinear filtering. | ||
| 192 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | ||
| 193 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | ||
| 194 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
| 195 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); | ||
| 196 | glGenerateMipmap(GL_TEXTURE_2D); | ||
| 197 | |||
| 198 | // Return the ID of the texture we just created | ||
| 199 | return textureID; | ||
| 200 | } | 143 | } |
| 201 | 144 | ||
| 202 | void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) | 145 | void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) |
| @@ -333,9 +276,14 @@ GLFWwindow* initRenderer() | |||
| 333 | glGenVertexArrays(1, &VertexArrayID); | 276 | glGenVertexArrays(1, &VertexArrayID); |
| 334 | glBindVertexArray(VertexArrayID); | 277 | glBindVertexArray(VertexArrayID); |
| 335 | 278 | ||
| 279 | // Enable depth testing | ||
| 336 | glEnable(GL_DEPTH_TEST); | 280 | glEnable(GL_DEPTH_TEST); |
| 337 | glDepthFunc(GL_LESS); | 281 | glDepthFunc(GL_LESS); |
| 338 | 282 | ||
| 283 | // Enable blending | ||
| 284 | glEnable(GL_BLEND); | ||
| 285 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
| 286 | |||
| 339 | // Set up the framebuffer | 287 | // Set up the framebuffer |
| 340 | glGenFramebuffers(1, &FramebufferName); | 288 | glGenFramebuffers(1, &FramebufferName); |
| 341 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); | 289 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); |
| @@ -419,8 +367,27 @@ GLFWwindow* initRenderer() | |||
| 419 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); | 367 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); |
| 420 | glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); | 368 | glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); |
| 421 | 369 | ||
| 422 | artifactsTex = loadBMP_custom("../res/artifacts.bmp"); | 370 | glGenTextures(1, &artifactsTex); |
| 423 | scanlinesTex = loadBMP_custom("../res/scanlines.bmp"); | 371 | glBindTexture(GL_TEXTURE_2D, artifactsTex); |
| 372 | int atdw, atdh; | ||
| 373 | unsigned char* artifactsTex_data = stbi_load("../res/artifacts.bmp", &atdw, &atdh, 0, 3); | ||
| 374 | flipImageData(artifactsTex_data, atdw, atdh, 3); | ||
| 375 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, atdw, atdh, 0, GL_RGB, GL_UNSIGNED_BYTE, artifactsTex_data); | ||
| 376 | stbi_image_free(artifactsTex_data); | ||
| 377 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 378 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); | ||
| 379 | glGenerateMipmap(GL_TEXTURE_2D); | ||
| 380 | |||
| 381 | glGenTextures(1, &scanlinesTex); | ||
| 382 | glBindTexture(GL_TEXTURE_2D, scanlinesTex); | ||
| 383 | int stdw, stdh; | ||
| 384 | unsigned char* scanlinesTex_data = stbi_load("../res/scanlines.bmp", &stdw, &stdh, 0, 3); | ||
| 385 | flipImageData(scanlinesTex_data, stdw, stdh, 3); | ||
| 386 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, atdw, atdh, 0, GL_RGB, GL_UNSIGNED_BYTE, scanlinesTex_data); | ||
| 387 | stbi_image_free(scanlinesTex_data); | ||
| 388 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 389 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); | ||
| 390 | glGenerateMipmap(GL_TEXTURE_2D); | ||
| 424 | 391 | ||
| 425 | // Load the shaders | 392 | // Load the shaders |
| 426 | ntscShader = LoadShaders("../shaders/ntsc.vertex", "../shaders/ntsc.fragment"); | 393 | ntscShader = LoadShaders("../shaders/ntsc.vertex", "../shaders/ntsc.fragment"); |
| @@ -492,7 +459,7 @@ Texture* createTexture(int width, int height) | |||
| 492 | 459 | ||
| 493 | glGenTextures(1, &(tex->texID)); | 460 | glGenTextures(1, &(tex->texID)); |
| 494 | glBindTexture(GL_TEXTURE_2D, tex->texID); | 461 | glBindTexture(GL_TEXTURE_2D, tex->texID); |
| 495 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); | 462 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| 496 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 463 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 497 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 464 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 498 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 465 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| @@ -523,11 +490,16 @@ Texture* loadTextureFromBMP(char* filename) | |||
| 523 | } | 490 | } |
| 524 | 491 | ||
| 525 | Texture* tex = new Texture(); | 492 | Texture* tex = new Texture(); |
| 526 | tex->texID = loadBMP_custom(filename); | 493 | glGenTextures(1, &(tex->texID)); |
| 527 | |||
| 528 | glBindTexture(GL_TEXTURE_2D, tex->texID); | 494 | glBindTexture(GL_TEXTURE_2D, tex->texID); |
| 529 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &(tex->width)); | 495 | unsigned char* data = stbi_load(filename, &(tex->width), &(tex->height), 0, 4); |
| 530 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &(tex->height)); | 496 | flipImageData(data, tex->width, tex->height, 4); |
| 497 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | ||
| 498 | stbi_image_free(data); | ||
| 499 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 500 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 501 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 502 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 531 | 503 | ||
| 532 | return tex; | 504 | return tex; |
| 533 | } | 505 | } |
| @@ -787,6 +759,14 @@ void renderScreen(Texture* tex) | |||
| 787 | glUniform1i(glGetUniformLocation(ntscShader, "NTSCArtifactSampler"), 2); | 759 | glUniform1i(glGetUniformLocation(ntscShader, "NTSCArtifactSampler"), 2); |
| 788 | glUniform1f(glGetUniformLocation(ntscShader, "NTSCLerp"), curBuf * 1.0); | 760 | glUniform1f(glGetUniformLocation(ntscShader, "NTSCLerp"), curBuf * 1.0); |
| 789 | 761 | ||
| 762 | if ((rand() % 60) == 0) | ||
| 763 | { | ||
| 764 | // Change the 0.0 to a 1.0 or a 10.0 for a glitchy effect! | ||
| 765 | glUniform1f(glGetUniformLocation(ntscShader, "Tuning_NTSC"), 0.0); | ||
| 766 | } else { | ||
| 767 | glUniform1f(glGetUniformLocation(ntscShader, "Tuning_NTSC"), 0.0); | ||
| 768 | } | ||
| 769 | |||
| 790 | // Render our composition | 770 | // Render our composition |
| 791 | glEnableVertexAttribArray(0); | 771 | glEnableVertexAttribArray(0); |
| 792 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); | 772 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); |
