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.
 
 
 

198 lines
4.9 KiB

#include "misc.h"
#include "FreeImage.h"
#include <stdio.h>
#pragma comment(lib,"FreeImage.lib")
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void * data)
{
GLuint object;
glGenBuffers(1, &object);
glBindBuffer(bufferType, object);
glBufferData(bufferType, size, data, usage);
glBindBuffer(bufferType, 0);
return object;
}
char* LoadFileContent(const char *path) {
FILE* pFile = fopen(path, "rb");
if (pFile) {
fseek(pFile, 0, SEEK_END);
int nLen = ftell(pFile);
char* buffer = nullptr;
if (nLen != 0) {
buffer = new char[nLen + 1];
rewind(pFile);
fread(buffer, nLen, 1, pFile);
buffer[nLen] = '\0';
}
else {
printf("load file %s fail, content is 0\n", path);
}
fclose(pFile);
return buffer;
}
else {
printf("open file %s fail\n", path);
}
fclose(pFile);
return nullptr;
}
GLuint CompileShader(GLenum shaderType, const char * shaderPath)
{
//创建shader
GLuint shader = glCreateShader(shaderType);
if (shader == 0) {
printf("glCreateShader false\n");
return 0;
}
//读取shader代码
const char* shaderCode = LoadFileContent(shaderPath);
if (shaderCode == nullptr) {
printf("load shader code from file: %s false\n", shaderPath);
return 0;
}
//把shader代码 从内存传到显存
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 is : %s \n shader code :\n %s \n ", szLog, shaderCode);
glDeleteShader(shader);
return 0;
}
return shader;
}
/**
* 创建一个GPU程序
*/
GLuint CreateGPUProgram(const char* vsShaderPath, const char* fsShaderPath) {
GLuint vsShader = CompileShader(GL_VERTEX_SHADER,vsShaderPath);
GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER,fsShaderPath);
//创建program
GLuint program = glCreateProgram();
//绑定shader
glAttachShader(program, vsShader);
glAttachShader(program, fsShader);
//连接
glLinkProgram(program);
//解绑shader
glDetachShader(program, vsShader);
glDetachShader(program, fsShader);
//删除shader
glDeleteShader(vsShader);
glDeleteShader(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 CPU program fail error %s\n", log);
glDeleteProgram(program);
program = 0;
}
return program;
}
GLuint CreateTextureFromBMP(const char * imagePath)
{
unsigned char* imgData = (unsigned char*)LoadFileContent(imagePath);
if (*((unsigned short*)imgData) != 0x4D42) {
printf("cannot decode %s\n", imagePath);
return 0;
}
//decode bmp
int pixelDataOffset = *((int*)(imgData + 10));
int width = *((int*)(imgData + 18));
int height = *((int*)(imgData + 22));
unsigned char* pixelData = imgData + pixelDataOffset;
//bgr 转 rgb
for (int i = 0; i < width * height * 3; i+=3) {
unsigned char tmp = pixelData[i + 2];
pixelData[i + 2] = pixelData[i + 0];
pixelData[i + 0] = tmp;
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
glBindTexture(GL_TEXTURE_2D, 0);
delete imgData;
return texture;
}
GLuint CreateTexture(int w, int h, const void* data, GLenum type)
{
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
GLuint CreateTextureFromFile(const char * imagePath)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(imagePath, 0);
if (fifmt == FIF_UNKNOWN)
{
printf("File %s not found! ", imagePath);
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, imagePath, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
GLuint res = CreateTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}