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.

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