Add simple camera and input handling classes
This commit is contained in:
parent
4c0a3d37d7
commit
25f1002ec1
|
@ -3,3 +3,11 @@ An idea for a 3D game engine that renders voxel planets, puts them into orbits a
|
|||
|
||||
## The Goal
|
||||
The goal of this application is to make a scriptable voxel planets engine to use in the making of games.
|
||||
|
||||
## Compile
|
||||
Currently only tested on Linux.
|
||||
```
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
|
|
@ -52,10 +52,69 @@ void Application::Initialize()
|
|||
// Initialize GLEW
|
||||
glewInit();
|
||||
|
||||
// Create camera
|
||||
m_camera = new Camera();
|
||||
|
||||
// Run the engine
|
||||
Run();
|
||||
}
|
||||
|
||||
void Application::HandleEvents()
|
||||
{
|
||||
/* Update the input manager */
|
||||
Input::getInstance().Flush();
|
||||
|
||||
/* Check for events */
|
||||
SDL_Event e;
|
||||
while ( SDL_PollEvent(&e) )
|
||||
{
|
||||
switch(e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
Exit();
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
Input::getInstance().pressKey(e.key.keysym.sym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
Input::getInstance().releaseKey(e.key.keysym.sym);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
Input::getInstance().setMouseCoords(e.motion.x, e.motion.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
Input::getInstance().pressKey(e.button.button);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
Input::getInstance().releaseKey(e.button.button);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
Input::getInstance().setMouseWheel(e.wheel.y, e.wheel.x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec2 mousepos = Input::getInstance().getMouseCoords();
|
||||
|
||||
if(Input::getInstance().isKeyDown(SDLK_w))
|
||||
m_camera->ProcessKeyboard(Camera_Movement::FORWARD, 0.01f);
|
||||
|
||||
if(Input::getInstance().isKeyDown(SDLK_s))
|
||||
m_camera->ProcessKeyboard(Camera_Movement::BACKWARD, 0.01f);
|
||||
|
||||
if(Input::getInstance().isKeyDown(SDLK_d))
|
||||
m_camera->ProcessKeyboard(Camera_Movement::RIGHT, 0.01f);
|
||||
|
||||
if(Input::getInstance().isKeyDown(SDLK_a))
|
||||
m_camera->ProcessKeyboard(Camera_Movement::LEFT, 0.01f);
|
||||
|
||||
m_camera->ProcessMouseScroll((float) Input::getInstance().getMouseWheelVertical() / 10.0f);
|
||||
|
||||
if(Input::getInstance().isKeyPressed(SDL_BUTTON_LEFT))
|
||||
std::cout << "mX: " << mousepos.x << " mY: " << mousepos.y << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void Application::Run()
|
||||
{
|
||||
m_run = true;
|
||||
|
@ -66,14 +125,8 @@ void Application::Run()
|
|||
{
|
||||
last_ = now_;
|
||||
now_ = SDL_GetPerformanceCounter();
|
||||
while(SDL_PollEvent(&m_event) != 0)
|
||||
{
|
||||
// Close button is pressed
|
||||
if(m_event.type == SDL_QUIT)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
}
|
||||
|
||||
HandleEvents();
|
||||
|
||||
deltaTime_ = ((now_ - last_) / (double)SDL_GetPerformanceFrequency());
|
||||
|
||||
|
@ -105,7 +158,7 @@ void Application::Run()
|
|||
|
||||
void Application::Update(GLfloat dtime)
|
||||
{
|
||||
log_info(std::to_string(dtime));
|
||||
|
||||
}
|
||||
|
||||
void Application::Render()
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define __APPLICATION_H__
|
||||
#include "util/Common.h"
|
||||
#include "util/Singleton.h"
|
||||
#include "Camera.h"
|
||||
#include "Input.h"
|
||||
|
||||
class Application : public Singleton<Application>
|
||||
{
|
||||
|
@ -14,6 +16,7 @@ class Application : public Singleton<Application>
|
|||
|
||||
friend class Singleton<Application>;
|
||||
private:
|
||||
Camera* m_camera;
|
||||
SDL_Window* m_window;
|
||||
SDL_Event m_event;
|
||||
SDL_GLContext m_glContext;
|
||||
|
@ -24,6 +27,7 @@ class Application : public Singleton<Application>
|
|||
|
||||
bool m_run;
|
||||
|
||||
void HandleEvents();
|
||||
void Run();
|
||||
void Render();
|
||||
void Update(GLfloat dtime);
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
#include "Camera.h"
|
||||
|
||||
// TODO: use Roll
|
||||
|
||||
Camera::Camera(glm::vec3 position, glm::vec3 up, GLfloat yaw, GLfloat pitch, GLfloat roll) :
|
||||
m_front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||
m_movementSpeed(SPEED),
|
||||
m_mouseSensitivity(SENSITIVTY),
|
||||
m_zoom(ZOOM)
|
||||
{
|
||||
m_position = position;
|
||||
m_worldUp = up;
|
||||
m_yaw = yaw;
|
||||
m_pitch = pitch;
|
||||
m_roll = roll;
|
||||
updateCameraVectors();
|
||||
}
|
||||
|
||||
Camera::Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch, GLfloat roll) :
|
||||
m_front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||
m_movementSpeed(SPEED),
|
||||
m_mouseSensitivity(SENSITIVTY),
|
||||
m_zoom(ZOOM)
|
||||
{
|
||||
m_position = glm::vec3(posX, posY, posZ);
|
||||
m_worldUp = glm::vec3(upX, upY, upZ);
|
||||
m_yaw = yaw;
|
||||
m_pitch = pitch;
|
||||
m_roll = roll;
|
||||
updateCameraVectors();
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getViewMatrix()
|
||||
{
|
||||
return glm::lookAt(m_position, m_position + m_front, m_up);
|
||||
}
|
||||
|
||||
void Camera::ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime)
|
||||
{
|
||||
GLfloat velocity = m_movementSpeed * deltaTime;
|
||||
|
||||
if (direction == FORWARD)
|
||||
m_position += m_front * velocity;
|
||||
if (direction == BACKWARD)
|
||||
m_position -= m_front * velocity;
|
||||
if (direction == LEFT)
|
||||
m_position -= m_right * velocity;
|
||||
if (direction == RIGHT)
|
||||
m_position += m_right * velocity;
|
||||
}
|
||||
|
||||
void Camera::ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true)
|
||||
{
|
||||
xoffset *= m_mouseSensitivity;
|
||||
yoffset *= m_mouseSensitivity;
|
||||
|
||||
m_yaw += xoffset;
|
||||
m_pitch += yoffset;
|
||||
|
||||
// Make sure that when pitch is out of bounds, screen doesn't get flipped
|
||||
if (constrainPitch)
|
||||
{
|
||||
if (m_pitch > 89.0f)
|
||||
{
|
||||
m_pitch = 89.0f;
|
||||
}
|
||||
|
||||
if (m_pitch < -89.0f)
|
||||
{
|
||||
m_pitch = -89.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Update Front, Right and Up Vectors using the updated Eular angles
|
||||
updateCameraVectors();
|
||||
}
|
||||
|
||||
void Camera::ProcessMouseScroll(GLfloat yoffset)
|
||||
{
|
||||
if (m_zoom >= 44.0f && m_zoom <= 45.0f)
|
||||
{
|
||||
m_zoom -= yoffset;
|
||||
}
|
||||
|
||||
if (m_zoom <= 44.0f)
|
||||
{
|
||||
m_zoom = 44.0f;
|
||||
}
|
||||
|
||||
if (m_zoom >= 45.0f)
|
||||
{
|
||||
m_zoom = 45.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::updateCameraVectors()
|
||||
{
|
||||
// Calculate the new Front vector
|
||||
glm::vec3 front;
|
||||
front.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
|
||||
front.y = sin(glm::radians(m_pitch));
|
||||
front.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
|
||||
m_front = glm::normalize(front);
|
||||
|
||||
// Also re-calculate the Right and Up vector
|
||||
// Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
||||
m_right = glm::normalize(glm::cross(m_front, m_worldUp));
|
||||
m_up = glm::normalize(glm::cross(m_right, m_front));
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef __CAMERA_H__
|
||||
#define __CAMERA_H__
|
||||
|
||||
#include "util/Common.h"
|
||||
|
||||
// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
|
||||
enum Camera_Movement {
|
||||
FORWARD,
|
||||
BACKWARD,
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
// Default camera values
|
||||
const GLfloat YAW = -90.0f;
|
||||
const GLfloat PITCH = 0.0f;
|
||||
const GLfloat ROLL = 0.0f;
|
||||
const GLfloat SPEED = 3.0f;
|
||||
const GLfloat SENSITIVTY = 0.25f;
|
||||
const GLfloat ZOOM = 45.0f;
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH, GLfloat roll = ROLL);
|
||||
Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch, GLfloat roll);
|
||||
~Camera();
|
||||
|
||||
glm::mat4 getViewMatrix();
|
||||
glm::vec3 getPosition() const { return m_position; }
|
||||
void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime);
|
||||
void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch);
|
||||
void ProcessMouseScroll(GLfloat yoffset);
|
||||
|
||||
GLfloat getFOV() const { return m_zoom; }
|
||||
private:
|
||||
glm::vec3 m_position;
|
||||
glm::vec3 m_front;
|
||||
glm::vec3 m_up;
|
||||
glm::vec3 m_right;
|
||||
glm::vec3 m_worldUp;
|
||||
|
||||
// Eular Angles
|
||||
GLfloat m_yaw;
|
||||
GLfloat m_pitch;
|
||||
GLfloat m_roll;
|
||||
|
||||
// Camera options
|
||||
GLfloat m_movementSpeed;
|
||||
GLfloat m_mouseSensitivity;
|
||||
GLfloat m_zoom;
|
||||
|
||||
void updateCameraVectors();
|
||||
};
|
||||
#endif // __CAMERA_H__
|
|
@ -0,0 +1,64 @@
|
|||
#include "Input.h"
|
||||
|
||||
// Remember previous positions
|
||||
void Input::Flush()
|
||||
{
|
||||
for(auto& it : m_keyMap)
|
||||
{
|
||||
m_oldKeyMap[it.first] = it.second;
|
||||
}
|
||||
|
||||
// Keep old mouse coordinates
|
||||
m_oldMouseCoords = m_mouseCoords;
|
||||
|
||||
// Reset the mouse wheel scroll, as we will ever only need it once.
|
||||
m_mwheelY = 0;
|
||||
m_mwheelX = 0;
|
||||
}
|
||||
|
||||
void Input::pressKey(unsigned int keyID)
|
||||
{
|
||||
m_keyMap[keyID] = true;
|
||||
}
|
||||
|
||||
void Input::releaseKey(unsigned int keyID)
|
||||
{
|
||||
m_keyMap[keyID] = false;
|
||||
}
|
||||
|
||||
void Input::setMouseCoords(float x, float y)
|
||||
{
|
||||
m_mouseCoords.x = x;
|
||||
m_mouseCoords.y = y;
|
||||
}
|
||||
|
||||
bool Input::isKeyDown(unsigned int keyID)
|
||||
{
|
||||
auto it = m_keyMap.find(keyID);
|
||||
if(it != m_keyMap.end())
|
||||
return it->second;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::wasKeyDown(unsigned int keyID)
|
||||
{
|
||||
auto it = m_oldKeyMap.find(keyID);
|
||||
if(it != m_oldKeyMap.end())
|
||||
return it->second;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::isKeyPressed(unsigned int keyID)
|
||||
{
|
||||
if(isKeyDown(keyID) == true && wasKeyDown(keyID) == false)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Input::setMouseWheel(int vert, int horiz)
|
||||
{
|
||||
m_mwheelY = vert;
|
||||
m_mwheelX = horiz;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __INPUT_H__
|
||||
#define __INPUT_H__
|
||||
|
||||
#include "util/Singleton.h"
|
||||
#include "util/Math3D.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class Input : public Singleton<Input>
|
||||
{
|
||||
public:
|
||||
void Flush();
|
||||
|
||||
void pressKey(unsigned int keyID);
|
||||
void releaseKey(unsigned int keyID);
|
||||
|
||||
void setMouseCoords(float x, float y);
|
||||
void setMouseWheel(int vert, int horiz);
|
||||
|
||||
bool isKeyDown(unsigned int keyID);
|
||||
bool isKeyPressed(unsigned int keyID);
|
||||
|
||||
glm::vec2 getMouseCoords() const { return m_mouseCoords; }
|
||||
glm::vec2 getOldMouseCoords() const { return m_oldMouseCoords; }
|
||||
|
||||
int getMouseWheelVertical() const { return m_mwheelY; }
|
||||
int getMouseWheelHorizontal() const { return m_mwheelX; }
|
||||
|
||||
friend class Singleton<Input>;
|
||||
private:
|
||||
bool wasKeyDown(unsigned int keyID);
|
||||
std::unordered_map<unsigned int, bool> m_keyMap;
|
||||
std::unordered_map<unsigned int, bool> m_oldKeyMap;
|
||||
glm::vec2 m_mouseCoords;
|
||||
glm::vec2 m_oldMouseCoords;
|
||||
int m_mwheelY;
|
||||
int m_mwheelX;
|
||||
};
|
||||
#endif // __INPUT_H__
|
146
src/Shader.cpp
146
src/Shader.cpp
|
@ -1,4 +1,13 @@
|
|||
#include "Shader.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
struct Shader::Attribute {
|
||||
GLint size;
|
||||
GLboolean normalized;
|
||||
GLsizei stride;
|
||||
GLuint offset;
|
||||
GLenum type;
|
||||
};
|
||||
|
||||
/** Compile a shader from file */
|
||||
void Shader::compileShader(const string& filePath, GLuint& id)
|
||||
|
@ -39,14 +48,14 @@ void Shader::compileShader(const string& filePath, GLuint& id)
|
|||
|
||||
glDeleteShader(id);
|
||||
|
||||
// Exit with failure.
|
||||
// Exit with failure.
|
||||
std::printf("%s\n", &(errorLog[0]));
|
||||
fatalError("Shader " + filePath + " failed to compile");
|
||||
fatalError("Shader @" + filePath + " failed to compile.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Create new shader from vertex and fragment files */
|
||||
Shader& Shader::createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath)
|
||||
Shader& Shader::createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath)
|
||||
{
|
||||
Shader* shader = new Shader();
|
||||
|
||||
|
@ -69,6 +78,37 @@ Shader& Shader::createShader(const string& vertexShaderFilePath, const string& f
|
|||
return *shader;
|
||||
}
|
||||
|
||||
/** Create new shader from vertex, fragment and geometry files */
|
||||
Shader& Shader::createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath, const string& geometryShaderFilePath)
|
||||
{
|
||||
Shader* shader = new Shader();
|
||||
|
||||
shader->m_programID = glCreateProgram();
|
||||
shader->m_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
if(shader->m_vertexShaderID == 0)
|
||||
{
|
||||
fatalError("Vertex shader failed to be created!");
|
||||
}
|
||||
|
||||
shader->m_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if(shader->m_fragmentShaderID == 0)
|
||||
{
|
||||
fatalError("Fragment shader failed to be created!");
|
||||
}
|
||||
|
||||
shader->m_geometryShaderID = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
if(shader->m_geometryShaderID == 0)
|
||||
{
|
||||
fatalError("Geometry shader failed to be created!");
|
||||
}
|
||||
|
||||
Shader::compileShader(vertexShaderFilePath, shader->m_vertexShaderID);
|
||||
Shader::compileShader(fragmentShaderFilePath, shader->m_fragmentShaderID);
|
||||
Shader::compileShader(geometryShaderFilePath, shader->m_geometryShaderID);
|
||||
|
||||
return *shader;
|
||||
}
|
||||
|
||||
/** Get uniform location */
|
||||
GLuint Shader::getUniformLocation(const string& uniformName)
|
||||
{
|
||||
|
@ -76,9 +116,11 @@ GLuint Shader::getUniformLocation(const string& uniformName)
|
|||
if (it == m_uniforms.end())
|
||||
{
|
||||
// Get uniform location
|
||||
GLint r = glGetUniformLocation(m_programID, uniformName.c_str());
|
||||
if ( r == GL_INVALID_OPERATION || r < 0 )
|
||||
GLint r = glGetUniformLocation(m_programID, uniformName.c_str());
|
||||
if (r == GL_INVALID_OPERATION || r < 0)
|
||||
{
|
||||
log_warn("Uniform " + uniformName + " doesn't exist in program.");
|
||||
}
|
||||
|
||||
// Add it to the cache
|
||||
m_uniforms[uniformName] = r;
|
||||
|
@ -91,6 +133,35 @@ GLuint Shader::getUniformLocation(const string& uniformName)
|
|||
}
|
||||
}
|
||||
|
||||
GLuint Shader::getAttribLocation(const string& attrbuteName)
|
||||
{
|
||||
GLint attrib = glGetAttribLocation(m_programID, attrbuteName.c_str());
|
||||
if (attrib == GL_INVALID_OPERATION || attrib < 0)
|
||||
{
|
||||
log_warn("Attribute " + attrbuteName + " doesn't exist in program.");
|
||||
}
|
||||
|
||||
return attrib;
|
||||
}
|
||||
|
||||
void Shader::setAttribute(const std::string& name,
|
||||
GLint size,
|
||||
GLboolean normalized,
|
||||
GLsizei stride,
|
||||
GLuint offset,
|
||||
GLenum type)
|
||||
{
|
||||
GLuint loc = getAttribLocation(name);
|
||||
glEnableVertexAttribArray(loc);
|
||||
glVertexAttribPointer(loc, size, type, normalized, stride * sizeof(GLfloat),
|
||||
(void*)(offset * sizeof(GLfloat)));
|
||||
m_attributes[name].size = size;
|
||||
m_attributes[name].normalized = normalized;
|
||||
m_attributes[name].stride = stride;
|
||||
m_attributes[name].offset = offset;
|
||||
m_attributes[name].type = type;
|
||||
}
|
||||
|
||||
/** Link the shaders together */
|
||||
void Shader::linkShaders()
|
||||
{
|
||||
|
@ -120,8 +191,8 @@ void Shader::linkShaders()
|
|||
glDeleteShader(m_vertexShaderID);
|
||||
glDeleteShader(m_fragmentShaderID);
|
||||
|
||||
fatalError("Shader linking failed!");
|
||||
std::printf("%s\n", &(infoLog[0]));
|
||||
fatalError("Shader linking failed!");
|
||||
}
|
||||
|
||||
// Always detach shaders after a successful link.
|
||||
|
@ -131,12 +202,6 @@ void Shader::linkShaders()
|
|||
glDeleteShader(m_fragmentShaderID);
|
||||
}
|
||||
|
||||
/** Bind attribute location */
|
||||
void Shader::addAttribute(const string& attribName)
|
||||
{
|
||||
glBindAttribLocation(m_programID, m_attributes++, attribName.c_str());
|
||||
}
|
||||
|
||||
/** Bind the shader for usage */
|
||||
void Shader::start()
|
||||
{
|
||||
|
@ -198,3 +263,60 @@ void Shader::setUniform(const string& name, int val)
|
|||
{
|
||||
glUniform1i(getUniformLocation(name), val);
|
||||
}
|
||||
|
||||
void Shader::use()
|
||||
{
|
||||
if (!m_valid)
|
||||
{
|
||||
m_valid = true;
|
||||
glLinkProgram(m_programID);
|
||||
|
||||
start();
|
||||
|
||||
GLint result;
|
||||
glGetProgramiv(m_programID, GL_LINK_STATUS, &result);
|
||||
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
log_error("Shader relink failed!");
|
||||
GLsizei maxLength = 0;
|
||||
glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
|
||||
char* log = new char[maxLength];
|
||||
glGetProgramInfoLog(m_programID, maxLength, &maxLength, log);
|
||||
|
||||
std::printf("%s\n", log);
|
||||
}
|
||||
|
||||
glBindVertexArray(vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
|
||||
for (auto it(m_attributes.begin()); it != m_attributes.end(); ++it)
|
||||
{
|
||||
GLuint location = getAttribLocation(it->first);
|
||||
glEnableVertexAttribArray(location);
|
||||
glVertexAttribPointer(
|
||||
location,
|
||||
it->second.size,
|
||||
it->second.type,
|
||||
it->second.normalized,
|
||||
it->second.stride * sizeof(GLfloat),
|
||||
(void*)(it->second.offset * sizeof(GLfloat))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
start();
|
||||
|
||||
glBindVertexArray(vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::setBuffers(GLint vao, GLint vbo, GLint ebo)
|
||||
{
|
||||
this->vao = vao;
|
||||
this->vbo = vbo;
|
||||
this->ebo = ebo;
|
||||
}
|
||||
|
|
26
src/Shader.h
26
src/Shader.h
|
@ -4,19 +4,22 @@
|
|||
#include <map>
|
||||
|
||||
#include "util/Common.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
static Shader& createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath);
|
||||
static Shader& createShader(const string& vertexShaderFilePath, const string& fragmentShaderFilePath, const string& geometryShaderFilePath);
|
||||
|
||||
void linkShaders();
|
||||
|
||||
void addAttribute(const string& attribName);
|
||||
|
||||
GLuint getUniformLocation(const string& uniformName);
|
||||
void setAttribute(const std::string& name, GLint size, GLboolean normalized, GLsizei stride, GLuint offset, GLenum type = GL_FLOAT);
|
||||
|
||||
GLuint getUniformLocation(const string& uniformName);
|
||||
inline GLuint operator[](const std::string& name) { return getUniformLocation(name); }
|
||||
GLuint getAttribLocation(const string& attrbuteName);
|
||||
|
||||
// Set uniforms
|
||||
void setUniform(const string& name, float x, float y, float z);
|
||||
void setUniform(const string& name, const vec3& v);
|
||||
void setUniform(const string& name, const dvec3& v);
|
||||
|
@ -28,16 +31,27 @@ public:
|
|||
void setUniform(const string& name, float val);
|
||||
void setUniform(const string& name, int val);
|
||||
|
||||
void setBuffers(GLint vao, GLint vbo, GLint ebo);
|
||||
|
||||
// Bind Attributes and start the shader program
|
||||
void use();
|
||||
|
||||
// Start the shader program without binding attributes
|
||||
void start();
|
||||
void stop();
|
||||
private:
|
||||
int m_attributes;
|
||||
struct Attribute;
|
||||
bool m_valid;
|
||||
|
||||
GLuint m_programID;
|
||||
GLuint m_vertexShaderID;
|
||||
GLuint m_fragmentShaderID;
|
||||
GLuint m_geometryShaderID;
|
||||
|
||||
map<string, GLint> m_uniforms;
|
||||
map<string, GLuint> m_uniforms;
|
||||
map<string, Attribute> m_attributes;
|
||||
|
||||
GLint vao, vbo, ebo;
|
||||
|
||||
static void compileShader(const string& filePath, GLuint& id);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue