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.

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