diff --git a/SOIL.h b/SOIL.h new file mode 100644 index 0000000..43f634f --- /dev/null +++ b/SOIL.h @@ -0,0 +1,433 @@ +/** + @mainpage SOIL + + Jonathan Dummer + 2007-07-26-10.36 + + Simple OpenGL Image Library + + A tiny c library for uploading images as + textures into OpenGL. Also saving and + loading of images is supported. + + I'm using Sean's Tool Box image loader as a base: + http://www.nothings.org/ + + I'm upgrading it to load TGA and DDS files, and a direct + path for loading DDS files straight into OpenGL textures, + when applicable. + + Image Formats: + - BMP load & save + - TGA load & save + - DDS load & save + - PNG load + - JPG load + + OpenGL Texture Features: + - resample to power-of-two sizes + - MIPmap generation + - compressed texture S3TC formats (if supported) + - can pre-multiply alpha for you, for better compositing + - can flip image about the y-axis (except pre-compressed DDS files) + + Thanks to: + * Sean Barret - for the awesome stb_image + * Dan Venkitachalam - for finding some non-compliant DDS files, and patching some explicit casts + * everybody at gamedev.net +**/ + +#ifndef HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY +#define HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY + +#ifdef __cplusplus +extern "C" { +#endif + +/** + The format of images that may be loaded (force_channels). + SOIL_LOAD_AUTO leaves the image in whatever format it was found. + SOIL_LOAD_L forces the image to load as Luminous (greyscale) + SOIL_LOAD_LA forces the image to load as Luminous with Alpha + SOIL_LOAD_RGB forces the image to load as Red Green Blue + SOIL_LOAD_RGBA forces the image to load as Red Green Blue Alpha +**/ +enum +{ + SOIL_LOAD_AUTO = 0, + SOIL_LOAD_L = 1, + SOIL_LOAD_LA = 2, + SOIL_LOAD_RGB = 3, + SOIL_LOAD_RGBA = 4 +}; + +/** + Passed in as reuse_texture_ID, will cause SOIL to + register a new texture ID using glGenTextures(). + If the value passed into reuse_texture_ID > 0 then + SOIL will just re-use that texture ID (great for + reloading image assets in-game!) +**/ +enum +{ + SOIL_CREATE_NEW_ID = 0 +}; + +/** + flags you can pass into SOIL_load_OGL_texture() + and SOIL_create_OGL_texture(). + (note that if SOIL_FLAG_DDS_LOAD_DIRECT is used + the rest of the flags with the exception of + SOIL_FLAG_TEXTURE_REPEATS will be ignored while + loading already-compressed DDS files.) + + SOIL_FLAG_POWER_OF_TWO: force the image to be POT + SOIL_FLAG_MIPMAPS: generate mipmaps for the texture + SOIL_FLAG_TEXTURE_REPEATS: otherwise will clamp + SOIL_FLAG_MULTIPLY_ALPHA: for using (GL_ONE,GL_ONE_MINUS_SRC_ALPHA) blending + SOIL_FLAG_INVERT_Y: flip the image vertically + SOIL_FLAG_COMPRESS_TO_DXT: if the card can display them, will convert RGB to DXT1, RGBA to DXT5 + SOIL_FLAG_DDS_LOAD_DIRECT: will load DDS files directly without _ANY_ additional processing + SOIL_FLAG_NTSC_SAFE_RGB: clamps RGB components to the range [16,235] + SOIL_FLAG_CoCg_Y: Google YCoCg; RGB=>CoYCg, RGBA=>CoCgAY + SOIL_FLAG_TEXTURE_RECTANGE: uses ARB_texture_rectangle ; pixel indexed & no repeat or MIPmaps or cubemaps +**/ +enum +{ + SOIL_FLAG_POWER_OF_TWO = 1, + SOIL_FLAG_MIPMAPS = 2, + SOIL_FLAG_TEXTURE_REPEATS = 4, + SOIL_FLAG_MULTIPLY_ALPHA = 8, + SOIL_FLAG_INVERT_Y = 16, + SOIL_FLAG_COMPRESS_TO_DXT = 32, + SOIL_FLAG_DDS_LOAD_DIRECT = 64, + SOIL_FLAG_NTSC_SAFE_RGB = 128, + SOIL_FLAG_CoCg_Y = 256, + SOIL_FLAG_TEXTURE_RECTANGLE = 512 +}; + +/** + The types of images that may be saved. + (TGA supports uncompressed RGB / RGBA) + (BMP supports uncompressed RGB) + (DDS supports DXT1 and DXT5) +**/ +enum +{ + SOIL_SAVE_TYPE_TGA = 0, + SOIL_SAVE_TYPE_BMP = 1, + SOIL_SAVE_TYPE_DDS = 2 +}; + +/** + Defines the order of faces in a DDS cubemap. + I recommend that you use the same order in single + image cubemap files, so they will be interchangeable + with DDS cubemaps when using SOIL. +**/ +#define SOIL_DDS_CUBEMAP_FACE_ORDER "EWUDNS" + +/** + The types of internal fake HDR representations + + SOIL_HDR_RGBE: RGB * pow( 2.0, A - 128.0 ) + SOIL_HDR_RGBdivA: RGB / A + SOIL_HDR_RGBdivA2: RGB / (A*A) +**/ +enum +{ + SOIL_HDR_RGBE = 0, + SOIL_HDR_RGBdivA = 1, + SOIL_HDR_RGBdivA2 = 2 +}; + +/** + Loads an image from disk into an OpenGL texture. + \param filename the name of the file to upload as a texture + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_texture + ( + const char *filename, + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads 6 images from disk into an OpenGL cubemap texture. + \param x_pos_file the name of the file to upload as the +x cube face + \param x_neg_file the name of the file to upload as the -x cube face + \param y_pos_file the name of the file to upload as the +y cube face + \param y_neg_file the name of the file to upload as the -y cube face + \param z_pos_file the name of the file to upload as the +z cube face + \param z_neg_file the name of the file to upload as the -z cube face + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_cubemap + ( + const char *x_pos_file, + const char *x_neg_file, + const char *y_pos_file, + const char *y_neg_file, + const char *z_pos_file, + const char *z_neg_file, + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads 1 image from disk and splits it into an OpenGL cubemap texture. + \param filename the name of the file to upload as a texture + \param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc. + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_single_cubemap + ( + const char *filename, + const char face_order[6], + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads an HDR image from disk into an OpenGL texture. + \param filename the name of the file to upload as a texture + \param fake_HDR_format SOIL_HDR_RGBE, SOIL_HDR_RGBdivA, SOIL_HDR_RGBdivA2 + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_HDR_texture + ( + const char *filename, + int fake_HDR_format, + int rescale_to_max, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads an image from RAM into an OpenGL texture. + \param buffer the image data in RAM just as if it were still in a file + \param buffer_length the size of the buffer in bytes + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_texture_from_memory + ( + const unsigned char *const buffer, + int buffer_length, + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads 6 images from memory into an OpenGL cubemap texture. + \param x_pos_buffer the image data in RAM to upload as the +x cube face + \param x_pos_buffer_length the size of the above buffer + \param x_neg_buffer the image data in RAM to upload as the +x cube face + \param x_neg_buffer_length the size of the above buffer + \param y_pos_buffer the image data in RAM to upload as the +x cube face + \param y_pos_buffer_length the size of the above buffer + \param y_neg_buffer the image data in RAM to upload as the +x cube face + \param y_neg_buffer_length the size of the above buffer + \param z_pos_buffer the image data in RAM to upload as the +x cube face + \param z_pos_buffer_length the size of the above buffer + \param z_neg_buffer the image data in RAM to upload as the +x cube face + \param z_neg_buffer_length the size of the above buffer + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_cubemap_from_memory + ( + const unsigned char *const x_pos_buffer, + int x_pos_buffer_length, + const unsigned char *const x_neg_buffer, + int x_neg_buffer_length, + const unsigned char *const y_pos_buffer, + int y_pos_buffer_length, + const unsigned char *const y_neg_buffer, + int y_neg_buffer_length, + const unsigned char *const z_pos_buffer, + int z_pos_buffer_length, + const unsigned char *const z_neg_buffer, + int z_neg_buffer_length, + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Loads 1 image from RAM and splits it into an OpenGL cubemap texture. + \param buffer the image data in RAM just as if it were still in a file + \param buffer_length the size of the buffer in bytes + \param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc. + \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_load_OGL_single_cubemap_from_memory + ( + const unsigned char *const buffer, + int buffer_length, + const char face_order[6], + int force_channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Creates a 2D OpenGL texture from raw image data. Note that the raw data is + _NOT_ freed after the upload (so the user can load various versions). + \param data the raw data to be uploaded as an OpenGL texture + \param width the width of the image in pixels + \param height the height of the image in pixels + \param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_create_OGL_texture + ( + const unsigned char *const data, + int width, int height, int channels, + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Creates an OpenGL cubemap texture by splitting up 1 image into 6 parts. + \param data the raw data to be uploaded as an OpenGL texture + \param width the width of the image in pixels + \param height the height of the image in pixels + \param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA + \param face_order the order of the faces in the file, and combination of NSWEUD, for North, South, Up, etc. + \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) + \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT + \return 0-failed, otherwise returns the OpenGL texture handle +**/ +unsigned int + SOIL_create_OGL_single_cubemap + ( + const unsigned char *const data, + int width, int height, int channels, + const char face_order[6], + unsigned int reuse_texture_ID, + unsigned int flags + ); + +/** + Captures the OpenGL window (RGB) and saves it to disk + \return 0 if it failed, otherwise returns 1 +**/ +int + SOIL_save_screenshot + ( + const char *filename, + int image_type, + int x, int y, + int width, int height + ); + +/** + Loads an image from disk into an array of unsigned chars. + Note that *channels return the original channel count of the + image. If force_channels was other than SOIL_LOAD_AUTO, + the resulting image has force_channels, but *channels may be + different (if the original image had a different channel + count). + \return 0 if failed, otherwise returns 1 +**/ +unsigned char* + SOIL_load_image + ( + const char *filename, + int *width, int *height, int *channels, + int force_channels + ); + +/** + Loads an image from memory into an array of unsigned chars. + Note that *channels return the original channel count of the + image. If force_channels was other than SOIL_LOAD_AUTO, + the resulting image has force_channels, but *channels may be + different (if the original image had a different channel + count). + \return 0 if failed, otherwise returns 1 +**/ +unsigned char* + SOIL_load_image_from_memory + ( + const unsigned char *const buffer, + int buffer_length, + int *width, int *height, int *channels, + int force_channels + ); + +/** + Saves an image from an array of unsigned chars (RGBA) to disk + \return 0 if failed, otherwise returns 1 +**/ +int + SOIL_save_image + ( + const char *filename, + int image_type, + int width, int height, int channels, + const unsigned char *const data + ); + +/** + Frees the image data (note, this is just C's "free()"...this function is + present mostly so C++ programmers don't forget to use "free()" and call + "delete []" instead [8^) +**/ +void + SOIL_free_image_data + ( + unsigned char *img_data + ); + +/** + This function resturn a pointer to a string describing the last thing + that happened inside SOIL. It can be used to determine why an image + failed to load. +**/ +const char* + SOIL_last_result + ( + void + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY */ diff --git a/renderFramework.vcxproj b/renderFramework.vcxproj index 99c9717..c3cc46e 100644 --- a/renderFramework.vcxproj +++ b/renderFramework.vcxproj @@ -128,12 +128,14 @@ + + diff --git a/renderFramework.vcxproj.filters b/renderFramework.vcxproj.filters index 1158e0a..0b87639 100644 --- a/renderFramework.vcxproj.filters +++ b/renderFramework.vcxproj.filters @@ -27,6 +27,9 @@ 源文件 + + 源文件 + @@ -41,5 +44,8 @@ 源文件 + + 源文件 + \ No newline at end of file diff --git a/shader.cpp b/shader.cpp new file mode 100644 index 0000000..92cbd41 --- /dev/null +++ b/shader.cpp @@ -0,0 +1,193 @@ +#include "shader.h" +#include "utils.h" +#include "vertexbuffer.h" + +GLuint Shader::CompileShader(GLuint shaderType, const char * shaderCode) +{ + GLuint shader = glCreateShader(shaderType); + glShaderSource(shader, 1, &shaderCode, nullptr); + glCompileShader(shader); + GLint compileResult = GL_TRUE; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + if (compileResult == GL_FALSE) { + char szLog[1024] = { 0 }; + GLsizei logLen = 0; + glGetShaderInfoLog(shader, 1024, &logLen, szLog); + printf("Compile Shader fail error log : %s \nshader code :\n%s\n", szLog, shaderCode); + glDeleteShader(shader); + shader = 0; + } + return shader; +} + +GLuint Shader::CreateProgram(GLuint vsShader, GLuint fsShader) +{ + GLuint program = glCreateProgram(); + glAttachShader(program, vsShader); + glAttachShader(program, fsShader); + glLinkProgram(program); + glDetachShader(program, vsShader); + glDetachShader(program, fsShader); + GLint nResult; + glGetProgramiv(program, GL_LINK_STATUS, &nResult); + if (nResult == GL_FALSE) { + char log[1024] = { 0 }; + GLsizei writed = 0; + glGetProgramInfoLog(program, 1024, &writed, log); + printf("create gpu program fail,link error : %s\n", log); + glDeleteProgram(program); + program = 0; + } + return program; +} + +void Shader::Init(const char * vs, const char * fs) +{ + int nFileSize = 0; + const char* vsCode = (char*)LoadFileContent(vs, nFileSize); + const char* fsCode = (char*)LoadFileContent(vs, nFileSize); + GLuint vsShader = CompileShader(GL_VERTEX_SHADER, vsCode); + if (vsShader == 0) { + return; + } + GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER, fsCode); + if (fsShader == 0) { + return; + } + mProgram = CreateProgram(vsShader, fsShader); + glDeleteShader(vsShader); + glDeleteShader(fsShader); + if (mProgram != 0) { + mModelMatrixLocation = glGetUniformLocation(mProgram, "ModelMatrix"); + mViewMatrixLocation = glGetUniformLocation(mProgram, "ViewMatrix"); + mProjectionMatrixLocation = glGetUniformLocation(mProgram, "ProjectionMatrix"); + mPositionLocation = glGetAttribLocation(mProgram, "position"); + mColorLocation = glGetAttribLocation(mProgram, "color"); + mTexcoordLocation = glGetAttribLocation(mProgram, "texcoord"); + mNormalLocation = glGetAttribLocation(mProgram, "normal"); + } +} +void Shader::Bind(float *M, float *V, float*P) +{ + glUseProgram(mProgram); + if (mModelMatrixLocation >= 0) glUniformMatrix4fv(mModelMatrixLocation, 1, GL_FALSE, M); + if (mViewMatrixLocation >= 0)glUniformMatrix4fv(mViewMatrixLocation, 1, GL_FALSE, V); + if (mProjectionMatrixLocation >= 0)glUniformMatrix4fv(mProjectionMatrixLocation, 1, GL_FALSE, P); + + int iIndex = 0; + for (auto iter = mUniformTextures.begin(); iter != mUniformTextures.end(); ++iter) { + glActiveTexture(GL_TEXTURE0 + iIndex); + glBindTexture(GL_TEXTURE_2D, iter->second->mTexture); + glUniform1i(iter->second->mLocation, iIndex++); + } + for (auto iter = mUniformTextureCubes.begin(); iter != mUniformTextureCubes.end(); ++iter) { + glActiveTexture(GL_TEXTURE0 + iIndex); + glBindTexture(GL_TEXTURE_CUBE_MAP, iter->second->mTexture); + glUniform1i(iter->second->mLocation, iIndex++); + } + for (auto iter = mUniformVec4s.begin(); iter != mUniformVec4s.end(); ++iter) { + glUniform4fv(iter->second->mLocation, 1, iter->second->v); + } + if (mPositionLocation >= 0) { + glEnableVertexAttribArray(mPositionLocation); + glVertexAttribPointer(mPositionLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 0)); + } + if (mColorLocation >= 0) { + glEnableVertexAttribArray(mColorLocation); + glVertexAttribPointer(mColorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 4)); + } + if (mTexcoordLocation >= 0) { + glEnableVertexAttribArray(mTexcoordLocation); + glVertexAttribPointer(mTexcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 8)); + } + if (mNormalLocation >= 0) { + glEnableVertexAttribArray(mNormalLocation); + glVertexAttribPointer(mNormalLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 12)); + } +} + +void Shader::SetTexture(const char * name, const char * imagePath) +{ + auto iter = mUniformTextures.find(name); + if (iter == mUniformTextures.end()) { + GLint location = glGetUniformLocation(mProgram, name); + if (location != -1) { + UniformTexture* t = new UniformTexture; + t->mLocation = location; + t->mTexture = CreateTextureFromFile(imagePath); + mUniformTextures.insert(std::pair(name, t)); + } + else { + glDeleteTextures(1, &iter->second->mTexture); + iter->second->mTexture = CreateTextureFromFile(imagePath); + } + } +} + +void Shader::SetVec4(const char * name, float x, float y, float z, float w) +{ + auto iter = mUniformVec4s.find(name); + if (iter == mUniformVec4s.end()) { + GLuint location = glGetUniformLocation(mProgram, name); + if (location != -1) { + UniformVector4f* v = new UniformVector4f; + v->v[0] = x; + v->v[1] = y; + v->v[2] = z; + v->v[3] = w; + v->mLocation = location; + mUniformVec4s.insert(std::pair(name, v)); + } + } + else { + iter->second->v[0] = x; + iter->second->v[1] = x; + iter->second->v[2] = x; + iter->second->v[3] = x; + } +} + +GLuint Shader::SetTexture(const char * name, GLuint texture) { + auto iter = mUniformTextures.find(name); + GLuint oldTexture = 0; + if (iter == mUniformTextures.end()) { + GLint location = glGetUniformLocation(mProgram, name); + if (location != -1) { + UniformTexture*t = new UniformTexture; + t->mLocation = location; + t->mTexture = texture; + mUniformTextures.insert(std::pair(name, t)); + } + } + else { + oldTexture = iter->second->mTexture; + iter->second->mTexture = texture; + } + return oldTexture; +} + +GLuint Shader::SetTextureCube(const char * name, GLuint texture) { + auto iter = mUniformTextureCubes.find(name); + GLuint oldTexture = 0; + if (iter == mUniformTextureCubes.end()) { + GLint location = glGetUniformLocation(mProgram, name); + if (location != -1) { + UniformTextureCube*t = new UniformTextureCube; + t->mLocation = location; + t->mTexture = texture; + mUniformTextureCubes.insert(std::pair(name, t)); + } + } + else { + oldTexture = iter->second->mTexture; + iter->second->mTexture = texture; + } + return oldTexture; +} + + + + + + + diff --git a/shader.h b/shader.h new file mode 100644 index 0000000..4c8a997 --- /dev/null +++ b/shader.h @@ -0,0 +1,62 @@ +#pragma once +#include "ggl.h" + +struct UniformTexture { + GLint mLocation; + GLuint mTexture; + UniformTexture() { + mLocation = -1; + mTexture = 0; + } +}; + +struct UniformTextureCube { + GLint mLocation; + GLuint mTexture; + UniformTextureCube() { + mLocation = -1; + mTexture = 0; + } +}; + +struct UniformVector4f { + GLint mLocation; + float v[4]; + UniformVector4f() { + mLocation = -1; + memset(v, 0, sizeof(float) * 4); + } +}; + +class Shader { +public: + static GLuint CompileShader(GLuint shaderType, const char* shaderCode); + static GLuint CreateProgram(GLuint vsShader, GLuint fsShader); +public: + GLuint mProgram; + GLint mModelMatrixLocation, mViewMatrixLocation, mProjectionMatrixLocation; + GLint mPositionLocation, mColorLocation, mTexcoordLocation, mNormalLocation; + std::map mUniformTextures; + std::map mUniformTextureCubes; + std::map mUniformVec4s; + void Init(const char* vs, const char* fs); + void Bind(float* M, float* V, float* P); + void SetTexture(const char* name, const char* imagePath); + GLuint SetTexture(const char* name, GLuint texture); + GLuint SetTextureCube(const char * name, GLuint texture); + void SetVec4(const char * name, float x, float y, float z, float w); +}; + + + + + + + + + + + + + + diff --git a/utils.cpp b/utils.cpp index 151166a..85afdf8 100644 --- a/utils.cpp +++ b/utils.cpp @@ -1,4 +1,6 @@ #include "utils.h" +#pragma comment(lib,"SOIL.lib") + unsigned char* DecodeBMP(unsigned char*bmpFileData, int&width, int&height) { if (0x4D42 == *((unsigned short*)bmpFileData)) { int pixelDataOffset = *((int*)(bmpFileData + 10)); @@ -79,4 +81,10 @@ GLuint CreateTextureCubeFromBMP(const char *front, const char *back, const char glBindTexture(GL_TEXTURE_CUBE_MAP, 0); delete bmpFileContent; return texture; +} + +GLuint CreateTextureFromFile(const char*filePath) +{ + GLuint texture = SOIL_load_OGL_texture(filePath, 0, 0, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_INVERT_Y); + return texture; } \ No newline at end of file diff --git a/utils.h b/utils.h index 03bef46..2b4ee1b 100644 --- a/utils.h +++ b/utils.h @@ -1,8 +1,10 @@ #pragma once #include "ggl.h" +#include "SOIL.h" unsigned char * LoadFileContent(const char*path, int&filesize); unsigned char * DecodeBMP(unsigned char*bmpFileData, int&width, int&height); GLuint CreateTexture2D(unsigned char*pixelData, int width, int height, GLenum type); GLuint CreateTexture2DFromBMP(const char *bmpPath); GLuint CreateTextureCubeFromBMP(const char *front, const char *back, const char *left, - const char *right, const char *top, const char *bottom); \ No newline at end of file + const char *right, const char *top, const char *bottom); +GLuint CreateTextureFromFile(const char*filePath); \ No newline at end of file