summaryrefslogtreecommitdiff
path: root/examples/example_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/example_opengl.cpp')
-rw-r--r--examples/example_opengl.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/examples/example_opengl.cpp b/examples/example_opengl.cpp
new file mode 100644
index 0000000..1879864
--- /dev/null
+++ b/examples/example_opengl.cpp
@@ -0,0 +1,162 @@
+/*
+LodePNG Examples
+
+Copyright (c) 2005-2012 Lode Vandevenne
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+*/
+
+//Compile command for Linux:
+//g++ lodepng.cpp example_opengl.cpp -lSDL -lGL -O3
+
+/*
+LodePNG OpenGL example. Decodes a PNG and shows it in OpenGL. PNG filename
+should be given as a command line parameter.
+
+It's written for the most basic old OpenGL version, and a correction for non
+power of two textures had to be added.
+
+Only very few lines on the sample are about loading the PNG. Most of the
+sample lines show a way to render a texture in 2D in OpenGL.
+
+No fancy 3D graphics are shown, it only shows the image statically. The sample
+shows LodePNG can be used to load PNG images as textures in OpenGL.
+*/
+
+#include "lodepng.h"
+
+#include <iostream>
+#include <SDL/SDL.h>
+#include <GL/gl.h>
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ std::cout << "Please provide a filename." << std::endl;
+ return 1;
+ }
+ const char* filename = argv[1];
+
+ // Load file and decode image.
+ std::vector<unsigned char> image;
+ unsigned width, height;
+ unsigned error = lodepng::decode(image, width, height, filename);
+
+ // If there's an error, display it.
+ if(error != 0)
+ {
+ std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl;
+ return 1;
+ }
+
+ // Here the PNG is loaded in "image". All the rest of the code is SDL and OpenGL stuff.
+
+ int screenw = width;
+ if(screenw > 1024) screenw = 1024;
+ int screenh = height;
+ if(screenh > 768) screenw = 768;
+
+ if(SDL_Init(SDL_INIT_VIDEO) < 0)
+ {
+ std::cout << "Error: Unable to init SDL: " << SDL_GetError() << std::endl;
+ return 1;
+ }
+
+ SDL_Surface* scr = SDL_SetVideoMode(screenw, screenh, 32, SDL_OPENGL);
+
+ if(scr == 0)
+ {
+ std::cout << "Error: Unable to set video. SDL error message: " << SDL_GetError() << std::endl;
+ return 1;
+ }
+
+ // The official code for "Setting Your Raster Position to a Pixel Location" (i.e. set up a camera for 2D screen)
+ glViewport(0, 0, screenw, screenh);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, screenw, screenh, 0, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // Make some OpenGL properties better for 2D and enable alpha channel.
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+
+ if(glGetError() != GL_NO_ERROR)
+ {
+ std::cout << "Error initing GL" << std::endl;
+ return 1;
+ }
+
+ // Texture size must be power of two for the primitive OpenGL version this is written for. Find next power of two.
+ size_t u2 = 1; while(u2 < width) u2 *= 2;
+ size_t v2 = 1; while(v2 < height) v2 *= 2;
+ // Ratio for power of two version compared to actual version, to render the non power of two image with proper size.
+ double u3 = (double)width / u2;
+ double v3 = (double)height / v2;
+
+ // Make power of two version of the image.
+ std::vector<unsigned char> image2(u2 * v2 * 4);
+ for(size_t y = 0; y < height; y++)
+ for(size_t x = 0; x < width; x++)
+ for(size_t c = 0; c < 4; c++)
+ {
+ image2[4 * u2 * y + 4 * x + c] = image[4 * width * y + 4 * x + c];
+ }
+
+ // Enable the texture for OpenGL.
+ glEnable(GL_TEXTURE_2D);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_NEAREST = no smoothing
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, u2, v2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &image2[0]);
+
+ bool done = false;
+ SDL_Event event = {0};
+ glColor4ub(255, 255, 255, 255);
+
+ while(!done)
+ {
+ // Quit the loop when receiving quit event.
+ while(SDL_PollEvent(&event))
+ {
+ if(event.type == SDL_QUIT) done = 1;
+ }
+
+ // Draw the texture on a quad, using u3 and v3 to correct non power of two texture size.
+ glBegin(GL_QUADS);
+ glTexCoord2d( 0, 0); glVertex2f( 0, 0);
+ glTexCoord2d(u3, 0); glVertex2f(width, 0);
+ glTexCoord2d(u3, v3); glVertex2f(width, height);
+ glTexCoord2d( 0, v3); glVertex2f( 0, height);
+ glEnd();
+
+ // Redraw and clear screen.
+ SDL_GL_SwapBuffers();
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ //Limit frames per second, to not heat up the CPU and GPU too much.
+ SDL_Delay(16);
+ }
+}