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