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.

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