Files
SWBF2-Classic-Msh-Viewer/MshViewer/Source/OpenGlController.cpp
Anakin a875820f48 removed unused files,
removed unused functions,
removed unused variables,
reduced dynamic stack memory (there was too much allocated),
moved some code around into better place,
implemented destructor (there is still a std::_face_node left on the stack when the program is done),
2016-10-31 16:19:12 +01:00

405 lines
9.2 KiB
C++

#include <gl\glew.h>
#include <gl\glfw3.h>
#include <Windows.h>
#include "OpenGLController.h"
#include "callback.h"
#include <glm\gtc\matrix_transform.hpp>
#include "shader.hpp"
#include "Texture.h"
#include <iostream>
#define VERTEX_SHADER "Shader/VertexTextureShader.mv2shdr"
#define FRAGMENT_SHADER "Shader/FragmentTextureShader.mv2shdr"
//#define TEXTURE_NAME "Textures/texture32R.tga"
/////////////////////////////////////////////////////////////////////////
// public constructor/destructor
OpenGLController* OpenGLController::getInstance(int oglMajor, int oglMinor)
{
static OpenGLController *instace = new OpenGLController(oglMajor, oglMinor);
return instace;
}
OpenGLController::~OpenGLController()
{
glDeleteBuffers(1, &gluiUVBufferID);
glDeleteBuffers(1, &gluiVertexBufferID);
glDeleteVertexArrays(1, &gluiVertexArrayID);
glDeleteProgram(gluiShaderPrgmID);
glDeleteTextures(1, &gluiSamplerID);
glfwTerminate();
while (!vModels.empty())
{
Modl* cursor = vModels.back();
vModels.pop_back();
delete cursor->uv;
delete cursor->mesh;
delete cursor->vertex;
delete cursor;
}
}
/////////////////////////////////////////////////////////////////////////
// private constructor
OpenGLController::OpenGLController(int oglMajor, int oglMinor)
{
// init variables
initDefault();
iOglMajorVersion = oglMajor;
iOglMinorVersion = oglMinor;
// run OGL
processInit();
}
/////////////////////////////////////////////////////////////////////////
// private functions
void OpenGLController::initDefault()
{
pWindow = NULL;
sWindowName = "MeshViewer 2.0 pre-alpha";
iWidth = 640;
iHeight = 480;
iAntiAliasingLevel = 4;
gluiUVBufferID = 0;
gluiTextureID = 0;
gluiShaderPrgmID = 0;
gluiSamplerID = 0;
gluiMatrixID = 0;
fRotationX = 0;
fRotationY = 0;
fRotationZ = 0;
dTranslationX = 0;
dTranslationY = 0;
dTranslationZ = 5;
fFOV = 45.0f;
fMinView = 0.1f;
fMaxView = 100.0f;
}
void OpenGLController::processInit()
{
startGLFW();
createWindow();
startGLEW();
setCallbackFunctions();
// set background color
glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f);
// enable z-order
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// draw vertics only from one side
glEnable(GL_CULL_FACE);
// generate stuff
glGenVertexArrays(1, &gluiVertexArrayID);
glBindVertexArray(gluiVertexArrayID);
glGenBuffers(1, &gluiVertexBufferID);
glGenBuffers(1, &gluiUVBufferID);
// get the painter ready
try
{
gluiShaderPrgmID = LoadShaders(VERTEX_SHADER, FRAGMENT_SHADER);
}
catch (std::invalid_argument e)
{
MessageBox(NULL, e.what(), "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
exit(1);
}
gluiMatrixID = glGetUniformLocation(gluiShaderPrgmID, "MVP");
gluiSamplerID = glGetUniformLocation(gluiShaderPrgmID, "textureSampler");
}
void OpenGLController::startGLFW()
{
if (!glfwInit())
{
MessageBox(NULL, "Failed to initialize GLFW", "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
exit(0);
}
glfwWindowHint(GLFW_SAMPLES, iAntiAliasingLevel);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, iOglMajorVersion);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, iOglMinorVersion);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
void OpenGLController::createWindow()
{
pWindow = glfwCreateWindow(iWidth, iHeight, sWindowName.c_str(), NULL, NULL);
if (pWindow == NULL)
{
std::string message = "Your GPU does not support OpenGL ";
message += iOglMajorVersion;
message += ".";
message += iOglMinorVersion;
message += "\nTry to use older version";
MessageBox(NULL, message.c_str(), "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
glfwTerminate();
exit(0);
}
glfwSetWindowUserPointer(pWindow, this);
glfwMakeContextCurrent(pWindow);
}
void OpenGLController::startGLEW()
{
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
MessageBox(NULL, "Failed to initialize GLEW", "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
glfwTerminate();
exit(0);
}
}
void OpenGLController::setCallbackFunctions()
{
glfwSetMouseButtonCallback(pWindow, mouseButton);
glfwSetCursorPosCallback(pWindow, mouseMove);
glfwSetWindowSizeCallback(pWindow, windowResize);
glfwSetScrollCallback(pWindow, mouseWheel);
glfwSetKeyCallback(pWindow, keyPress);
}
glm::mat4 OpenGLController::getMVPMatrix()
{
// Projection
glm::mat4 m4x4Projection = glm::perspective(fFOV, float(iWidth) / float(iHeight), fMinView, fMaxView);
// View
glm::mat4 m4x4View = glm::lookAt(
glm::vec3(dTranslationX, dTranslationY, dTranslationZ),
glm::vec3(dTranslationX, dTranslationY, dTranslationZ - 1),
glm::vec3(0, 1, 0)
);
// Model
//TODO for all
glm::mat4 m4x4Model = vModels.front()->m4x4Translation;
// User controlled rotation
glm::mat4 m4x4ModelRot = glm::mat4(1.0f);
m4x4ModelRot = glm::rotate(m4x4ModelRot, fRotationX, glm::vec3(1, 0, 0));
m4x4ModelRot = glm::rotate(m4x4ModelRot, fRotationY, glm::vec3(0, 1, 0));
m4x4ModelRot = glm::rotate(m4x4ModelRot, fRotationZ, glm::vec3(0, 0, 1));
// Return MVP
return m4x4Projection * m4x4View * m4x4ModelRot * m4x4Model;
}
/////////////////////////////////////////////////////////////////////////
// public getter
GLFWwindow * OpenGLController::getWindow() const
{
return pWindow;
}
/////////////////////////////////////////////////////////////////////////
// public functions
void OpenGLController::resize(int width, int height)
{
iWidth = width;
iHeight = height;
}
void OpenGLController::addRotX(float value)
{
fRotationX += value;
}
void OpenGLController::addRotY(float value)
{
fRotationY += value;
}
void OpenGLController::addTransX(double value)
{
dTranslationX += value;
}
void OpenGLController::addTransY(double value)
{
dTranslationY += value;
}
void OpenGLController::addTransZ(double value)
{
dTranslationZ += value;
}
void OpenGLController::updateScene()
{
// get new matrices
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// use shader prgm
glUseProgram(gluiShaderPrgmID);
// tell shader transformation
glUniformMatrix4fv(gluiMatrixID, 1, GL_FALSE, &getMVPMatrix()[0][0]);
// bind texture in texture unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gluiTextureID);
// tell sampler to use texture unit 0
glUniform1i(gluiSamplerID, 0);
// open attribute position
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, gluiVertexBufferID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// open attribute uv
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, gluiUVBufferID);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
//draw objects
//// TODO: for all
glDrawArrays(GL_TRIANGLES, 0, vModels.front()->meshSize);
//close attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(pWindow);
glfwPollEvents();
}
void OpenGLController::loadMsh(const char * path)
{
// get data
try
{
Object obj(path);
vModels = obj.getModels();
}
catch (std::invalid_argument e)
{
MessageBox(NULL, e.what(), "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
exit(1);
}
glGenTextures(1, &gluiTextureID);
glBindTexture(GL_TEXTURE_2D, gluiTextureID);
try
{
////TODO: for all
if (vModels.front()->texture == "")
throw std::invalid_argument("no texture name");
std::string tempPath = path;
while (tempPath.back() != '/' && tempPath.back() != '\\')
tempPath.pop_back();
TextureTGA tempTex(std::string(tempPath + vModels.front()->texture).c_str());
glTexImage2D(GL_TEXTURE_2D,
0,
tempTex.hasAlpha() ? GL_RGBA : GL_RGB,
tempTex.getWidth(),
tempTex.getHeight(),
0, tempTex.hasAlpha() ? GL_BGRA : GL_BGR,
GL_UNSIGNED_BYTE,
tempTex.getData().data()
);
}
catch (std::invalid_argument e)
{
GLubyte solidColor[4] = { 255, 0, 0, 255};
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
1,
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
(const GLvoid*)solidColor
);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindBuffer(GL_ARRAY_BUFFER, gluiVertexBufferID);
////TODO: for all
std::vector<GLfloat> tempVertex;
for (unsigned int i = 0; i < vModels.front()->meshSize; i++)
{
tempVertex.push_back((GLfloat)vModels.front()->vertex[vModels.front()->mesh[i] * 3]);
tempVertex.push_back((GLfloat)vModels.front()->vertex[vModels.front()->mesh[i] * 3 + 1]);
tempVertex.push_back((GLfloat)vModels.front()->vertex[vModels.front()->mesh[i] * 3 + 2]);
}
glBufferData(
GL_ARRAY_BUFFER,
sizeof(tempVertex) * tempVertex.size(),
tempVertex.data(),
GL_STATIC_DRAW
);
////TODO: for all
std::vector<GLfloat> tempUV;
if (vModels.front()->uv == NULL)
{
for (unsigned int i = 0; i < vModels.front()->meshSize; i++)
tempUV.push_back(1.0);
}
else
{
for (unsigned int i = 0; i < vModels.front()->meshSize; i++)
{
tempUV.push_back((GLfloat)vModels.front()->uv[vModels.front()->mesh[i] * 2]);
tempUV.push_back((GLfloat)vModels.front()->uv[vModels.front()->mesh[i] * 2 + 1]);
}
}
glBindBuffer(GL_ARRAY_BUFFER, gluiUVBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(tempUV) * tempUV.size(),
tempUV.data(),
GL_STATIC_DRAW
);
}