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); |