You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
8.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #include "misc.h"
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include "FreeImage.h"
  5. #pragma comment(lib,"FreeImage.lib")
  6. GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void * data)
  7. {
  8. GLuint object;
  9. glGenBuffers(1, &object);
  10. glBindBuffer(bufferType, object);
  11. glBufferData(bufferType, size, data, usage);
  12. glBindBuffer(bufferType, 0);
  13. return object;
  14. }
  15. char* LoadFileContent(const char *path) {
  16. FILE* pFile = fopen(path, "rb");
  17. if (pFile) {
  18. fseek(pFile, 0, SEEK_END);
  19. int nLen = ftell(pFile);
  20. char* buffer = nullptr;
  21. if (nLen != 0) {
  22. buffer = new char[nLen + 1];
  23. rewind(pFile);
  24. fread(buffer, nLen, 1, pFile);
  25. buffer[nLen] = '\0';
  26. }
  27. else {
  28. printf("load file %s fail, content is 0\n", path);
  29. }
  30. fclose(pFile);
  31. return buffer;
  32. }
  33. else {
  34. printf("open file %s fail\n", path);
  35. }
  36. fclose(pFile);
  37. return nullptr;
  38. }
  39. GLuint CompileShader(GLenum shaderType, const char * shaderPath)
  40. {
  41. //����shader
  42. GLuint shader = glCreateShader(shaderType);
  43. if (shader == 0) {
  44. printf("glCreateShader false\n");
  45. return 0;
  46. }
  47. //��ȡshader����
  48. const char* shaderCode = LoadFileContent(shaderPath);
  49. if (shaderCode == nullptr) {
  50. printf("load shader code from file: %s false\n", shaderPath);
  51. return 0;
  52. }
  53. //��shader���� ���ڴ洫���Դ�
  54. glShaderSource(shader, 1, &shaderCode, nullptr);
  55. glCompileShader(shader);
  56. GLint compileResult = GL_TRUE;
  57. glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
  58. if (compileResult == GL_FALSE) {
  59. char szLog[1024] = { 0 };
  60. GLsizei logLen = 0;//ʵ�ʴ�����־����
  61. glGetShaderInfoLog(shader, 1024, &logLen, szLog);
  62. printf("Compile shader fail error log is : %s \n shader code :\n %s \n ", szLog, shaderCode);
  63. glDeleteShader(shader);
  64. return 0;
  65. }
  66. return shader;
  67. }
  68. /**
  69. * һGPU
  70. */
  71. GLuint CreateGPUProgram(const char* vsShaderPath, const char* fsShaderPath) {
  72. GLuint vsShader = CompileShader(GL_VERTEX_SHADER,vsShaderPath);
  73. GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER,fsShaderPath);
  74. //����program
  75. GLuint program = glCreateProgram();
  76. //����shader
  77. glAttachShader(program, vsShader);
  78. glAttachShader(program, fsShader);
  79. //����
  80. glLinkProgram(program);
  81. //����shader
  82. glDetachShader(program, vsShader);
  83. glDetachShader(program, fsShader);
  84. //ɾ��shader
  85. glDeleteShader(vsShader);
  86. glDeleteShader(fsShader);
  87. //��������
  88. GLint nResult;
  89. glGetProgramiv(program, GL_LINK_STATUS, &nResult);
  90. if (nResult == GL_FALSE) {
  91. char log[1024] = { 0 };
  92. GLsizei writed = 0;
  93. glGetProgramInfoLog(program, 1024, &writed, log);
  94. printf("Create CPU program fail error %s\n", log);
  95. glDeleteProgram(program);
  96. program = 0;
  97. }
  98. return program;
  99. }
  100. static unsigned char* DecodeBMPData(unsigned char* imgData, int &width, int &height) {
  101. //decode bmp
  102. int pixelDataOffset = *((int*)(imgData + 10));
  103. width = *((int*)(imgData + 18));
  104. height = *((int*)(imgData + 22));
  105. unsigned char* pixelData = imgData + pixelDataOffset;
  106. //bgr ת rgb
  107. for (int i = 0; i < width * height * 3; i += 3) {
  108. unsigned char tmp = pixelData[i + 2];
  109. pixelData[i + 2] = pixelData[i + 0];
  110. pixelData[i + 0] = tmp;
  111. }
  112. return pixelData;
  113. }
  114. GLuint CreateTextureFromBMP(const char * imagePath)
  115. {
  116. unsigned char* imgData = (unsigned char*)LoadFileContent(imagePath);
  117. if (*((unsigned short*)imgData) != 0x4D42) {
  118. printf("cannot decode %s\n", imagePath);
  119. return 0;
  120. }
  121. int width, height;
  122. unsigned char* pixelData = DecodeBMPData(imgData, width, height);
  123. GLuint texture;
  124. glGenTextures(1, &texture);
  125. glBindTexture(GL_TEXTURE_2D, texture);
  126. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  127. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  128. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  129. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  130. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
  131. glBindTexture(GL_TEXTURE_2D, 0);
  132. delete imgData;
  133. return texture;
  134. }
  135. static GLuint CreateTexture(int w, int h, const void* data, GLenum type)
  136. {
  137. GLuint texId;
  138. glGenTextures(1, &texId);
  139. glBindTexture(GL_TEXTURE_2D, texId);
  140. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  141. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  142. glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
  143. return texId;
  144. }
  145. GLuint CreateTextureFromFile(const char * imagePath)
  146. {
  147. //1 ��ȡͼƬ��ʽ
  148. FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(imagePath, 0);
  149. if (fifmt == FIF_UNKNOWN)
  150. {
  151. printf("File %s not found! ", imagePath);
  152. return 0;
  153. }
  154. //2 ����ͼƬ
  155. FIBITMAP *dib = FreeImage_Load(fifmt, imagePath, 0);
  156. FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
  157. //! ��ȡ����ָ��
  158. FIBITMAP* temp = dib;
  159. dib = FreeImage_ConvertTo32Bits(dib);
  160. FreeImage_Unload(temp);
  161. BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
  162. int width = FreeImage_GetWidth(dib);
  163. int height = FreeImage_GetHeight(dib);
  164. for (int i = 0; i < width * height * 4; i += 4)
  165. {
  166. BYTE temp = pixels[i];
  167. pixels[i] = pixels[i + 2];
  168. pixels[i + 2] = temp;
  169. }
  170. GLuint res = CreateTexture(width, height, pixels, GL_RGBA);
  171. FreeImage_Unload(dib);
  172. return res;
  173. }
  174. const unsigned long FORMAT_DXT1 = 0x31545844l; // ������ʵDXT1������ascii��
  175. static unsigned char* DecodeDXT1Data(unsigned char* imgData, int &width, int &height, int &pixelSize) {
  176. height = *((int*)(imgData + sizeof(unsigned long) * 3));
  177. width = *((int*)(imgData + sizeof(unsigned long) * 4));
  178. pixelSize = *((int*)(imgData + sizeof(unsigned long) * 5));
  179. unsigned long compressFormat;
  180. compressFormat = *((int*)(imgData + sizeof(unsigned long) * 21));
  181. switch (compressFormat) {
  182. case FORMAT_DXT1:
  183. printf("decode dxt1\n");
  184. break;
  185. }
  186. unsigned char* pixelData = new unsigned char[pixelSize];
  187. memcpy(pixelData, imgData + sizeof(unsigned long) * 32, pixelSize);
  188. return pixelData;
  189. }
  190. GLuint CreateTextureFromDds(const char * imagePath)
  191. {
  192. unsigned char* imgData = (unsigned char*)LoadFileContent(imagePath);
  193. if (memcmp(imgData, "DDS ", 4) != 0) {
  194. printf("cannot decode %s\n", imagePath);
  195. return 0;
  196. }
  197. int width, height;
  198. int pixelSize = 0;
  199. unsigned char* pixelData = DecodeDXT1Data(imgData, width, height, pixelSize);
  200. GLuint texture;
  201. glGenTextures(1, &texture);
  202. glBindTexture(GL_TEXTURE_2D, texture);
  203. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  204. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  205. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  206. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  207. //GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
  208. glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, pixelSize, pixelData);
  209. glBindTexture(GL_TEXTURE_2D, 0);
  210. delete imgData;
  211. return texture;
  212. }
  213. void SaveImage(const char*imagePath, unsigned char*imgData, int width, int height)
  214. {
  215. FILE*pFile = fopen(imagePath, "wb");
  216. if (pFile)
  217. {
  218. BITMAPFILEHEADER bfh;
  219. memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
  220. bfh.bfType = 0x4D42;
  221. bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + width*height * 3;
  222. bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  223. fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, pFile);
  224. BITMAPINFOHEADER bih;
  225. memset(&bih, 0, sizeof(BITMAPINFOHEADER));
  226. bih.biWidth = width;
  227. bih.biHeight = height;
  228. bih.biBitCount = 24;
  229. bih.biSize = sizeof(BITMAPINFOHEADER);
  230. fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, pFile);
  231. unsigned char temp = 0;
  232. for (int i = 0; i<width*height * 3; i += 3)
  233. {
  234. temp = imgData[i + 2];
  235. imgData[i + 2] = imgData[i];
  236. imgData[i] = temp;
  237. }
  238. fwrite(imgData, 1, width*height * 3, pFile);
  239. fclose(pFile);
  240. }
  241. }
  242. void CheckGLError(const char*file, int line)
  243. {
  244. GLenum error = glGetError();
  245. if (error != GL_NO_ERROR)
  246. {
  247. switch (error)
  248. {
  249. case GL_INVALID_ENUM:
  250. printf("GL Error GL_INVALID_ENUM %s : %d\n", file, line);
  251. break;
  252. case GL_INVALID_VALUE:
  253. printf("GL Error GL_INVALID_VALUE %s : %d\n", file, line);
  254. break;
  255. case GL_INVALID_OPERATION:
  256. printf("GL Error GL_INVALID_OPERATION %s : %d\n", file, line);
  257. break;
  258. case GL_STACK_OVERFLOW:
  259. printf("GL Error GL_STACK_OVERFLOW %s : %d\n", file, line);
  260. break;
  261. case GL_STACK_UNDERFLOW:
  262. printf("GL Error GL_STACK_UNDERFLOW %s : %d\n", file, line);
  263. break;
  264. case GL_OUT_OF_MEMORY:
  265. printf("GL Error GL_OUT_OF_MEMORY %s : %d\n", file, line);
  266. break;
  267. default:
  268. printf("GL Error 0x%x %s : %d\n", error, file, line);
  269. break;
  270. }
  271. }
  272. }