#pragma once
#include "glad/glad.h"
#include "KHR/khrplatform.h"
#include "gl/GL.h"
#include "assert.h"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
class GiShaderProgram
{
public:
GiShaderProgram();
GiShaderProgram(const char* vertexPath, const char* fragmentPath);
~GiShaderProgram();
void Release();
void use();
void SetShaderPath(const char* vertexPath, const char* fragmentPath);
void setBool(const std::string& name, bool value) const;
void setInt(const std::string& name, int value) const;
void setFloat(const std::string& name, float value) const;
void setMat4d(const std::string& name, double* pMat) const;
void setMat4f(const std::string& name, float* pMat) const;
void setVec4f(const std::string& name, float* pvec) const;
void setVec3f(const std::string& name, float* pvec) const;
void setVec3f(const std::string& name, float para1, float para2, float para3) const;
private:
void checkCompileErrors(unsigned int shader, std::string type);
unsigned int ID;
};
class GiVAO
{
public:
GiVAO();
GiVAO(double *pPts, size_t iNum, int ipara1, int ipara2, int ipara3);
GiVAO(float* pPts, size_t iNum, int ipara1, int ipara2, int ipara3);
~GiVAO();
void SetPts(double* pPts, size_t iNum, int ipara1, int ipara2, int ipara3);
void SetPts(float* pPts, size_t iNum, int ipara1, int ipara2, int ipara3);
void Use();
void DrawArrays(int type, int iFirst, int iCount);
private:
unsigned int ID;
unsigned int iVBO;
};
class GiFrameBuffer
{
public:
GiFrameBuffer();
GiFrameBuffer(const unsigned int iWidth, const unsigned int iHight);
~GiFrameBuffer();
void Use();
void ResetRect(const unsigned int iWidth, const unsigned int iHight);
unsigned int GetTextureID();
private:
unsigned int ID;
unsigned int iTexturebuffer;
unsigned int iRbo;
};
class GiTexture
{
public:
GiTexture();
GiTexture(const char* vertexPath);
GiTexture(GLbyte* pDIB, int iWidth, int iHeight, int iFormat, bool bIsLinear = true);
~GiTexture();
void Release();
void use();
unsigned int GetID();
private:
unsigned int loadTexture(char const* path);
unsigned int ID;
};
static GLenum CheckGLError()
{
GLenum errorCode;
while ((errorCode = glGetError()) != GL_NO_ERROR)
{
std::string error;
switch (errorCode)
{
case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;
case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;
case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
}
assert(false);
}
return errorCode;
}
#include "GiShaderProgram.h"
#include "stb_image.h"
GiShaderProgram::GiShaderProgram()
{
ID = 0;
}
GiShaderProgram::GiShaderProgram(const char* vertexPath, const char* fragmentPath)
{
ID = 0;
SetShaderPath(vertexPath, fragmentPath);
}
GiShaderProgram::~GiShaderProgram()
{
if (ID != 0)
{
glDeleteProgram(ID);
CheckGLError();
ID = 0;
}
}
void GiShaderProgram::Release()
{
if (ID != 0)
{
glDeleteProgram(ID);
CheckGLError();
ID = 0;
}
}
void GiShaderProgram::use()
{
glUseProgram(ID);
CheckGLError();
}
void GiShaderProgram::SetShaderPath(const char* vertexPath, const char* fragmentPath)
{
if (ID != 0)
{
glDeleteProgram(ID);
CheckGLError();
ID = 0;
}
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure& e)
{
assert(false);
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void GiShaderProgram::setBool(const std::string& name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
CheckGLError();
}
void GiShaderProgram::setInt(const std::string& name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
CheckGLError();
}
void GiShaderProgram::setFloat(const std::string& name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
CheckGLError();
}
void GiShaderProgram::setMat4d(const std::string& name, double* pMat) const
{
float pData[16];
for (int i = 0; i < 16; i++)
pData[i] = (float)pMat[i];
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, pData);
CheckGLError();
}
void GiShaderProgram::setMat4f(const std::string& name, float* pMat) const
{
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, pMat);
CheckGLError();
}
void GiShaderProgram::setVec4f(const std::string& name, float* pvec) const
{
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, pvec);
CheckGLError();
}
void GiShaderProgram::setVec3f(const std::string& name, float* pvec) const
{
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, pvec);
CheckGLError();
}
void GiShaderProgram::setVec3f(const std::string& name, float para1, float para2, float para3) const
{
float pPts[3] = {
para1,para2,para3 };
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, pPts);
CheckGLError();
}
void GiShaderProgram::checkCompileErrors(unsigned int shader, std::string type)
{
int success;
char infoLog[1024];
if (type != "PROGRAM")
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << infoLog << std::endl;
assert(false);
}
}
else
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << infoLog << std::endl;
assert(false);
}
}
}
GiVAO::GiVAO()
{
ID = 0;
}
GiVAO::GiVAO(double* pPts, size_t iNum, int ipara1, int ipara2, int ipara3)
{
glGenVertexArrays(1, &ID);
glGenBuffers(1, &iVBO);
SetPts(pPts, iNum, ipara1, ipara2, ipara3);
}
GiVAO::GiVAO(float* pPts, size_t iNum, int ipara1, int ipara2, int ipara3)
{
glGenVertexArrays(1, &ID);
glGenBuffers(1, &iVBO);
SetPts(pPts, iNum, ipara1, ipara2, ipara3);
}
GiVAO::~GiVAO()
{
if (ID != 0)
{
glDeleteBuffers(1, &iVBO);
glDeleteVertexArrays(1, &ID);
CheckGLError();
ID = 0;
}
}
void GiVAO::SetPts(float* pPts, size_t iNum, int ipara1, int ipara2, int ipara3)
{
if (ID == 0)
{
glGenVertexArrays(1, &ID);
glGenBuffers(1, &iVBO);
}
glBindVertexArray(ID);
glBindBuffer(GL_ARRAY_BUFFER, iVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * iNum, pPts, GL_STATIC_DRAW);
CheckGLError();
if (ipara1 > 0)
{
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ipara1, GL_FLOAT, GL_FALSE, (ipara1 + ipara2 + ipara3) * sizeof(float), (void*)0);
}
if (ipara2 > 0)
{
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, ipara2, GL_FLOAT, GL_FALSE, (ipara1 + ipara2 + ipara3) * sizeof(float), (void*)(ipara1 * sizeof(float)));
}
if (ipara3 > 0)
{
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, ipara3, GL_FLOAT, GL_FALSE, (ipara1 + ipara2 + ipara3) * sizeof(float), (void*)((ipara1 + ipara2) * sizeof(float)));
}
glBindVertexArray(0);
}
void GiVAO::SetPts(double* pPts, size_t iNum, int ipara1, int ipara2, int ipara3)
{
if (ID == 0)
{
glGenVertexArrays(1, &ID);
glGenBuffers(1, &iVBO);
}
glBindVertexArray(ID);
glBindBuffer(GL_ARRAY_BUFFER, iVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(double) * iNum, pPts, GL_STATIC_DRAW);
if (ipara1 > 0)
{
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ipara1, GL_DOUBLE, GL_FALSE, (ipara1 + ipara2 + ipara3) * sizeof(double), (void*)0);
}
if (ipara2 > 0)
{
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, ipara2, GL_DOUBLE, GL_FALSE, (ipara1 + ipara2 + ipara3) * sizeof(double), (void*)(ipara1 * sizeof(double)));
}
if (ipara3 > 0)
{
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, ipara3, GL_DOUBL