diff --git a/FinalImgs/CamInteractionThumbnail.png b/FinalImgs/CamInteractionThumbnail.png new file mode 100644 index 0000000..f73998c Binary files /dev/null and b/FinalImgs/CamInteractionThumbnail.png differ diff --git a/FinalImgs/bunny_vertex_shade.png b/FinalImgs/bunny_vertex_shade.png new file mode 100644 index 0000000..4a9bdd9 Binary files /dev/null and b/FinalImgs/bunny_vertex_shade.png differ diff --git a/FinalImgs/cow_blinn_shade.png b/FinalImgs/cow_blinn_shade.png new file mode 100644 index 0000000..c56027f Binary files /dev/null and b/FinalImgs/cow_blinn_shade.png differ diff --git a/FinalImgs/cow_diffuse_shade.png b/FinalImgs/cow_diffuse_shade.png new file mode 100644 index 0000000..ee22525 Binary files /dev/null and b/FinalImgs/cow_diffuse_shade.png differ diff --git a/FinalImgs/cow_point_raster.png b/FinalImgs/cow_point_raster.png new file mode 100644 index 0000000..8af4b05 Binary files /dev/null and b/FinalImgs/cow_point_raster.png differ diff --git a/FinalImgs/cow_shade_by_normal.png b/FinalImgs/cow_shade_by_normal.png new file mode 100644 index 0000000..3e4bf21 Binary files /dev/null and b/FinalImgs/cow_shade_by_normal.png differ diff --git a/FinalImgs/cube_line_raster.png b/FinalImgs/cube_line_raster.png new file mode 100644 index 0000000..cac0240 Binary files /dev/null and b/FinalImgs/cube_line_raster.png differ diff --git a/FinalImgs/performance_zoom_in.png b/FinalImgs/performance_zoom_in.png new file mode 100644 index 0000000..1d0b825 Binary files /dev/null and b/FinalImgs/performance_zoom_in.png differ diff --git a/FinalImgs/performance_zoom_in_pieChart.png b/FinalImgs/performance_zoom_in_pieChart.png new file mode 100644 index 0000000..d4f2326 Binary files /dev/null and b/FinalImgs/performance_zoom_in_pieChart.png differ diff --git a/FinalImgs/performance_zoom_out.png b/FinalImgs/performance_zoom_out.png new file mode 100644 index 0000000..b139567 Binary files /dev/null and b/FinalImgs/performance_zoom_out.png differ diff --git a/FinalImgs/performance_zoom_out_pieChart.png b/FinalImgs/performance_zoom_out_pieChart.png new file mode 100644 index 0000000..e8e9769 Binary files /dev/null and b/FinalImgs/performance_zoom_out_pieChart.png differ diff --git a/README.md b/README.md index ae0896a..63f10ce 100644 --- a/README.md +++ b/README.md @@ -1,184 +1,121 @@ -------------------------------------------------------------------------------- + CIS565: Project 4: CUDA Rasterizer ------------------------------------------------------------------------------- -Fall 2014 -------------------------------------------------------------------------------- -Due Monday 10/27/2014 @ 12 PM -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -NOTE: -------------------------------------------------------------------------------- -This project requires an NVIDIA graphics card with CUDA capability! Any card with CUDA compute capability 1.1 or higher will work fine for this project. For a full list of CUDA capable cards and their compute capability, please consult: http://developer.nvidia.com/cuda/cuda-gpus. If you do not have an NVIDIA graphics card in the machine you are working on, feel free to use any machine in the SIG Lab or in Moore100 labs. All machines in the SIG Lab and Moore100 are equipped with CUDA capable NVIDIA graphics cards. If this too proves to be a problem, please contact Patrick or Karl as soon as possible. -------------------------------------------------------------------------------- INTRODUCTION: ------------------------------------------------------------------------------- -In this project, you will implement a simplified CUDA based implementation of a standard rasterized graphics pipeline, similar to the OpenGL pipeline. In this project, you will implement vertex shading, primitive assembly, perspective transformation, rasterization, fragment shading, and write the resulting fragments to a framebuffer. More information about the rasterized graphics pipeline can be found in the class slides and in your notes from CIS560. +This is a simplified CUDA based implementation of a standard rasterized graphics pipeline, similar to the OpenGL pipeline. +The pipeline includes vertex shading, primitive assembly, perspective transformation, rasterization, fragment shading, and write the resulting fragments to a framebuffer. -The basecode provided includes an OBJ loader and much of the mundane I/O and bookkeeping code. The basecode also includes some functions that you may find useful, described below. The core rasterization pipeline is left for you to implement. -You MAY NOT use ANY raycasting/raytracing AT ALL in this project, EXCEPT in the fragment shader step. One of the purposes of this project is to see how a rasterization pipeline can generate graphics WITHOUT the need for raycasting! Raycasting may only be used in the fragment shader effect for interesting shading results, but is absolutely not allowed in any other stages of the pipeline. +BASIC FETAURES: +------------------------------------------------------------------------------- + +* Vertex Shading +* Primitive Assembly with support for triangle VBOs/IBOs +* Perspective Transformation +* Rasterization through either a scanline +* Fragment Shading +* A depth buffer for storing and depth testing fragments +* Fragment to framebuffer writing -Also, you MAY NOT use OpenGL ANYWHERE in this project, aside from the given OpenGL code for drawing Pixel Buffer Objects to the screen. Use of OpenGL for any pipeline stage instead of your own custom implementation will result in an incomplete project. -Finally, note that while this basecode is meant to serve as a strong starting point for a CUDA rasterizer, you are not required to use this basecode if you wish, and you may also change any part of the basecode specification as you please, so long as the final rendered result is correct. +ADVENCED FEATURES: ------------------------------------------------------------------------------- -CONTENTS: + + +MOUSE BASED interactive camera support ------------------------------------------------------------------------------- -The Project4 root directory contains the following subdirectories: - -* src/ contains the source code for the project. Both the Windows Visual Studio solution and the OSX makefile reference this folder for all source; the base source code compiles on OSX and Windows without modification. -* objs/ contains example obj test files: cow.obj, cube.obj, tri.obj. -* renders/ contains an example render of the given example cow.obj file with a z-depth fragment shader. -* windows/ contains a Windows Visual Studio 2010 project and all dependencies needed for building and running on Windows 7. +- mouse left click + drag: rotate the camera around the lookat center +- mouse right click + drag: translate the camera lookat point +- mouse scroll: zoom in/out +The video below shows how the interaction is like. +[![ScreenShot](FinalImgs/CamInteractionThumbnail.png)] (https://www.youtube.com/watch?v=23FbbAm_X8U&feature=youtu.be) + -The Windows and OSX versions of the project build and run exactly the same way as in Project0, Project1, and Project2. +Keyboard Control ------------------------------------------------------------------------------- -REQUIREMENTS: +- p: performance analysis on/off +- 1: points raster on/off +- 2: line raster on/off +- 3: normal based shading +- 4: face orientation shading +- 5: diffuse shading +- 6: blinn shading +- 7: texture map + + + +Back-face culling ------------------------------------------------------------------------------- -In this project, you are given code for: +This is done by checking the normal of current triangle face, if the normal is pointing backwards, then discard shading this face. -* A library for loading/reading standard Alias/Wavefront .obj format mesh files and converting them to OpenGL style VBOs/IBOs -* A suggested order of kernels with which to implement the graphics pipeline -* Working code for CUDA-GL interop -You will need to implement the following stages of the graphics pipeline and features: -* Vertex Shading -* Primitive Assembly with support for triangle VBOs/IBOs -* Perspective Transformation -* Rasterization through either a scanline or a tiled approach -* Fragment Shading -* A depth buffer for storing and depth testing fragments -* Fragment to framebuffer writing -* A simple lighting/shading scheme, such as Lambert or Blinn-Phong, implemented in the fragment shader - -You are also required to implement at least 3 of the following features: - -* Additional pipeline stages. Each one of these stages can count as 1 feature: - * Geometry shader - * Transformation feedback - * Back-face culling - * Scissor test - * Stencil test - * Blending - -IMPORTANT: For each of these stages implemented, you must also add a section to your README stating what the expected performance impact of that pipeline stage is, and real performance comparisons between your rasterizer with that stage and without. - -* Correct color interpolation between points on a primitive -* Texture mapping WITH texture filtering and perspective correct texture coordinates -* Support for additional primitices. Each one of these can count as HALF of a feature. - * Lines - * Line strips - * Triangle fans - * Triangle strips - * Points -* Anti-aliasing -* Order-independent translucency using a k-buffer -* MOUSE BASED interactive camera support. Interactive camera support based only on the keyboard is not acceptable for this feature. +Different Shading mode ------------------------------------------------------------------------------- -BASE CODE TOUR: -------------------------------------------------------------------------------- -You will be working primarily in two files: rasterizeKernel.cu, and rasterizerTools.h. Within these files, areas that you need to complete are marked with a TODO comment. Areas that are useful to and serve as hints for optional features are marked with TODO (Optional). Functions that are useful for reference are marked with the comment LOOK. +* Points +This is done after fragment shader, by selecting visible vertex from "vbo". When including points raster, the time consumption increases by similar amount of time used in vertex shader. +![](FinalImgs/cow_point_raster.png) -* rasterizeKernels.cu contains the core rasterization pipeline. - * A suggested sequence of kernels exists in this file, but you may choose to alter the order of this sequence or merge entire kernels if you see fit. For example, if you decide that doing has benefits, you can choose to merge the vertex shader and primitive assembly kernels, or merge the perspective transform into another kernel. There is not necessarily a right sequence of kernels (although there are wrong sequences, such as placing fragment shading before vertex shading), and you may choose any sequence you want. Please document in your README what sequence you choose and why. - * The provided kernels have had their input parameters removed beyond basic inputs such as the framebuffer. You will have to decide what inputs should go into each stage of the pipeline, and what outputs there should be. +* Lines +This is done after in rasterization, by determining whether current fragment is on the edges of the triangle face. When including lines raster, the time consumption increases by a significant amount. +This is because the line raster lines in the body of naive scanline, which needs to be parallelized. +![](FinalImgs/cube_line_raster.png) -* rasterizeTools.h contains various useful tools, including a number of barycentric coordinate related functions that you may find useful in implementing scanline based rasterization... - * A few pre-made structs are included for you to use, such as fragment and triangle. A simple rasterizer can be implemented with these structs as is. However, as with any part of the basecode, you may choose to modify, add to, use as-is, or outright ignore them as you see fit. - * If you do choose to add to the fragment struct, be sure to include in your README a rationale for why. +* normal based shading +This is done in fragment shader. +![](FinalImgs/cow_shade_by_normal.png) -You will also want to familiarize yourself with: +* face orientation shading (Correct color interpolation between points on a primitive) +This is done in fragment shader. +![](FinalImgs/bunny_vertex_shade.png) -* main.cpp, which contains code that transfers VBOs/CBOs/IBOs to the rasterization pipeline. Interactive camera work will also have to be implemented in this file if you choose that feature. -* utilities.h, which serves as a kitchen-sink of useful functions +* diffuse shading +This is done in fragment shader. +![](FinalImgs/cow_diffuse_shade.png) -------------------------------------------------------------------------------- -SOME RESOURCES: -------------------------------------------------------------------------------- -The following resources may be useful for this project: - -* High-Performance Software Rasterization on GPUs - * Paper (HPG 2011): http://www.tml.tkk.fi/~samuli/publications/laine2011hpg_paper.pdf - * Code: http://code.google.com/p/cudaraster/ Note that looking over this code for reference with regard to the paper is fine, but we most likely will not grant any requests to actually incorporate any of this code into your project. - * Slides: http://bps11.idav.ucdavis.edu/talks/08-gpuSoftwareRasterLaineAndPantaleoni-BPS2011.pdf -* The Direct3D 10 System (SIGGRAPH 2006) - for those interested in doing geometry shaders and transform feedback. - * http://133.11.9.3/~takeo/course/2006/media/papers/Direct3D10_siggraph2006.pdf -* Multi-Fragment Effects on the GPU using the k-Buffer - for those who want to do a k-buffer - * http://www.inf.ufrgs.br/~comba/papers/2007/kbuffer_preprint.pdf -* FreePipe: A Programmable, Parallel Rendering Architecture for Efficient Multi-Fragment Effects (I3D 2010) - * https://sites.google.com/site/hmcen0921/cudarasterizer -* Writing A Software Rasterizer In Javascript: - * Part 1: http://simonstechblog.blogspot.com/2012/04/software-rasterizer-part-1.html - * Part 2: http://simonstechblog.blogspot.com/2012/04/software-rasterizer-part-2.html +* blinn shading +This is done in fragment shader. +![](FinalImgs/cow_blinn_shade.png) -------------------------------------------------------------------------------- -NOTES ON GLM: -------------------------------------------------------------------------------- -This project uses GLM, the GL Math library, for linear algebra. You need to know two important points on how GLM is used in this project: +* texture map (WITH texture filtering and perspective correct texture coordinates) +Reading a texture image is completed with the support of "FreeImage", but he perspectively correct texture map is not finished yet. +This is to be done in rasterization stage, to find correcct color for each pixel by transformed uv coordinates (1/z, u/z, v/z). -* In this project, indices in GLM vectors (such as vec3, vec4), are accessed via swizzling. So, instead of v[0], v.x is used, and instead of v[1], v.y is used, and so on and so forth. -* GLM Matrix operations work fine on NVIDIA Fermi cards and later, but pre-Fermi cards do not play nice with GLM matrices. As such, in this project, GLM matrices are replaced with a custom matrix struct, called a cudaMat4, found in cudaMat4.h. A custom function for multiplying glm::vec4s and cudaMat4s is provided as multiplyMV() in intersections.h. -------------------------------------------------------------------------------- -README -------------------------------------------------------------------------------- -All students must replace or augment the contents of this Readme.md in a clear -manner with the following: -* A brief description of the project and the specific features you implemented. -* At least one screenshot of your project running. -* A 30 second or longer video of your project running. To create the video you - can use http://www.microsoft.com/expression/products/Encoder4_Overview.aspx -* A performance evaluation (described in detail below). -------------------------------------------------------------------------------- PERFORMANCE EVALUATION ------------------------------------------------------------------------------- -The performance evaluation is where you will investigate how to make your CUDA -programs more efficient using the skills you've learned in class. You must have -performed at least one experiment on your code to investigate the positive or -negative effects on performance. +I noticed that when the camera zooms in, the rasterizer fps drops significantly. So I started the comparison between camera zoom-out and camera zoom-in, with other set up exactly same. +The pictures below describes the camera zoom distance, and the corresponding performance analysis. +* Time Consumption Pie Chart for Pipeline (zoom-out, cow model) +![](FinalImgs/performance_zoom_out.png) +![](FinalImgs/performance_zoom_out_pieChart.png) +* Time Consumption Pie Chart for Pipeline (zoom-in, cow model) +![](FinalImgs/performance_zoom_in.png) +![](FinalImgs/performance_zoom_in_pieChart.png) -We encourage you to get creative with your tweaks. Consider places in your code -that could be considered bottlenecks and try to improve them. +It can be noticed that the rasterization takes additional time when camera zooms in, and introduces drop of efficiency. And all the rest stage takes roughly the same amount of time no matter zooms in or zooms out. +This is probably because when the camera is closer, each of the triangle face will become bigger, which occupies more pixels, hence takes longer to complete rasterization. +One possible solution is to parallelize the naive scanline approach, so save the consumption in iteration through many fragments. -Each student should provide no more than a one page summary of their -optimizations along with tables and or graphs to visually explain any -performance differences. -------------------------------------------------------------------------------- -THIRD PARTY CODE POLICY -------------------------------------------------------------------------------- -* Use of any third-party code must be approved by asking on Piazza. If it is approved, all students are welcome to use it. Generally, we approve use of third-party code that is not a core part of the project. For example, for the ray tracer, we would approve using a third-party library for loading models, but would not approve copying and pasting a CUDA function for doing refraction. -* Third-party code must be credited in README.md. -* Using third-party code without its approval, including using another student's code, is an academic integrity violation, and will result in you receiving an F for the semester. + +REFERRENCES ------------------------------------------------------------------------------- -SELF-GRADING -------------------------------------------------------------------------------- -* On the submission date, email your grade, on a scale of 0 to 100, to Liam, harmoli+cis565@seas.upenn.edu, with a one paragraph explanation. Be concise and realistic. Recall that we reserve 30 points as a sanity check to adjust your grade. Your actual grade will be (0.7 * your grade) + (0.3 * our grade). We hope to only use this in extreme cases when your grade does not realistically reflect your work - it is either too high or too low. In most cases, we plan to give you the exact grade you suggest. -* Projects are not weighted evenly, e.g., Project 0 doesn't count as much as the path tracer. We will determine the weighting at the end of the semester based on the size of each project. - ---- -SUBMISSION ---- -As with the previous project, you should fork this project and work inside of -your fork. Upon completion, commit your finished project back to your fork, and -make a pull request to the master repository. You should include a README.md -file in the root directory detailing the following - -* A brief description of the project and specific features you implemented -* At least one screenshot of your project running. -* A link to a video of your raytracer running. -* Instructions for building and running your project if they differ from the - base code. -* A performance writeup as detailed above. -* A list of all third-party code used. -* This Readme file edited as described above in the README section. +loading texture image + - http://www.mingw.org/ + - http://freeimage.sourceforge.net/download.html + - https://www.opengl.org/discussion_boards/showthread.php/163929-image-loading?p=1158293#post1158293 + - http://inst.eecs.berkeley.edu/~cs184/fa09/resources/sec_UsingFreeImage.pdf +perspectively correct texture mapping +- http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ +- http://chrishecker.com/Miscellaneous_Technical_Articles diff --git a/external/FreeImage/FreeImage.dll b/external/FreeImage/FreeImage.dll new file mode 100644 index 0000000..3ce0a70 Binary files /dev/null and b/external/FreeImage/FreeImage.dll differ diff --git a/external/FreeImage/FreeImage.lib b/external/FreeImage/FreeImage.lib new file mode 100644 index 0000000..b29ed71 Binary files /dev/null and b/external/FreeImage/FreeImage.lib differ diff --git a/external/src/objUtil/obj.cpp b/external/src/objUtil/obj.cpp index 22a33aa..f4b3ccb 100644 --- a/external/src/objUtil/obj.cpp +++ b/external/src/objUtil/obj.cpp @@ -94,6 +94,7 @@ void obj::buildVBOs(){ ibo[i] = IBOvec[i]; } setColor(glm::vec3(.4,.4,.4)); + } void obj::compareMaxMin(float x, float y, float z){ @@ -309,6 +310,8 @@ int* obj::getIBO(){ return ibo; } + + int obj::getVBOsize(){ return vbosize; } diff --git a/src/FreeImage.h b/src/FreeImage.h new file mode 100644 index 0000000..2755160 --- /dev/null +++ b/src/FreeImage.h @@ -0,0 +1,1122 @@ +// ========================================================== +// FreeImage 3 +// +// Design and implementation by +// - Floris van den Berg (flvdberg@wxs.nl) +// - Hervé Drolon (drolon@infonie.fr) +// +// Contributors: +// - see changes log named 'Whatsnew.txt', see header of each .h and .cpp file +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== + +#ifndef FREEIMAGE_H +#define FREEIMAGE_H + +// Version information ------------------------------------------------------ + +#define FREEIMAGE_MAJOR_VERSION 3 +#define FREEIMAGE_MINOR_VERSION 16 +#define FREEIMAGE_RELEASE_SERIAL 0 + +// Compiler options --------------------------------------------------------- + +#include // needed for UNICODE functions + +#if defined(FREEIMAGE_LIB) + #define DLL_API + #define DLL_CALLCONV +#else + #if defined(_WIN32) || defined(__WIN32__) + #define DLL_CALLCONV __stdcall + // The following ifdef block is the standard way of creating macros which make exporting + // from a DLL simpler. All files within this DLL are compiled with the FREEIMAGE_EXPORTS + // symbol defined on the command line. this symbol should not be defined on any project + // that uses this DLL. This way any other project whose source files include this file see + // DLL_API functions as being imported from a DLL, wheras this DLL sees symbols + // defined with this macro as being exported. + #ifdef FREEIMAGE_EXPORTS + #define DLL_API __declspec(dllexport) + #else + #define DLL_API __declspec(dllimport) + #endif // FREEIMAGE_EXPORTS + #else + // try the gcc visibility support (see http://gcc.gnu.org/wiki/Visibility) + #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + #ifndef GCC_HASCLASSVISIBILITY + #define GCC_HASCLASSVISIBILITY + #endif + #endif // __GNUC__ + #define DLL_CALLCONV + #if defined(GCC_HASCLASSVISIBILITY) + #define DLL_API __attribute__ ((visibility("default"))) + #else + #define DLL_API + #endif + #endif // WIN32 / !WIN32 +#endif // FREEIMAGE_LIB + +// Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined +// If your big endian system isn't being detected, add an OS specific check +#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \ + defined(__BIG_ENDIAN__) +#define FREEIMAGE_BIGENDIAN +#endif // BYTE_ORDER + +// This really only affects 24 and 32 bit formats, the rest are always RGB order. +#define FREEIMAGE_COLORORDER_BGR 0 +#define FREEIMAGE_COLORORDER_RGB 1 +#if defined(FREEIMAGE_BIGENDIAN) +#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB +#else +#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR +#endif + +// Ensure 4-byte enums if we're using Borland C++ compilers +#if defined(__BORLANDC__) +#pragma option push -b +#endif + +// For C compatibility -------------------------------------------------------- + +#ifdef __cplusplus +#define FI_DEFAULT(x) = x +#define FI_ENUM(x) enum x +#define FI_STRUCT(x) struct x +#else +#define FI_DEFAULT(x) +#define FI_ENUM(x) typedef int x; enum x +#define FI_STRUCT(x) typedef struct x x; struct x +#endif + +// Bitmap types ------------------------------------------------------------- + +FI_STRUCT (FIBITMAP) { void *data; }; +FI_STRUCT (FIMULTIBITMAP) { void *data; }; + +// Types used in the library (directly copied from Windows) ----------------- + +#if defined(__MINGW32__) && defined(_WINDOWS_H) +#define _WINDOWS_ // prevent a bug in MinGW32 +#endif // __MINGW32__ + +#ifndef _WINDOWS_ +#define _WINDOWS_ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _MSC_VER +// define portable types for 32-bit / 64-bit OS +#include +typedef int32_t BOOL; +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef int32_t LONG; +typedef int64_t INT64; +typedef uint64_t UINT64; +#else +// MS is not C99 ISO compliant +typedef long BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef long LONG; +typedef signed __int64 INT64; +typedef unsigned __int64 UINT64; +#endif // _MSC_VER + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +typedef struct tagRGBQUAD { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; +#else + BYTE rgbRed; + BYTE rgbGreen; + BYTE rgbBlue; +#endif // FREEIMAGE_COLORORDER + BYTE rgbReserved; +} RGBQUAD; + +typedef struct tagRGBTRIPLE { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; +#else + BYTE rgbtRed; + BYTE rgbtGreen; + BYTE rgbtBlue; +#endif // FREEIMAGE_COLORORDER +} RGBTRIPLE; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +typedef struct tagBITMAPINFOHEADER{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} BITMAPINFOHEADER, *PBITMAPINFOHEADER; + +typedef struct tagBITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; +} BITMAPINFO, *PBITMAPINFO; + +#endif // _WINDOWS_ + +// Types used in the library (specific to FreeImage) ------------------------ + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +/** 48-bit RGB +*/ +typedef struct tagFIRGB16 { + WORD red; + WORD green; + WORD blue; +} FIRGB16; + +/** 64-bit RGBA +*/ +typedef struct tagFIRGBA16 { + WORD red; + WORD green; + WORD blue; + WORD alpha; +} FIRGBA16; + +/** 96-bit RGB Float +*/ +typedef struct tagFIRGBF { + float red; + float green; + float blue; +} FIRGBF; + +/** 128-bit RGBA Float +*/ +typedef struct tagFIRGBAF { + float red; + float green; + float blue; + float alpha; +} FIRGBAF; + +/** Data structure for COMPLEX type (complex number) +*/ +typedef struct tagFICOMPLEX { + /// real part + double r; + /// imaginary part + double i; +} FICOMPLEX; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +// Indexes for byte arrays, masks and shifts for treating pixels as words --- +// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- + +#ifndef FREEIMAGE_BIGENDIAN +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Little Endian (x86 / MS Windows, Linux) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x00FF0000 +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x000000FF +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 16 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 0 +#define FI_RGBA_ALPHA_SHIFT 24 +#else +// Little Endian (x86 / MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x000000FF +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x00FF0000 +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 0 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 16 +#define FI_RGBA_ALPHA_SHIFT 24 +#endif // FREEIMAGE_COLORORDER +#else +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Big Endian (PPC / none) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x0000FF00 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0xFF000000 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 8 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 24 +#define FI_RGBA_ALPHA_SHIFT 0 +#else +// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0xFF000000 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0x0000FF00 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 24 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 8 +#define FI_RGBA_ALPHA_SHIFT 0 +#endif // FREEIMAGE_COLORORDER +#endif // FREEIMAGE_BIGENDIAN + +#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK|FI_RGBA_GREEN_MASK|FI_RGBA_BLUE_MASK) + +// The 16bit macros only include masks and shifts, since each color element is not byte aligned + +#define FI16_555_RED_MASK 0x7C00 +#define FI16_555_GREEN_MASK 0x03E0 +#define FI16_555_BLUE_MASK 0x001F +#define FI16_555_RED_SHIFT 10 +#define FI16_555_GREEN_SHIFT 5 +#define FI16_555_BLUE_SHIFT 0 +#define FI16_565_RED_MASK 0xF800 +#define FI16_565_GREEN_MASK 0x07E0 +#define FI16_565_BLUE_MASK 0x001F +#define FI16_565_RED_SHIFT 11 +#define FI16_565_GREEN_SHIFT 5 +#define FI16_565_BLUE_SHIFT 0 + +// ICC profile support ------------------------------------------------------ + +#define FIICC_DEFAULT 0x00 +#define FIICC_COLOR_IS_CMYK 0x01 + +FI_STRUCT (FIICCPROFILE) { + WORD flags; // info flag + DWORD size; // profile's size measured in bytes + void *data; // points to a block of contiguous memory containing the profile +}; + +// Important enums ---------------------------------------------------------- + +/** I/O image format identifiers. +*/ +FI_ENUM(FREE_IMAGE_FORMAT) { + FIF_UNKNOWN = -1, + FIF_BMP = 0, + FIF_ICO = 1, + FIF_JPEG = 2, + FIF_JNG = 3, + FIF_KOALA = 4, + FIF_LBM = 5, + FIF_IFF = FIF_LBM, + FIF_MNG = 6, + FIF_PBM = 7, + FIF_PBMRAW = 8, + FIF_PCD = 9, + FIF_PCX = 10, + FIF_PGM = 11, + FIF_PGMRAW = 12, + FIF_PNG = 13, + FIF_PPM = 14, + FIF_PPMRAW = 15, + FIF_RAS = 16, + FIF_TARGA = 17, + FIF_TIFF = 18, + FIF_WBMP = 19, + FIF_PSD = 20, + FIF_CUT = 21, + FIF_XBM = 22, + FIF_XPM = 23, + FIF_DDS = 24, + FIF_GIF = 25, + FIF_HDR = 26, + FIF_FAXG3 = 27, + FIF_SGI = 28, + FIF_EXR = 29, + FIF_J2K = 30, + FIF_JP2 = 31, + FIF_PFM = 32, + FIF_PICT = 33, + FIF_RAW = 34, + FIF_WEBP = 35, + FIF_JXR = 36 +}; + +/** Image type used in FreeImage. +*/ +FI_ENUM(FREE_IMAGE_TYPE) { + FIT_UNKNOWN = 0, // unknown type + FIT_BITMAP = 1, // standard image : 1-, 4-, 8-, 16-, 24-, 32-bit + FIT_UINT16 = 2, // array of unsigned short : unsigned 16-bit + FIT_INT16 = 3, // array of short : signed 16-bit + FIT_UINT32 = 4, // array of unsigned long : unsigned 32-bit + FIT_INT32 = 5, // array of long : signed 32-bit + FIT_FLOAT = 6, // array of float : 32-bit IEEE floating point + FIT_DOUBLE = 7, // array of double : 64-bit IEEE floating point + FIT_COMPLEX = 8, // array of FICOMPLEX : 2 x 64-bit IEEE floating point + FIT_RGB16 = 9, // 48-bit RGB image : 3 x 16-bit + FIT_RGBA16 = 10, // 64-bit RGBA image : 4 x 16-bit + FIT_RGBF = 11, // 96-bit RGB float image : 3 x 32-bit IEEE floating point + FIT_RGBAF = 12 // 128-bit RGBA float image : 4 x 32-bit IEEE floating point +}; + +/** Image color type used in FreeImage. +*/ +FI_ENUM(FREE_IMAGE_COLOR_TYPE) { + FIC_MINISWHITE = 0, // min value is white + FIC_MINISBLACK = 1, // min value is black + FIC_RGB = 2, // RGB color model + FIC_PALETTE = 3, // color map indexed + FIC_RGBALPHA = 4, // RGB color model with alpha channel + FIC_CMYK = 5 // CMYK color model +}; + +/** Color quantization algorithms. +Constants used in FreeImage_ColorQuantize. +*/ +FI_ENUM(FREE_IMAGE_QUANTIZE) { + FIQ_WUQUANT = 0, // Xiaolin Wu color quantization algorithm + FIQ_NNQUANT = 1 // NeuQuant neural-net quantization algorithm by Anthony Dekker +}; + +/** Dithering algorithms. +Constants used in FreeImage_Dither. +*/ +FI_ENUM(FREE_IMAGE_DITHER) { + FID_FS = 0, // Floyd & Steinberg error diffusion + FID_BAYER4x4 = 1, // Bayer ordered dispersed dot dithering (order 2 dithering matrix) + FID_BAYER8x8 = 2, // Bayer ordered dispersed dot dithering (order 3 dithering matrix) + FID_CLUSTER6x6 = 3, // Ordered clustered dot dithering (order 3 - 6x6 matrix) + FID_CLUSTER8x8 = 4, // Ordered clustered dot dithering (order 4 - 8x8 matrix) + FID_CLUSTER16x16= 5, // Ordered clustered dot dithering (order 8 - 16x16 matrix) + FID_BAYER16x16 = 6 // Bayer ordered dispersed dot dithering (order 4 dithering matrix) +}; + +/** Lossless JPEG transformations +Constants used in FreeImage_JPEGTransform +*/ +FI_ENUM(FREE_IMAGE_JPEG_OPERATION) { + FIJPEG_OP_NONE = 0, // no transformation + FIJPEG_OP_FLIP_H = 1, // horizontal flip + FIJPEG_OP_FLIP_V = 2, // vertical flip + FIJPEG_OP_TRANSPOSE = 3, // transpose across UL-to-LR axis + FIJPEG_OP_TRANSVERSE = 4, // transpose across UR-to-LL axis + FIJPEG_OP_ROTATE_90 = 5, // 90-degree clockwise rotation + FIJPEG_OP_ROTATE_180 = 6, // 180-degree rotation + FIJPEG_OP_ROTATE_270 = 7 // 270-degree clockwise (or 90 ccw) +}; + +/** Tone mapping operators. +Constants used in FreeImage_ToneMapping. +*/ +FI_ENUM(FREE_IMAGE_TMO) { + FITMO_DRAGO03 = 0, // Adaptive logarithmic mapping (F. Drago, 2003) + FITMO_REINHARD05 = 1, // Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005) + FITMO_FATTAL02 = 2 // Gradient domain high dynamic range compression (R. Fattal, 2002) +}; + +/** Upsampling / downsampling filters. +Constants used in FreeImage_Rescale. +*/ +FI_ENUM(FREE_IMAGE_FILTER) { + FILTER_BOX = 0, // Box, pulse, Fourier window, 1st order (constant) b-spline + FILTER_BICUBIC = 1, // Mitchell & Netravali's two-param cubic filter + FILTER_BILINEAR = 2, // Bilinear filter + FILTER_BSPLINE = 3, // 4th order (cubic) b-spline + FILTER_CATMULLROM = 4, // Catmull-Rom spline, Overhauser spline + FILTER_LANCZOS3 = 5 // Lanczos3 filter +}; + +/** Color channels. +Constants used in color manipulation routines. +*/ +FI_ENUM(FREE_IMAGE_COLOR_CHANNEL) { + FICC_RGB = 0, // Use red, green and blue channels + FICC_RED = 1, // Use red channel + FICC_GREEN = 2, // Use green channel + FICC_BLUE = 3, // Use blue channel + FICC_ALPHA = 4, // Use alpha channel + FICC_BLACK = 5, // Use black channel + FICC_REAL = 6, // Complex images: use real part + FICC_IMAG = 7, // Complex images: use imaginary part + FICC_MAG = 8, // Complex images: use magnitude + FICC_PHASE = 9 // Complex images: use phase +}; + +// Metadata support --------------------------------------------------------- + +/** + Tag data type information (based on TIFF specifications) + + Note: RATIONALs are the ratio of two 32-bit integer values. +*/ +FI_ENUM(FREE_IMAGE_MDTYPE) { + FIDT_NOTYPE = 0, // placeholder + FIDT_BYTE = 1, // 8-bit unsigned integer + FIDT_ASCII = 2, // 8-bit bytes w/ last byte null + FIDT_SHORT = 3, // 16-bit unsigned integer + FIDT_LONG = 4, // 32-bit unsigned integer + FIDT_RATIONAL = 5, // 64-bit unsigned fraction + FIDT_SBYTE = 6, // 8-bit signed integer + FIDT_UNDEFINED = 7, // 8-bit untyped data + FIDT_SSHORT = 8, // 16-bit signed integer + FIDT_SLONG = 9, // 32-bit signed integer + FIDT_SRATIONAL = 10, // 64-bit signed fraction + FIDT_FLOAT = 11, // 32-bit IEEE floating point + FIDT_DOUBLE = 12, // 64-bit IEEE floating point + FIDT_IFD = 13, // 32-bit unsigned integer (offset) + FIDT_PALETTE = 14, // 32-bit RGBQUAD + FIDT_LONG8 = 16, // 64-bit unsigned integer + FIDT_SLONG8 = 17, // 64-bit signed integer + FIDT_IFD8 = 18 // 64-bit unsigned integer (offset) +}; + +/** + Metadata models supported by FreeImage +*/ +FI_ENUM(FREE_IMAGE_MDMODEL) { + FIMD_NODATA = -1, + FIMD_COMMENTS = 0, // single comment or keywords + FIMD_EXIF_MAIN = 1, // Exif-TIFF metadata + FIMD_EXIF_EXIF = 2, // Exif-specific metadata + FIMD_EXIF_GPS = 3, // Exif GPS metadata + FIMD_EXIF_MAKERNOTE = 4, // Exif maker note metadata + FIMD_EXIF_INTEROP = 5, // Exif interoperability metadata + FIMD_IPTC = 6, // IPTC/NAA metadata + FIMD_XMP = 7, // Abobe XMP metadata + FIMD_GEOTIFF = 8, // GeoTIFF metadata + FIMD_ANIMATION = 9, // Animation metadata + FIMD_CUSTOM = 10, // Used to attach other metadata types to a dib + FIMD_EXIF_RAW = 11 // Exif metadata as a raw buffer +}; + +/** + Handle to a metadata model +*/ +FI_STRUCT (FIMETADATA) { void *data; }; + +/** + Handle to a FreeImage tag +*/ +FI_STRUCT (FITAG) { void *data; }; + +// File IO routines --------------------------------------------------------- + +#ifndef FREEIMAGE_IO +#define FREEIMAGE_IO + +typedef void* fi_handle; +typedef unsigned (DLL_CALLCONV *FI_ReadProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); +typedef unsigned (DLL_CALLCONV *FI_WriteProc) (void *buffer, unsigned size, unsigned count, fi_handle handle); +typedef int (DLL_CALLCONV *FI_SeekProc) (fi_handle handle, long offset, int origin); +typedef long (DLL_CALLCONV *FI_TellProc) (fi_handle handle); + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // WIN32 + +FI_STRUCT(FreeImageIO) { + FI_ReadProc read_proc; // pointer to the function used to read data + FI_WriteProc write_proc; // pointer to the function used to write data + FI_SeekProc seek_proc; // pointer to the function used to seek + FI_TellProc tell_proc; // pointer to the function used to aquire the current position +}; + +#if (defined(_WIN32) || defined(__WIN32__)) +#pragma pack(pop) +#else +#pragma pack() +#endif // WIN32 + +/** +Handle to a memory I/O stream +*/ +FI_STRUCT (FIMEMORY) { void *data; }; + +#endif // FREEIMAGE_IO + +// Plugin routines ---------------------------------------------------------- + +#ifndef PLUGINS +#define PLUGINS + +typedef const char *(DLL_CALLCONV *FI_FormatProc)(void); +typedef const char *(DLL_CALLCONV *FI_DescriptionProc)(void); +typedef const char *(DLL_CALLCONV *FI_ExtensionListProc)(void); +typedef const char *(DLL_CALLCONV *FI_RegExprProc)(void); +typedef void *(DLL_CALLCONV *FI_OpenProc)(FreeImageIO *io, fi_handle handle, BOOL read); +typedef void (DLL_CALLCONV *FI_CloseProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef int (DLL_CALLCONV *FI_PageCountProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef int (DLL_CALLCONV *FI_PageCapabilityProc)(FreeImageIO *io, fi_handle handle, void *data); +typedef FIBITMAP *(DLL_CALLCONV *FI_LoadProc)(FreeImageIO *io, fi_handle handle, int page, int flags, void *data); +typedef BOOL (DLL_CALLCONV *FI_SaveProc)(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data); +typedef BOOL (DLL_CALLCONV *FI_ValidateProc)(FreeImageIO *io, fi_handle handle); +typedef const char *(DLL_CALLCONV *FI_MimeProc)(void); +typedef BOOL (DLL_CALLCONV *FI_SupportsExportBPPProc)(int bpp); +typedef BOOL (DLL_CALLCONV *FI_SupportsExportTypeProc)(FREE_IMAGE_TYPE type); +typedef BOOL (DLL_CALLCONV *FI_SupportsICCProfilesProc)(void); +typedef BOOL (DLL_CALLCONV *FI_SupportsNoPixelsProc)(void); + +FI_STRUCT (Plugin) { + FI_FormatProc format_proc; + FI_DescriptionProc description_proc; + FI_ExtensionListProc extension_proc; + FI_RegExprProc regexpr_proc; + FI_OpenProc open_proc; + FI_CloseProc close_proc; + FI_PageCountProc pagecount_proc; + FI_PageCapabilityProc pagecapability_proc; + FI_LoadProc load_proc; + FI_SaveProc save_proc; + FI_ValidateProc validate_proc; + FI_MimeProc mime_proc; + FI_SupportsExportBPPProc supports_export_bpp_proc; + FI_SupportsExportTypeProc supports_export_type_proc; + FI_SupportsICCProfilesProc supports_icc_profiles_proc; + FI_SupportsNoPixelsProc supports_no_pixels_proc; +}; + +typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id); + +#endif // PLUGINS + + +// Load / Save flag constants ----------------------------------------------- + +#define FIF_LOAD_NOPIXELS 0x8000 //! loading: load the image header only (not supported by all plugins, default to full loading) + +#define BMP_DEFAULT 0 +#define BMP_SAVE_RLE 1 +#define CUT_DEFAULT 0 +#define DDS_DEFAULT 0 +#define EXR_DEFAULT 0 //! save data as half with piz-based wavelet compression +#define EXR_FLOAT 0x0001 //! save data as float instead of as half (not recommended) +#define EXR_NONE 0x0002 //! save with no compression +#define EXR_ZIP 0x0004 //! save with zlib compression, in blocks of 16 scan lines +#define EXR_PIZ 0x0008 //! save with piz-based wavelet compression +#define EXR_PXR24 0x0010 //! save with lossy 24-bit float compression +#define EXR_B44 0x0020 //! save with lossy 44% float compression - goes to 22% when combined with EXR_LC +#define EXR_LC 0x0040 //! save images with one luminance and two chroma channels, rather than as RGB (lossy compression) +#define FAXG3_DEFAULT 0 +#define GIF_DEFAULT 0 +#define GIF_LOAD256 1 //! load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color +#define GIF_PLAYBACK 2 //! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading +#define HDR_DEFAULT 0 +#define ICO_DEFAULT 0 +#define ICO_MAKEALPHA 1 //! convert to 32bpp and create an alpha channel from the AND-mask when loading +#define IFF_DEFAULT 0 +#define J2K_DEFAULT 0 //! save with a 16:1 rate +#define JP2_DEFAULT 0 //! save with a 16:1 rate +#define JPEG_DEFAULT 0 //! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420) +#define JPEG_FAST 0x0001 //! load the file as fast as possible, sacrificing some quality +#define JPEG_ACCURATE 0x0002 //! load the file with the best quality, sacrificing some speed +#define JPEG_CMYK 0x0004 //! load separated CMYK "as is" (use | to combine with other load flags) +#define JPEG_EXIFROTATE 0x0008 //! load and rotate according to Exif 'Orientation' tag if available +#define JPEG_GREYSCALE 0x0010 //! load and convert to a 8-bit greyscale image +#define JPEG_QUALITYSUPERB 0x80 //! save with superb quality (100:1) +#define JPEG_QUALITYGOOD 0x0100 //! save with good quality (75:1) +#define JPEG_QUALITYNORMAL 0x0200 //! save with normal quality (50:1) +#define JPEG_QUALITYAVERAGE 0x0400 //! save with average quality (25:1) +#define JPEG_QUALITYBAD 0x0800 //! save with bad quality (10:1) +#define JPEG_PROGRESSIVE 0x2000 //! save as a progressive-JPEG (use | to combine with other save flags) +#define JPEG_SUBSAMPLING_411 0x1000 //! save with high 4x1 chroma subsampling (4:1:1) +#define JPEG_SUBSAMPLING_420 0x4000 //! save with medium 2x2 medium chroma subsampling (4:2:0) - default value +#define JPEG_SUBSAMPLING_422 0x8000 //! save with low 2x1 chroma subsampling (4:2:2) +#define JPEG_SUBSAMPLING_444 0x10000 //! save with no chroma subsampling (4:4:4) +#define JPEG_OPTIMIZE 0x20000 //! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size) +#define JPEG_BASELINE 0x40000 //! save basic JPEG, without metadata or any markers +#define KOALA_DEFAULT 0 +#define LBM_DEFAULT 0 +#define MNG_DEFAULT 0 +#define PCD_DEFAULT 0 +#define PCD_BASE 1 //! load the bitmap sized 768 x 512 +#define PCD_BASEDIV4 2 //! load the bitmap sized 384 x 256 +#define PCD_BASEDIV16 3 //! load the bitmap sized 192 x 128 +#define PCX_DEFAULT 0 +#define PFM_DEFAULT 0 +#define PICT_DEFAULT 0 +#define PNG_DEFAULT 0 +#define PNG_IGNOREGAMMA 1 //! loading: avoid gamma correction +#define PNG_Z_BEST_SPEED 0x0001 //! save using ZLib level 1 compression flag (default value is 6) +#define PNG_Z_DEFAULT_COMPRESSION 0x0006 //! save using ZLib level 6 compression flag (default recommended value) +#define PNG_Z_BEST_COMPRESSION 0x0009 //! save using ZLib level 9 compression flag (default value is 6) +#define PNG_Z_NO_COMPRESSION 0x0100 //! save without ZLib compression +#define PNG_INTERLACED 0x0200 //! save using Adam7 interlacing (use | to combine with other save flags) +#define PNM_DEFAULT 0 +#define PNM_SAVE_RAW 0 //! if set the writer saves in RAW format (i.e. P4, P5 or P6) +#define PNM_SAVE_ASCII 1 //! if set the writer saves in ASCII format (i.e. P1, P2 or P3) +#define PSD_DEFAULT 0 +#define PSD_CMYK 1 //! reads tags for separated CMYK (default is conversion to RGB) +#define PSD_LAB 2 //! reads tags for CIELab (default is conversion to RGB) +#define RAS_DEFAULT 0 +#define RAW_DEFAULT 0 //! load the file as linear RGB 48-bit +#define RAW_PREVIEW 1 //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit +#define RAW_DISPLAY 2 //! load the file as RGB 24-bit +#define RAW_HALFSIZE 4 //! output a half-size color image +#define SGI_DEFAULT 0 +#define TARGA_DEFAULT 0 +#define TARGA_LOAD_RGB888 1 //! if set the loader converts RGB555 and ARGB8888 -> RGB888. +#define TARGA_SAVE_RLE 2 //! if set, the writer saves with RLE compression +#define TIFF_DEFAULT 0 +#define TIFF_CMYK 0x0001 //! reads/stores tags for separated CMYK (use | to combine with compression flags) +#define TIFF_PACKBITS 0x0100 //! save using PACKBITS compression +#define TIFF_DEFLATE 0x0200 //! save using DEFLATE compression (a.k.a. ZLIB compression) +#define TIFF_ADOBE_DEFLATE 0x0400 //! save using ADOBE DEFLATE compression +#define TIFF_NONE 0x0800 //! save without any compression +#define TIFF_CCITTFAX3 0x1000 //! save using CCITT Group 3 fax encoding +#define TIFF_CCITTFAX4 0x2000 //! save using CCITT Group 4 fax encoding +#define TIFF_LZW 0x4000 //! save using LZW compression +#define TIFF_JPEG 0x8000 //! save using JPEG compression +#define TIFF_LOGLUV 0x10000 //! save using LogLuv compression +#define WBMP_DEFAULT 0 +#define XBM_DEFAULT 0 +#define XPM_DEFAULT 0 +#define WEBP_DEFAULT 0 //! save with good quality (75:1) +#define WEBP_LOSSLESS 0x100 //! save in lossless mode +#define JXR_DEFAULT 0 //! save with quality 80 and no chroma subsampling (4:4:4) +#define JXR_LOSSLESS 0x0064 //! save lossless +#define JXR_PROGRESSIVE 0x2000 //! save as a progressive-JXR (use | to combine with other save flags) + +// Background filling options --------------------------------------------------------- +// Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas + +#define FI_COLOR_IS_RGB_COLOR 0x00 // RGBQUAD color is a RGB color (contains no valid alpha channel) +#define FI_COLOR_IS_RGBA_COLOR 0x01 // RGBQUAD color is a RGBA color (contains a valid alpha channel) +#define FI_COLOR_FIND_EQUAL_COLOR 0x02 // For palettized images: lookup equal RGB color from palette +#define FI_COLOR_ALPHA_IS_INDEX 0x04 // The color's rgbReserved member (alpha) contains the palette index to be used +#define FI_COLOR_PALETTE_SEARCH_MASK (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX) // No color lookup is performed + + +#ifdef __cplusplus +extern "C" { +#endif + +// Init / Error routines ---------------------------------------------------- + +DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE)); +DLL_API void DLL_CALLCONV FreeImage_DeInitialise(void); + +// Version routines --------------------------------------------------------- + +DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void); +DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void); + +// Message output functions ------------------------------------------------- + +typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg); +typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg); + +DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf); +DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf); +DLL_API void DLL_CALLCONV FreeImage_OutputMessageProc(int fif, const char *fmt, ...); + +// Allocate / Clone / Unload routines --------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib); + +// Header loading routines +DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib); + +// Load / Save routines ----------------------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); + +// Memory I/O stream routines ----------------------------------------------- + +DLL_API FIMEMORY *DLL_CALLCONV FreeImage_OpenMemory(BYTE *data FI_DEFAULT(0), DWORD size_in_bytes FI_DEFAULT(0)); +DLL_API void DLL_CALLCONV FreeImage_CloseMemory(FIMEMORY *stream); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API long DLL_CALLCONV FreeImage_TellMemory(FIMEMORY *stream); +DLL_API BOOL DLL_CALLCONV FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin); +DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes); +DLL_API unsigned DLL_CALLCONV FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream); +DLL_API unsigned DLL_CALLCONV FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream); + +DLL_API FIMULTIBITMAP *DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags); + +// Plugin Interface --------------------------------------------------------- + +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_RegisterExternalPlugin(const char *path, const char *format FI_DEFAULT(0), const char *description FI_DEFAULT(0), const char *extension FI_DEFAULT(0), const char *regexpr FI_DEFAULT(0)); +DLL_API int DLL_CALLCONV FreeImage_GetFIFCount(void); +DLL_API int DLL_CALLCONV FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable); +DLL_API int DLL_CALLCONV FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFormat(const char *format); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromMime(const char *mime); +DLL_API const char *DLL_CALLCONV FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif); +DLL_API const char *DLL_CALLCONV FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilename(const char *filename); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFIFFromFilenameU(const wchar_t *filename); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif); +DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif); + +// Multipaging interface ---------------------------------------------------- + +DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0)); +DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags FI_DEFAULT(0)); +DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0)); +DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap); +DLL_API void DLL_CALLCONV FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data); +DLL_API void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data); +DLL_API void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page); +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page); +DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *data, BOOL changed); +DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source); +DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count); + +// Filetype request routines ------------------------------------------------ + +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0)); +DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0)); + +// Image type request routine ----------------------------------------------- + +DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib); + +// FreeImage helper routines ------------------------------------------------ + +DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void); +DLL_API BOOL DLL_CALLCONV FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); +DLL_API BOOL DLL_CALLCONV FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue); + +// Pixel access routines ---------------------------------------------------- + +DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib); +DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline); + +DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); +DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); +DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value); +DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value); + +// DIB info routines -------------------------------------------------------- + +DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib); +DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res); +DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res); + +DLL_API BITMAPINFOHEADER *DLL_CALLCONV FreeImage_GetInfoHeader(FIBITMAP *dib); +DLL_API BITMAPINFO *DLL_CALLCONV FreeImage_GetInfo(FIBITMAP *dib); +DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib); +DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib); + +DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib); +DLL_API BYTE * DLL_CALLCONV FreeImage_GetTransparencyTable(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled); +DLL_API void DLL_CALLCONV FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count); +DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib); +DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index); +DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib); + +DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); +DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetThumbnail(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail); + +// ICC profile routines ----------------------------------------------------- + +DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib); +DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size); +DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib); + +// Line conversion routines ------------------------------------------------- + +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels); +DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels); + +// Smart conversion routines ------------------------------------------------ + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize FI_DEFAULT(FIQ_WUQUANT), int PaletteSize FI_DEFAULT(256), int ReserveSize FI_DEFAULT(0), RGBQUAD *ReservePalette FI_DEFAULT(NULL)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); +DLL_API void DLL_CALLCONV FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown FI_DEFAULT(FALSE)); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGBF(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE)); + +// Tone mapping operators --------------------------------------------------- + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0), double adaptation FI_DEFAULT(1), double color_correction FI_DEFAULT(0)); + +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoFattal02(FIBITMAP *src, double color_saturation FI_DEFAULT(0.5), double attenuation FI_DEFAULT(0.85)); + +// ZLib interface ----------------------------------------------------------- + +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size); +DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size); + +// -------------------------------------------------------------------------- +// Metadata routines +// -------------------------------------------------------------------------- + +// tag creation / destruction +DLL_API FITAG *DLL_CALLCONV FreeImage_CreateTag(void); +DLL_API void DLL_CALLCONV FreeImage_DeleteTag(FITAG *tag); +DLL_API FITAG *DLL_CALLCONV FreeImage_CloneTag(FITAG *tag); + +// tag getters and setters +DLL_API const char *DLL_CALLCONV FreeImage_GetTagKey(FITAG *tag); +DLL_API const char *DLL_CALLCONV FreeImage_GetTagDescription(FITAG *tag); +DLL_API WORD DLL_CALLCONV FreeImage_GetTagID(FITAG *tag); +DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag); +DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag); +DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag); +DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag); + +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length); +DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value); + +// iterator +DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag); +DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag); +DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle); + +// metadata setter and getter +DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag); +DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag); + +// helpers +DLL_API unsigned DLL_CALLCONV FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src); + +// tag to C string conversion +DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL)); + +// -------------------------------------------------------------------------- +// JPEG lossless transformation routines +// -------------------------------------------------------------------------- + +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); +DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE)); + + +// -------------------------------------------------------------------------- +// Image manipulation toolkit +// -------------------------------------------------------------------------- + +// rotation and flipping +/// @deprecated see FreeImage_Rotate +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateClassic(FIBITMAP *dib, double angle); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask); +DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib); + +// upsampling / downsampling +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE)); + +// color manipulation routines (point operations) +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustCurve(FIBITMAP *dib, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustGamma(FIBITMAP *dib, double gamma); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustBrightness(FIBITMAP *dib, double percentage); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustContrast(FIBITMAP *dib, double percentage); +DLL_API BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *dib); +DLL_API BOOL DLL_CALLCONV FreeImage_GetHistogram(FIBITMAP *dib, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel FI_DEFAULT(FICC_BLACK)); +DLL_API int DLL_CALLCONV FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert); +DLL_API BOOL DLL_CALLCONV FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert FI_DEFAULT(FALSE)); +DLL_API unsigned DLL_CALLCONV FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap); +DLL_API unsigned DLL_CALLCONV FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha); +DLL_API unsigned DLL_CALLCONV FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices, BYTE *dstindices, unsigned count, BOOL swap); +DLL_API unsigned DLL_CALLCONV FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b); + +// channel processing routines +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetChannel(FIBITMAP *dib, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); +DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel); + +// copy / paste / composite routines +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom); +DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL)); +DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib); + +// background filling routines +DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateEx(int width, int height, int bpp, const RGBQUAD *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options FI_DEFAULT(0), const RGBQUAD *palette FI_DEFAULT(NULL), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); + +// miscellaneous algorithms +DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle FI_DEFAULT(3)); + +// restore the borland-specific enum size option +#if defined(__BORLANDC__) +#pragma option pop +#endif + +#ifdef __cplusplus +} +#endif + +#endif // FREEIMAGE_H diff --git a/src/main.cpp b/src/main.cpp index 13d8e67..8a7206c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ // Written by Yining Karl Li, Copyright (c) 2012 University of Pennsylvania #include "main.h" +#pragma comment(lib,"FreeImage.lib") //------------------------------- //-------------MAIN-------------- @@ -28,6 +29,7 @@ int main(int argc, char** argv){ cout << "Usage: mesh=[obj file]" << endl; return 0; } + //iniCamera(); frame = 0; seconds = time (NULL); @@ -42,13 +44,22 @@ int main(int argc, char** argv){ return 0; } + +double xpos, ypos, xposLast, yposLast; //mouse position + +//fovy, aspect, eye, up, lookat +cam mouseCam(65.0f, (float)width/(float)height, glm::vec3(0.0f, 0.0f, 10.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f)); //cam class + + void mainLoop() { + while(!glfwWindowShouldClose(window)){ + glfwPollEvents(); runCuda(); + //fps calculation time_t seconds2 = time (NULL); - if(seconds2-seconds >= 1){ fps = fpstracker/(seconds2-seconds); @@ -67,11 +78,62 @@ void mainLoop() { // VAO, shader program, and texture already bound glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); glfwSwapBuffers(window); + + // check for mouse press + int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + if (state == GLFW_PRESS){ + glfwGetCursorPos(window, &xpos, &ypos); + rotateMouseCam(xpos, ypos, xposLast, yposLast); + } + int state2 = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT); + if (state2 == GLFW_PRESS){ + glfwGetCursorPos(window, &xpos, &ypos); + translateMouseCam(xpos, ypos, xposLast, yposLast); + } + glfwGetCursorPos(window,&xposLast,&yposLast); + } glfwDestroyWindow(window); glfwTerminate(); } +void rotateMouseCam(double x, double y, double xlast, double ylast){ + + float PI = 3.1415926f; + float Sensitivity = 0.1f; + float rotX = ((float)x - (float)xlast ) * Sensitivity; + float rotY = ((float)y - (float)ylast ) * Sensitivity; + mouseCam.theta -= rotY; //theta is the vertical rotation + glm::clamp(mouseCam.theta, 0.0001f, 179.9999f); + mouseCam.phi += rotX; //phi is the horizontal circle rotation + if(mouseCam.phi > 360.0f) + mouseCam.phi -= 360.0f; + mouseCam.calculateCamPos(); +} + +void translateMouseCam(double x, double y, double xlast, double ylast){ + + float Sensitivity = 0.001f; + float transX = ((float)x - (float)xlast ) * Sensitivity; + float transY = ((float)y - (float)ylast ) * Sensitivity; + glm::vec3 viewDir = glm::normalize(mouseCam.center - mouseCam.eye); + glm::vec3 rightDir = glm::cross(viewDir, mouseCam.up); + if(mouseCam.phi < 180.0f){ + //mouseCam.center.y += transY; + //mouseCam.center.x += transX; + mouseCam.center += transY * mouseCam.up; + mouseCam.center += transX * rightDir; + } + else{ + //mouseCam.center.y -= transY; + //mouseCam.center.x -= transX; + mouseCam.center -= transY * mouseCam.up; + mouseCam.center -= transX * rightDir; + } + + mouseCam.calculateCamPos(); +} + //------------------------------- //---------RUNTIME STUFF--------- //------------------------------- @@ -89,12 +151,19 @@ void runCuda(){ 1.0, 0.0, 0.0}; cbo = newcbo; cbosize = 9; + + /*cbo = mesh->getCBO(); + cbosize = mesh->getCBOsize();*/ ibo = mesh->getIBO(); ibosize = mesh->getIBOsize(); + nbo = mesh->getNBO(); + nbosize = mesh->getNBOsize(); + + cudaGLMapBufferObject((void**)&dptr, pbo); - cudaRasterizeCore(dptr, glm::vec2(width, height), frame, vbo, vbosize, cbo, cbosize, ibo, ibosize); + cudaRasterizeCore(dptr, glm::vec2(width, height), frame, vbo, vbosize, cbo, cbosize, ibo, ibosize, nbo, nbosize); cudaGLUnmapBufferObject(pbo); vbo = NULL; @@ -125,7 +194,13 @@ bool init(int argc, char* argv[]) { return false; } glfwMakeContextCurrent(window); - glfwSetKeyCallback(window, keyCallback); + + glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); //sticking mouse button + + glfwSetKeyCallback(window, keyCallback); //keyboard callback + // glfwSetMouseButtonCallback(window, mousebuttonCallback); //mouse button callback + glfwSetScrollCallback(window,mousescrollCallback); //mouse scroll callback + //glfwSetCursorPosCallback(window,mousemoveCallback); //mouse move callback // Set up GL context glewExperimental = GL_TRUE; @@ -138,6 +213,10 @@ bool init(int argc, char* argv[]) { initTextures(); initCuda(); initPBO(); + + //initialize texture +initTextureMap("C:/Users/AppleDu/Documents/GitHub/Project4-Rasterizer/textures/magicCube.png"); + GLuint passthroughProgram; passthroughProgram = initShader(); @@ -234,6 +313,7 @@ GLuint initShader() { return program; } + //------------------------------- //---------CLEANUP STUFF--------- //------------------------------- @@ -272,6 +352,10 @@ void shut_down(int return_code){ //------------------------------ //-------GLFW CALLBACKS--------- //------------------------------ +int PERFORMANCE_MEASURE = 0; +int SHADING_MODE = 2; //0-shading based on normal, 1-shade based on depth, 2-diffuse, 3-blinn, 4-texture map, 5-original cbo, +int POINT_RASTER = 0; //0/1 to off/on points display +int LINE_RASTER = 0; //0/1 to off/on lines display void errorCallback(int error, const char* description){ fputs(description, stderr); @@ -281,4 +365,114 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS){ glfwSetWindowShouldClose(window, GL_TRUE); } + else if(key == GLFW_KEY_P && action == GLFW_PRESS){ //performance analysis + PERFORMANCE_MEASURE = 1 - PERFORMANCE_MEASURE; + } + else if(key == GLFW_KEY_1 && action == GLFW_PRESS){ //point render + POINT_RASTER = 1 - POINT_RASTER; + } + else if(key == GLFW_KEY_2 && action == GLFW_PRESS){ //line render + LINE_RASTER = 1 - LINE_RASTER; + } + else if(key == GLFW_KEY_3 && action == GLFW_PRESS){ //normal based shading + SHADING_MODE = 0; + } + else if(key == GLFW_KEY_4 && action == GLFW_PRESS){ //vertex interpolation shading + SHADING_MODE = 5; + } + else if(key == GLFW_KEY_5 && action == GLFW_PRESS){ //diffuse + SHADING_MODE = 2; + } + else if(key == GLFW_KEY_6 && action == GLFW_PRESS){ //blinn + SHADING_MODE = 3; + } + else if(key == GLFW_KEY_7 && action == GLFW_PRESS){ //texture map //TODO + SHADING_MODE = 4; + } +} + + +void mousescrollCallback(GLFWwindow * window, double xoffset, double yoffset ){ + // x is always 0, only y is changing, +ve for upwards, -ve for downwards + //printf("mouse scroll %.2f %.2f\n", xoffset, yoffset); + float Sensitivity = 0.8f; + + //correct zoom...TODO + //mouseCam.eye.z -= yoffset * Sensitivity; + //mouseCam.calculateMVP(); + + //cheap zoom + if(mouseCam.fovy - Sensitivity * yoffset > 5.0f && mouseCam.fovy - Sensitivity * yoffset < 180.0f){ + mouseCam.fovy -= Sensitivity * yoffset; + mouseCam.calculateMVP(); + } +} + +void mousemoveCallback(GLFWwindow *window, double xpos, double ypos){ + xposLast = xpos; + yposLast = ypos; +} + + +//------------------------------ +//-------TEXTURE STUFF--------- +//------------------------------ +//http://www.mingw.org/ +//http://freeimage.sourceforge.net/download.html +//https://www.opengl.org/discussion_boards/showthread.php/163929-image-loading?p=1158293#post1158293 +//http://inst.eecs.berkeley.edu/~cs184/fa09/resources/sec_UsingFreeImage.pdf + +//loading and initializing texture map +tex textureMap; //defined in "rasterizeKernel.h" +std::vector textureColor; + +void initTextureMap(char* textureFileName){ + int h = 0, w = 0; + int tmp = loadTexture(textureFileName,textureColor,h,w); + if( tmp != -1){ + textureMap.id = tmp; //start index, point to textureColor + textureMap.h = h; //height + textureMap.w = w; //width + } +} + +int loadTexture(char* file, std::vector &c, int &h,int &w){ + FIBITMAP* image = FreeImage_Load( FreeImage_GetFileType(file, 0), file); + if(!image){ + printf("Error: fail to open texture file %s\n", file ); + FreeImage_Unload(image); + return -1; + } + image = FreeImage_ConvertTo32Bits(image); + + w = FreeImage_GetWidth(image); + h = FreeImage_GetHeight(image); + if( w == 0 && h == 0 ) { + printf("Error: texture file is empty\n"); + FreeImage_Unload(image); + return -1; + } + + int start = c.size(); + //int total = w * h; + //if(n.size()>0) //useful when load multiple picture of texture + //total += n[n.size()-1]; + //n.push_back(total); + + //int k = 0; + for(int i = 0; i < w; i++){ + for(int j = 0;j < h; j++){ + RGBQUAD color; + FreeImage_GetPixelColor( image, i, j, &color ); + glm::vec3 nc(color.rgbRed, color.rgbGreen, color.rgbBlue); + c.push_back(nc); + + //printf("color @ %d is %.2f, %.2f, %.2f\n",k, c[k].r, c[k].g, c[k].b); + // k++; + } + } + + FreeImage_Unload(image); + printf("Loaded texture %s with %dx%d pixels\n", file,w,h ); + return start; } \ No newline at end of file diff --git a/src/main.h b/src/main.h index 8999110..e2daec7 100644 --- a/src/main.h +++ b/src/main.h @@ -22,6 +22,7 @@ #include "rasterizeKernels.h" #include "utilities.h" +#include "FreeImage.h" //for loading texture from ".jpg", ".png", ".bmp" using namespace std; @@ -49,6 +50,10 @@ float* cbo; int cbosize; int* ibo; int ibosize; +float* nbo; +int nbosize; +float* uvbo; +int uvbosize; //------------------------------- //----------CUDA STUFF----------- @@ -75,6 +80,8 @@ void runCuda(); void keyboard(unsigned char key, int x, int y); #endif + + //------------------------------- //----------SETUP STUFF---------- //------------------------------- @@ -83,6 +90,8 @@ void initPBO(); void initCuda(); void initTextures(); void initVAO(); +void initTextureMap(char* textureFileName); +int loadTexture(char* file, std::vector &c, int &h,int &w ); GLuint initShader(); //------------------------------- @@ -97,7 +106,12 @@ void deleteTexture(GLuint* tex); //-------GLFW CALLBACKS--------- //------------------------------ void mainLoop(); +void rotateMouseCam(double x, double y, double xlast, double ylast); +void translateMouseCam(double x, double y, double xlast, double ylast); void errorCallback(int error, const char *description); void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); +void mousebuttonCallback(GLFWwindow* window, int button, int action, int mods); +void mousescrollCallback(GLFWwindow * window, double xoffset, double yoffset ); +void mousemoveCallback(GLFWwindow *window, double xpos, double ypos); #endif \ No newline at end of file diff --git a/src/rasterizeKernels.cu b/src/rasterizeKernels.cu index 10b0000..87710a6 100644 --- a/src/rasterizeKernels.cu +++ b/src/rasterizeKernels.cu @@ -13,7 +13,12 @@ fragment* depthbuffer; float* device_vbo; float* device_cbo; int* device_ibo; +float* device_nbo; triangle* primitives; +glm::vec3* device_tbo; +cudaEvent_t start, stop; +float timeDuration; + void checkCUDAError(const char *msg) { cudaError_t err = cudaGetLastError(); @@ -71,6 +76,113 @@ __host__ __device__ glm::vec3 getFromFramebuffer(int x, int y, glm::vec3* frameb } } +__host__ __device__ glm::vec3 findTextureColor(glm::vec3 point, glm::vec3 * texColors, tex theTex){ + //int id = theTex.id; + //int size = theTex.h * theTex.w; + //printf("point: %.2f, %.2f, %.2f\n", point.r, point.g, point.b); + glm::vec3 result; + float u,v; + if( fabs( point.x - 0.1f ) < 0.002f){ + + u = point.y + 0.5f; + v = point.z + 0.5f; + } + else if( fabs( point.y - 0.1f )< 0.002f){ + + u = point.x + 0.5f; + v = point.z + 0.5f; + } + else if( fabs( point.z - 0.1f ) < 0.002f){ + + u = point.x + 0.5f; + v = point.y + 0.5f; + } + + //int idx = ( (int) v * theTex.w )* theTex.h + (int)u * theTex.h; + + //result.r = texColors[idx].r/255.0f; + //result.g = texColors[idx].g/255.0f; + //result.b = texColors[idx].b/255.0f; + //printf("texture color: %.2f, %.2f, %.2f\n", result.r, result.g, result.b); + return result; +} + +__host__ __device__ glm::vec3 getTextureColor(glm::vec3 &point, triangle &thePoly, glm::vec3 * texColors, tex &theTex){ + glm::vec3 result(0.0f, 0.0f, 0.0f); + triangle newPoly = thePoly; + //Shift XY coordinate system (+0.5, +0.5) to match the subpixeling technique + newPoly.p0 += glm::vec3(0.5f, 0.5f, 0.0f); + newPoly.p1 += glm::vec3(0.5f, 0.5f, 0.0f); + newPoly.p2 += glm::vec3(0.5f, 0.5f, 0.0f); + + //Calculate alternative 1/Z, U/Z and V/Z values which will be interpolated + newPoly.uv0 /= newPoly.p0.z; + newPoly.uv1 /= newPoly.p1.z; + newPoly.uv2 /= newPoly.p2.z; + + // Sort the vertices in ascending Y order + glm::vec3 tempf; + #define swapPoint(m, n) tempf = m; m = n; n = tempf; + if (newPoly.p0.y > newPoly.p1.y) //swap p0 and p1 + swapPoint(newPoly.p0, newPoly.p1); + if (newPoly.p0.y > newPoly.p2.y) //swap p0 and p2 + swapPoint(newPoly.p0, newPoly.p2); + if (newPoly.p1.y > newPoly.p2.y) //swap p1 and p2 + swapPoint(newPoly.p1, newPoly.p2); + #undef swapPoint + + float x0 = newPoly.p0.x; + float y0 = newPoly.p0.y; + float z0 = newPoly.p0.z; + float x1 = newPoly.p1.x; + float y1 = newPoly.p1.y; + float z1 = newPoly.p1.z; + float x2 = newPoly.p2.x; + float y2 = newPoly.p2.y; + float z2 = newPoly.p2.z; + float y0i = y0; + float y1i = y1; + float y2i = y2; + printf("swappded points: %.2f, %.2f, %.2f", y0, y1, y2); + + if ((y0i == y1i && y0i == y2i) + || ((int) x0 == (int) x1 && (int) x0 == (int) x2)) + return result; + // Calculate horizontal and vertical increments for UV axes + float denom = ((x2 - x0) * (y1 - y0) - (x1 - x0) * (y2 - y0)); + + if (!denom) // Skip if it's an infinitely thin line + return result; + + denom = 1 / denom; + glm::vec3 duv_dx, duv_dy; // ( d(1/z), d(u/z), d(v/z) ) + duv_dx.x = ((newPoly.uv2.x - newPoly.uv0.x) * (y1 - y0) - (newPoly.uv1.x - newPoly.uv0.x) * (y2 - y0)) * denom; + duv_dx.y = ((newPoly.uv2.y - newPoly.uv0.y) * (y1 - y0) - (newPoly.uv1.y - newPoly.uv0.y) * (y2 - y0)) * denom; + duv_dx.z = ((newPoly.uv2.z - newPoly.uv0.z) * (y1 - y0) - (newPoly.uv1.z - newPoly.uv0.z) * (y2 - y0)) * denom; + duv_dy.x = ((newPoly.uv2.x - newPoly.uv0.x) * (x2 - x0) - (newPoly.uv2.x - newPoly.uv0.x) * (x1 - x0)) * denom; + duv_dy.y = ((newPoly.uv2.y - newPoly.uv0.y) * (x2 - x0) - (newPoly.uv2.y - newPoly.uv0.y) * (x1 - x0)) * denom; + duv_dy.z = ((newPoly.uv2.z - newPoly.uv0.z) * (x2 - x0) - (newPoly.uv2.z - newPoly.uv0.z) * (x1 - x0)) * denom; + + // Calculate X-slopes along the edges + float dx_dy0, dx_dy1, dx_dy2; + if (y1 > y0) + dx_dy0 = (x1 - x0) / (y1 - y0); + if (y2 > y0) + dx_dy1 = (x2 - x0) / (y2 - y0); + if (y2 > y1) + dx_dy2 = (x2 - x1) / (y2 - y1); + + // Determine which side of the poly the longer edge is on + + int side = dx_dy1 > dx_dy0; + + if (y0 == y1) + side = x0 > x1; + if (y1 == y2) + side = x2 > x1; + return result; +} + //Kernel that clears a given pixel buffer with a given color __global__ void clearImage(glm::vec2 resolution, glm::vec3* image, glm::vec3 color){ int x = (blockIdx.x * blockDim.x) + threadIdx.x; @@ -129,36 +241,249 @@ __global__ void sendImageToPBO(uchar4* PBOpos, glm::vec2 resolution, glm::vec3* } //TODO: Implement a vertex shader -__global__ void vertexShadeKernel(float* vbo, int vbosize){ +__global__ void vertexShadeKernel(float* vbo, int vbosize, float* nbo, int nbosize, cudaMat4 M_mvp, cudaMat4 M_mv_prime){ + int index = (blockIdx.x * blockDim.x) + threadIdx.x; if(index 0.0f )? xMin : 0.0f; + yMin = ( yMin > 0.0f) ? yMin : 0.0f; + xMax = ( xMax < resolution.x -1) ? xMax : resolution.x -1; + yMax = ( yMax < resolution.y -1) ? yMax : resolution.y -1; + + if(xMin<0 || yMin<0 || xMin>=resolution.x || yMin>=resolution.y) + return; + if(xMax<0 || yMax<0 || xMax>=resolution.x || yMax>=resolution.y) + return; + + //scanline approach + for(int y = yMin; y < yMax; y++){ //top to down + for(int x = xMin; x < xMax; x++){ //left to right + int pixelID = x + resolution.x*y; + glm::vec2 screenCoord = imageToScreen(glm::vec2(x,y),resolution); //perspective transformation + glm::vec3 b = calculateBarycentricCoordinate(tri, screenCoord); //barycentric coordinate for (x,y) pixel + + if(isBarycentricCoordInBounds(b)){ //p is in the triangle bounds + float z = getZAtCoordinate(b, tri); //depth + + if(Z_TEST == 1){ //do the depth test with atomic function + // while(atomicCAS(&depthbuffer[pixelID].tested, 1, 0) != 1); //until current fragment is tested + } + if(z > depthbuffer[pixelID].position.z && z <= 1.0f){ + fragment frag = depthbuffer[pixelID]; + frag.color = interpolateColor(b,tri); + /*frag.position = interpolatePosition(b,tri); + frag.position.z = z;*/ + glm::vec3 point(screenCoord.x, screenCoord.y, z); + frag.position = point; + frag.normal = tri.n; + + if(LINE == 1){ //shade line color + glm::vec3 lineColor(0.0f,0.0f,1.0f); //blue + glm::vec3 p = interpolatePosition(b,tri); + if(fabs(glm::dot(glm::normalize(tri.p0 - p), glm::normalize(tri.p0 - tri.p1))-1.0f)<0.0001f|| + fabs(glm::dot(glm::normalize(tri.p1 - p), glm::normalize(tri.p1 - tri.p2))-1.0f)<0.0001f || + fabs(glm::dot(glm::normalize(tri.p2 - p), glm::normalize(tri.p2 - tri.p0))-1.0f)<0.0001f ){ + + frag.color = lineColor; + frag.normal = glm::vec3(0.0f, 0.0f, 1.0f); + } + } + + if(SHADING == 4){ // perspectively correct texture map + //http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ + // http://chrishecker.com/Miscellaneous_Technical_Articles + //glm::vec3 p = multiplyMV(M_mvp_inverse, glm::vec4(depthbuffer[index].position, 1.0f)); + // glm::vec3 p1 = multiplyMV(M_mvp_inverse, glm::vec4(primitives[index].p1, 1.0f)); + // glm::vec3 p2 = multiplyMV(M_mvp_inverse, glm::vec4(primitives[index].p2, 1.0f)); + //primitives[index].c0 = findTextureColor(p0, texColor, theTex); + //primitives[index].c1 = findTextureColor(p1, texColor, theTex); + // primitives[index].c2 = findTextureColor(p2, texColor, theTex); + } + + depthbuffer[pixelID] = frag; + } + // atomicExch(&depthbuffer[pixelID].tested, 1); + + } + } + + } + + + primitives[index] = tri; //update + } +} + +// display points +__global__ void rasterizationPointsKernel(float* vbo, int vbosize, float * nbo, int nbosize, fragment* depthbuffer, glm::vec2 resolution){ + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if(index=resolution.x || pixel.y>=resolution.y) + return; + int pixelID = pixel.x + pixel.y * resolution.x; + + //shade the point representation + if(point.z > depthbuffer[pixelID].position.z ){ + glm::vec3 pointColor(1.0f, 1.0f, 0.0f); //yellow + /* depthbuffer[pixelID].position = point; + depthbuffer[pixelID].color = pointColor; + depthbuffer[pixelID].normal = glm::vec3(0.0f, 0.0f, 1.0f);*/ + for(int i=pixel.x-1; i<=pixel.x+1; i++){ + for(int j=pixel.y-1; j<=pixel.y+1; j++){ + if(i<0 || j<0 || i>=resolution.x || j>=resolution.y) + return; + int newpixelID = i + j * resolution.x; + depthbuffer[newpixelID].position = point; + depthbuffer[newpixelID].color = pointColor; + depthbuffer[newpixelID].normal = glm::vec3(0.0f, 0.0f, 1.0f); + // atomicExch(&depthbuffer[pixelID].tested, 1); + } + } + } + } } + + //TODO: Implement a fragment shader -__global__ void fragmentShadeKernel(fragment* depthbuffer, glm::vec2 resolution){ +__global__ void fragmentShadeKernel(fragment* depthbuffer, glm::vec2 resolution, int SHADING){ + //set up light + glm::vec3 lightPos(500.0f, 500.0f, 1000.0f); //add a light in the scene for shading + int x = (blockIdx.x * blockDim.x) + threadIdx.x; int y = (blockIdx.y * blockDim.y) + threadIdx.y; int index = x + (y * resolution.x); + if(x<=resolution.x && y<=resolution.y){ + if(depthbuffer[index].normal.z<0) + return; + if(SHADING == 0){ //shade by normal + depthbuffer[index].color.r = glm::clamp(depthbuffer[index].normal.x, 0.0f, 1.0f); + depthbuffer[index].color.g = glm::clamp(depthbuffer[index].normal.y, 0.0f, 1.0f); + depthbuffer[index].color.b = glm::clamp(depthbuffer[index].normal.z, 0.0f, 1.0f); + } + else if(SHADING == 1){ //shade by depth + depthbuffer[index].color.r = glm::clamp(depthbuffer[index].position.z/1000.0f, 0.0f, 1.0f); + depthbuffer[index].color.g = glm::clamp(depthbuffer[index].position.z/1000.0f, 0.0f, 1.0f); + depthbuffer[index].color.b = glm::clamp(depthbuffer[index].position.z/1000.0f, 0.0f, 1.0f); + } + else if(SHADING == 2){ //diffuse shade + glm::vec3 lightDir = glm::normalize(lightPos - depthbuffer[index].position); + float cosTerm = glm::clamp(glm::dot(lightDir, depthbuffer[index].normal), 0.0f, 1.0f); + depthbuffer[index].color = glm::clamp(cosTerm * depthbuffer[index].color, 0.0f, 1.0f); + } + else if (SHADING == 3){ //blinn-phong shade + float coeff = 5.0f; + glm::vec3 lightDir = glm::normalize(lightPos - depthbuffer[index].position); + float cosTerm = glm::clamp(glm::dot(lightDir, depthbuffer[index].normal), 0.0f, 1.0f); + depthbuffer[index].color = glm::clamp( std::pow(cosTerm,coeff) * depthbuffer[index].color, 0.0f, 1.0f); + } + else{ + depthbuffer[index].color =glm::clamp(depthbuffer[index].color, 0.0f, 1.0f); + } } } + //Writes fragment colors to the framebuffer __global__ void render(glm::vec2 resolution, fragment* depthbuffer, glm::vec3* framebuffer){ @@ -172,7 +497,15 @@ __global__ void render(glm::vec2 resolution, fragment* depthbuffer, glm::vec3* f } // Wrapper for the __global__ call that sets up the kernel calls and does a ton of memory management -void cudaRasterizeCore(uchar4* PBOpos, glm::vec2 resolution, float frame, float* vbo, int vbosize, float* cbo, int cbosize, int* ibo, int ibosize){ +void cudaRasterizeCore(uchar4* PBOpos, glm::vec2 resolution, float frame, float* vbo, int vbosize, float* cbo, int cbosize, + int* ibo, int ibosize, float * nbo, int nbosize){ + + //set up camera, + // cam theCam = mouseCam; + + //cuda timer event + cudaEventCreate(&start); + cudaEventCreate(&stop); // set up crucial magic int tileSize = 8; @@ -199,6 +532,7 @@ void cudaRasterizeCore(uchar4* PBOpos, glm::vec2 resolution, float frame, float* //------------------------------ //memory stuff //------------------------------ + cudaEventRecord( start, 0 ); primitives = NULL; cudaMalloc((void**)&primitives, (ibosize/3)*sizeof(triangle)); @@ -214,41 +548,130 @@ void cudaRasterizeCore(uchar4* PBOpos, glm::vec2 resolution, float frame, float* cudaMalloc((void**)&device_cbo, cbosize*sizeof(float)); cudaMemcpy( device_cbo, cbo, cbosize*sizeof(float), cudaMemcpyHostToDevice); + device_nbo = NULL; + cudaMalloc((void**)&device_nbo, nbosize*sizeof(float)); + cudaMemcpy( device_nbo, nbo, nbosize*sizeof(float), cudaMemcpyHostToDevice); + + int tbosize = 0; + device_tbo = NULL; + if( SHADING_MODE == 5 && textureColor.size()!=0 ){ //texture map!!! + //establish color vector + tbosize = textureColor.size(); + glm::vec3 * tbo = new glm::vec3[tbosize]; + for(int i=0; i< tbosize; i++){ + tbo[i] = textureColor[i]; + } + cudaMalloc((void**)&device_tbo, tbosize*sizeof(glm::vec3)); + cudaMemcpy( device_tbo, tbo, tbosize*sizeof(glm::vec3), cudaMemcpyHostToDevice); + delete tbo; + } + tileSize = 32; int primitiveBlocks = ceil(((float)vbosize/3)/((float)tileSize)); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for set up memory : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } //------------------------------ //vertex shader //------------------------------ - vertexShadeKernel<<>>(device_vbo, vbosize); - + cudaEventRecord( start, 0 ); + vertexShadeKernel<<>>(device_vbo, vbosize, device_nbo, nbosize, mouseCam.M_mvp, mouseCam.M_mv_prime); cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for vertex shader : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } //------------------------------ //primitive assembly //------------------------------ + cudaEventRecord( start, 0 ); primitiveBlocks = ceil(((float)ibosize/3)/((float)tileSize)); - primitiveAssemblyKernel<<>>(device_vbo, vbosize, device_cbo, cbosize, device_ibo, ibosize, primitives); + primitiveAssemblyKernel<<>>(device_vbo, vbosize, device_cbo, cbosize, device_ibo, ibosize, device_nbo, nbosize, primitives, SHADING_MODE); cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for primitive assembly : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } //------------------------------ //rasterization //------------------------------ - rasterizationKernel<<>>(primitives, ibosize/3, depthbuffer, resolution); + cudaEventRecord( start, 0 ); + rasterizationKernel<<>>(primitives, ibosize/3, depthbuffer, resolution, device_tbo, tbosize, textureMap, LINE_RASTER, SHADING_MODE); cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for rasterization : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } //------------------------------ //fragment shader //------------------------------ - fragmentShadeKernel<<>>(depthbuffer, resolution); + cudaEventRecord( start, 0 ); + fragmentShadeKernel<<>>(depthbuffer, resolution, SHADING_MODE); cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for fragment shader : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } + //------------------------------ + //point raster shader + //------------------------------ + if(POINT_RASTER ==1){ + cudaEventRecord( start, 0 ); + primitiveBlocks = ceil(((float)vbosize/3)/((float)tileSize)); + rasterizationPointsKernel<<>>(device_vbo, vbosize, device_nbo, nbosize, depthbuffer, resolution); //render point out + cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for point raster : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } + } + + //------------------------------ //write fragments to framebuffer //------------------------------ + cudaEventRecord( start, 0 ); render<<>>(resolution, depthbuffer, framebuffer); sendImageToPBO<<>>(PBOpos, resolution, framebuffer); cudaDeviceSynchronize(); + cudaEventRecord( stop, 0 ); + cudaEventSynchronize( stop ); + cudaEventElapsedTime( &timeDuration, start, stop ); + if(PERFORMANCE_MEASURE == 1){ + printf("\n\n*****************************************************\n"); + printf("Time Taken for render : %f ms\n",timeDuration); + printf("*****************************************************\n"); + } kernelCleanup(); diff --git a/src/rasterizeKernels.h b/src/rasterizeKernels.h index 784be17..aa253da 100644 --- a/src/rasterizeKernels.h +++ b/src/rasterizeKernels.h @@ -9,8 +9,117 @@ #include #include #include "glm/glm.hpp" +#include "glm/gtc/matrix_transform.hpp" //to used 'lookAt' & 'perspective' +#include "cudaMat4.h" +#include "utilities.h" + +#define Z_TEST 0 +extern int PERFORMANCE_MEASURE; +extern int SHADING_MODE; //0-shading based on normal, 1-shade based on depth, 2-diffuse, 3-blinn, 4-texture map, 5-original cbo, +extern int POINT_RASTER; //0/1 to off/on points display +extern int LINE_RASTER; //0/1 to off/on lines display void kernelCleanup(); -void cudaRasterizeCore(uchar4* pos, glm::vec2 resolution, float frame, float* vbo, int vbosize, float* cbo, int cbosize, int* ibo, int ibosize); +void cudaRasterizeCore(uchar4* pos, glm::vec2 resolution, float frame, float* vbo, int vbosize, float* cbo, int cbosize, + int* ibo, int ibosize, float * nbo, int nbosize); + +class cam{ +public: + float fovy; //vertical field of view + float aspect; //aspect ratio = reso_x/reso_y + glm::vec3 eye; //location of camera + glm::vec3 up; //camera up vector + glm::vec3 center; //where camera is looking at + + float theta; + float phi; + float r; + + glm::mat4 M_model, M_view, M_projection; + //glm::mat4 M_camera; + cudaMat4 M_mvp_inverse; + cudaMat4 M_mvp; //model-view-projection matrix + cudaMat4 M_mv_prime; // transpose(inverse(modelView)) + + cam(){} + + //constructor + cam(float fovyi, float aspecti, glm::vec3 eyei, glm::vec3 upi, glm::vec3 centeri){ + fovy = fovyi; + eye = eyei; + up = glm::normalize(upi); + center = centeri; + aspect = aspecti; + + theta = 90.0f; + phi = 0.0f; + r = glm::length (eye - center); + calculateMVP(); + } + + //copy assignment operator + cam& operator= ( const cam& other ){ + fovy = other.fovy; + eye = other.eye; + up = glm::normalize(other.up); + center = other.center; + aspect = other.aspect; + r = other.r; + theta = other.theta; + phi = other.phi; + + //M_camera = other.M_camera; + M_mvp = other.M_mvp; + M_mv_prime = other.M_mv_prime; + return *this; + } + + void calculateCamPos(){ + eye.x = r * sin( theta * PI /180.0f ) * sin( phi * PI /180.0f ) + center.x; + eye.y = r * cos( theta * PI /180.0f ) + center.y; + eye.z = r * sin( theta * PI /180.0f ) * cos( phi * PI /180.0f ) + center.z; + calculateMVP(); + } + + void calculateMVP(){ + + //establish model matrix + //M_model = glm::mat4( glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + M_model = utilityCore::buildTransformationMatrix(glm::vec3(0.0f, -0.3f, 0.0f), glm::vec3(0.0f), glm::vec3(0.8f)); + + //establish view matrix = inverse of camera transform matrix + M_view = glm::lookAt(eye,center,up); + + //establish projection matrix + //make things closer appear bigger + float near = 0.1f; + float far = 1000.0f; + M_projection = glm::perspective(fovy,aspect,near,far); + + M_mvp = utilityCore::glmMat4ToCudaMat4( M_projection * M_view * M_model ); + //M_mvp_prime = utilityCore::glmMat4ToCudaMat4(glm::transpose(glm::inverse(M_projection * M_view * M_model ))); + M_mv_prime = utilityCore::glmMat4ToCudaMat4(glm::transpose(glm::inverse(M_view * M_model))); + + M_mvp_inverse = utilityCore::glmMat4ToCudaMat4( glm::inverse(M_projection * M_view * M_model )); + //printf("the mvp matrix:\n"); + //utilityCore::printCudaMat4(M_mvp); + + } +}; + +extern cam mouseCam; //used for mouse events in "main.cpp" + +class tex{ + +public: + tex(){} //default constructor + int id; + int h; + int w; + +}; +//stores multiple textures +extern tex textureMap; //used for loading texture in "main.cpp" +extern std::vector textureColor; #endif //RASTERIZEKERNEL_H diff --git a/src/rasterizeTools.h b/src/rasterizeTools.h index e9b5dcc..f71f455 100644 --- a/src/rasterizeTools.h +++ b/src/rasterizeTools.h @@ -16,12 +16,17 @@ struct triangle { glm::vec3 c0; glm::vec3 c1; glm::vec3 c2; + glm::vec3 n; + glm::vec3 uv0; + glm::vec3 uv1; + glm::vec3 uv2; }; struct fragment{ glm::vec3 color; glm::vec3 normal; glm::vec3 position; + int tested; }; //Multiplies a cudaMat4 matrix and a vec4 @@ -75,4 +80,28 @@ __host__ __device__ float getZAtCoordinate(glm::vec3 barycentricCoord, triangle return -(barycentricCoord.x*tri.p0.z + barycentricCoord.y*tri.p1.z + barycentricCoord.z*tri.p2.z); } +__host__ __device__ glm::vec3 interpolateColor(glm::vec3 barycentricCoord, triangle tri){ + return barycentricCoord.x * tri.c0 + barycentricCoord.y * tri.c1 + barycentricCoord.z * tri.c2; +} + +__host__ __device__ glm::vec3 interpolatePosition(glm::vec3 barycentricCoord, triangle tri){ + return barycentricCoord.x * tri.p0 + barycentricCoord.y * tri.p1 + barycentricCoord.z * tri.p2; +} + + +// convert imgae coordinates to screen coordinates +__host__ __device__ glm::vec2 imageToScreen(glm::vec2 pixel, glm::vec2 reso){ + glm::vec2 tmp; + tmp.x = (pixel.x - (reso.x-1.0f)/2.0f) / (reso.x/2.0f); + tmp.y = -(pixel.y - (reso.y-1.0f)/2.0f) / (reso.y/2.0f); + return tmp; +} + +// convert screen coordinates to image coordinates +__host__ __device__ glm::vec2 screenToImage(glm::vec2 screen, glm::vec2 reso){ + glm::vec2 tmp; + tmp.x = (int)glm::round( (screen.x + 1.0f) * reso.x / 2.0f); + tmp.y = (int)glm::round( (- screen.y + 1.0f) * reso.y / 2.0f); + return tmp; +} #endif \ No newline at end of file diff --git a/textures/Duck.bmp b/textures/Duck.bmp new file mode 100644 index 0000000..c9a4199 Binary files /dev/null and b/textures/Duck.bmp differ diff --git a/textures/cowTexture.jpg b/textures/cowTexture.jpg new file mode 100644 index 0000000..131d300 Binary files /dev/null and b/textures/cowTexture.jpg differ diff --git a/textures/magicCube.png b/textures/magicCube.png new file mode 100644 index 0000000..9aa0ebf Binary files /dev/null and b/textures/magicCube.png differ diff --git a/textures/treasureBox.png b/textures/treasureBox.png new file mode 100644 index 0000000..5a90d4e Binary files /dev/null and b/textures/treasureBox.png differ diff --git a/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/FreeImage.dll b/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/FreeImage.dll new file mode 100644 index 0000000..3ce0a70 Binary files /dev/null and b/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/FreeImage.dll differ diff --git a/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/PROJ4_Rasterizer.vcxproj b/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/PROJ4_Rasterizer.vcxproj index f640485..c7f1158 100644 --- a/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/PROJ4_Rasterizer.vcxproj +++ b/windows/PROJ4_Rasterizer/PROJ4_Rasterizer/PROJ4_Rasterizer.vcxproj @@ -42,12 +42,12 @@ Level3 Disabled - $(SolutionDir)..\..\external\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\..\external\FreeImage;$(SolutionDir)..\..\external\include;%(AdditionalIncludeDirectories) true - $(SolutionDir)..\..\external\lib\win\GLFW;$(SolutionDir)..\..\external\lib\win\GL;%(AdditionalLibraryDirectories) - cudart.lib;glew32s.lib;glfw3.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\external\FreeImage;$(SolutionDir)..\..\external\lib\win\GLFW;$(SolutionDir)..\..\external\lib\win\GL;%(AdditionalLibraryDirectories) + cudart.lib;glew32s.lib;glfw3.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;FreeImage.lib;%(AdditionalDependencies) @@ -56,15 +56,18 @@ MaxSpeed true true - $(SolutionDir)..\..\external\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\..\external\FreeImage;$(SolutionDir)..\..\external\include;%(AdditionalIncludeDirectories) true true true - $(SolutionDir)..\..\external\lib\win\GLFW;$(SolutionDir)..\..\external\lib\win\GL;%(AdditionalLibraryDirectories) - cudart.lib;glew32s.lib;glfw3.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)..\..\external\FreeImage;$(SolutionDir)..\..\external\lib\win\GLFW;$(SolutionDir)..\..\external\lib\win\GL;%(AdditionalLibraryDirectories) + cudart.lib;glew32s.lib;glfw3.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;FreeImage.lib;%(AdditionalDependencies) + + compute_30,sm_30 +