alistair 3 years ago
parent
commit
b36b6c1531
  1. 2
      src/CMakeLists.txt
  2. 249
      src/main.cpp
  3. 233
      src/mesh.cpp
  4. 60
      src/mesh.h
  5. 4
      src/shaders.cpp
  6. 3
      src/shaders.h
  7. 102
      src/shaders/test.frag
  8. 5
      src/shaders/test.vert

2
src/CMakeLists.txt

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
find_package(SDL2 REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(ASSIMP REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
include_directories(${OPENGL_INCLUDE_DIR})
@ -17,6 +18,7 @@ add_executable(testgame ${testgamefiles}) @@ -17,6 +18,7 @@ add_executable(testgame ${testgamefiles})
target_link_libraries(testgame ${GLEW_LIBRARIES})
target_link_libraries(testgame ${OPENGL_LIBRARIES})
target_link_libraries(testgame ${SDL2_LIBRARIES})
target_link_libraries(testgame ${ASSIMP_LIBRARIES})
add_custom_command(
TARGET testgame POST_BUILD

249
src/main.cpp

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
#include <SDL2/SDL.h>
//Using SDL, SDL OpenGL, standard IO, and, strings
#include <SDL2/SDL_mouse.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
@ -15,8 +14,10 @@ @@ -15,8 +14,10 @@
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <vector>
#include "shaders.h"
#include "mesh.h"
#include "stb_image.h"
@ -25,7 +26,7 @@ void printProgramLog( GLuint program ) @@ -25,7 +26,7 @@ void printProgramLog( GLuint program )
//Make sure name is shader
if( glIsProgram( program ) )
{
//Program log length
//Program loglength
int infoLogLength = 0;
int maxLength = infoLogLength;
@ -60,6 +61,7 @@ class SDLGLGLWindow { @@ -60,6 +61,7 @@ class SDLGLGLWindow {
GLuint gVBO = 0;
GLuint gIBO = 0;
GLuint gVAO = 0;
unsigned int lightVAO;
glm::vec3 cubePositions[10] = {
@ -75,9 +77,16 @@ class SDLGLGLWindow { @@ -75,9 +77,16 @@ class SDLGLGLWindow {
glm::vec3(-1.3f, 1.0f, -1.5f)
};
std::vector<glm::vec3> lightPositions = std::vector<glm::vec3>();
glm::mat4 projection;
glm::mat4 model = glm::mat3(1.0f);
glm::mat4 view = glm::mat4(1.0f);
private:
Shader *vertex;
Shader *fragment;
Model *bp_model;
public:
int screen_width;
int screen_height;
@ -99,13 +108,16 @@ class SDLGLGLWindow { @@ -99,13 +108,16 @@ class SDLGLGLWindow {
float cam_yaw = -90;
SDLGLGLWindow(int width, int height) {
SDLGLGLWindow(int width, int height)
{
screen_width = width;
screen_height = height;
if (!create_gl_window()) {
exit(1);
}
lightPositions.push_back(glm::vec3(1.2f, 2.0f, 2.0f));
}
void update_camera() {
@ -169,12 +181,13 @@ class SDLGLGLWindow { @@ -169,12 +181,13 @@ class SDLGLGLWindow {
//Generate program
gProgramID = glCreateProgram();
Shader vertex {GL_VERTEX_SHADER, gProgramID, "src/shaders/test.vert"};
Shader fragment {GL_FRAGMENT_SHADER, gProgramID, "src/shaders/test.frag"};
vertex = new Shader(GL_VERTEX_SHADER, gProgramID, "src/shaders/test.vert");
fragment = new Shader(GL_FRAGMENT_SHADER, gProgramID, "src/shaders/test.frag");
//Link program
glLinkProgram( gProgramID );
//Check for errors
GLint programSuccess = GL_TRUE;
glGetProgramiv( gProgramID, GL_LINK_STATUS, &programSuccess );
@ -185,6 +198,9 @@ class SDLGLGLWindow { @@ -185,6 +198,9 @@ class SDLGLGLWindow {
return false;
}
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
/* textures */
@ -193,8 +209,8 @@ class SDLGLGLWindow { @@ -193,8 +209,8 @@ class SDLGLGLWindow {
stbi_set_flip_vertically_on_load(true);
unsigned int texture[2];
glGenTextures(2, texture);
unsigned char *data = stbi_load("src/assets/container.jpg", &width, &height, &nrChannels, 0);
if (data) {
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
@ -209,7 +225,7 @@ class SDLGLGLWindow { @@ -209,7 +225,7 @@ class SDLGLGLWindow {
throw std::exception () ;
}
data = stbi_load("src/assets/awesomeface.png", &width, &height, &nrChannels, 0);
data = stbi_load("src/assets/specular.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glBindTexture(GL_TEXTURE_2D, texture[1]);
@ -226,58 +242,63 @@ class SDLGLGLWindow { @@ -226,58 +242,63 @@ class SDLGLGLWindow {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[1]);
vertex.use();
vertex.setInt("texture1", 0);
vertex.setInt("texture2", 1);
vertex->use();
fragment->setInt("material.diffusemap", 0);
fragment->setInt("material.specularmap", 1);
fragment->setBool("lighting_emit", false);
float cubeVertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
// vertices normals textures
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
//VBO data
/*
GLfloat vertexData[] =
@ -301,6 +322,7 @@ class SDLGLGLWindow { @@ -301,6 +322,7 @@ class SDLGLGLWindow {
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glBufferData( GL_ARRAY_BUFFER, sizeof cubeVertices, cubeVertices, GL_STATIC_DRAW );
//Create IBO
// glGenBuffers( 1, &gIBO );
// glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
@ -308,27 +330,31 @@ class SDLGLGLWindow { @@ -308,27 +330,31 @@ class SDLGLGLWindow {
GLint gVertexPos2DLocation = -1;
GLint gtexlocation = -1;
GLint normloc = -1;
gVertexPos2DLocation = glGetAttribLocation( gProgramID, "LVertexPos2D" );
gtexlocation = glGetAttribLocation( gProgramID, "texCoord" );
normloc = glGetAttribLocation( gProgramID, "aNormal" );
glVertexAttribPointer( gVertexPos2DLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(gVertexPos2DLocation);
glVertexAttribPointer(gtexlocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(gtexlocation);
glVertexAttribPointer( gVertexPos2DLocation, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), NULL);
glVertexAttribPointer( normloc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(3 * sizeof (float)));
glVertexAttribPointer(gtexlocation, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(6 * sizeof(float)));
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
glEnableVertexAttribArray(gtexlocation);
glEnableVertexAttribArray(gVertexPos2DLocation);
glEnableVertexAttribArray(normloc);
glGenVertexArrays(1, &lightVAO);
glBindVertexArray(lightVAO);
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
glBufferData( GL_ARRAY_BUFFER, sizeof cubeVertices, cubeVertices, GL_STATIC_DRAW );
glEnableVertexAttribArray(0);
// glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST);
return success;
}
void render()
{
@ -346,22 +372,65 @@ class SDLGLGLWindow { @@ -346,22 +372,65 @@ class SDLGLGLWindow {
//Bind program
glUseProgram( gProgramID );
glUniform3f(glGetUniformLocation(vertex->program, "objectColour"), 1.0f, 0.5f, 0.31f);
fragment->setInt("lights[0].type", 2);
fragment->setFloat("lights[0].angle_cutoff", glm::cos(glm::radians(12.5f)));
fragment->setFloat("lights[0].outer_angle_cutoff", glm::cos(glm::radians(17.5f)));
fragment->setVec3("lights[0].direction", camera_front);
fragment->setVec3("lights[0].position", camera_pos);
fragment->setVec3("lights[0].ambient", glm::vec3(0.3));
fragment->setVec3("lights[0].diffuse", glm::vec3(0.8));
fragment->setVec3("lights[0].specular", glm::vec3(1.0));
fragment->setBool("lights[0].attenuate", true);
fragment->setVec3("lights[0].attenuation", glm::vec3(1.0, 0.09, 0.032));
fragment->setInt("num_lights", 2);
fragment->setInt("lights[1].type", 1);
fragment->setVec3("lights[1].position", lightPositions[0]);
fragment->setVec3("lights[1].ambient", glm::vec3(0.3));
fragment->setVec3("lights[1].diffuse", glm::vec3(0.8));
fragment->setVec3("lights[1].specular", glm::vec3(1.0));
fragment->setBool("lights[1].attenuate", false);
fragment->setVec3("lights[1].attenuation", glm::vec3(1.0, 0.09, 0.032));
glUniform3f(glGetUniformLocation(vertex->program, "cameraPosition"), camera_pos.x, camera_pos.y, camera_pos.z);
fragment->setVec3("material.specular", glm::vec3(0.7));
fragment->setVec3("material.diffuse", glm::vec3(1.0, 1.0, 0.8));
fragment->setVec3("material.ambient", glm::vec3(0.1));
fragment->setFloat("material.shininess", 32);
/***** Light Attenuation
*
* Constant x, Linear y, Quadratic z
*
* Distance Constant Linear Quadratic
* 7 1.0 0.7 1.8
* 13 1.0 0.35 0.44
* 20 1.0 0.22 0.20
* 32 1.0 0.14 0.07
* 50 1.0 0.09 0.032
* 65 1.0 0.07 0.017
* 100 1.0 0.045 0.0075
* 160 1.0 0.027 0.0028
* 200 1.0 0.022 0.0019
* 325 1.0 0.014 0.0007
* 600 1.0 0.007 0.0002
* 3250 1.0 0.0014 0.000007
*
*/
// set col
glUniform4f(vertexcol, 0.0f, green, 0.0f, 1.0f);
//Set vertex data
glBindVertexArray(gVAO);
// glBindBuffer( GL_ARRAY_BUFFER, gVBO );
//Enable vertex position
//Set index data and render
/* set phong values */
fragment->setBool("lighting_emit", false);
// glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
// glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL );
for (int i = 0; i < 10; i++) {
@ -382,6 +451,19 @@ class SDLGLGLWindow { @@ -382,6 +451,19 @@ class SDLGLGLWindow {
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindVertexArray(lightVAO);
fragment->setBool("lighting_emit", true);
for (glm::vec3 pos : lightPositions) {
model = glm::mat4(1.0f);
model = glm::translate(model, pos);
model = glm::scale(model, glm::vec3(0.2f));
unsigned int loc = glGetUniformLocation(gProgramID, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 36);
}
//Disable vertex position
//glDisableVertexAttribArray( gVertexPos2DLocation );
@ -404,6 +486,9 @@ class SDLGLGLWindow { @@ -404,6 +486,9 @@ class SDLGLGLWindow {
SDL_DestroyWindow( gWindow );
gWindow = NULL;
delete vertex;
delete fragment;
//Quit SDL subsystems
SDL_Quit();
}
@ -418,9 +503,10 @@ int main(int argc, char **argv) { @@ -418,9 +503,10 @@ int main(int argc, char **argv) {
SDL_Event e;
//Enable text input
SDL_StartTextInput();
// SDL_StartTextInput();
SDL_SetRelativeMouseMode(SDL_TRUE);
bool mouse_mode = true;
//While application is running
while( !quit )
@ -436,6 +522,13 @@ int main(int argc, char **argv) { @@ -436,6 +522,13 @@ int main(int argc, char **argv) {
if (e.type == SDL_KEYDOWN) {
const float camera_speed = 0.4f;
switch (e.key.keysym.scancode) {
case SDL_SCANCODE_SPACE:
mouse_mode = !mouse_mode;
SDL_SetRelativeMouseMode(mouse_mode ? SDL_TRUE : SDL_FALSE);
break;
case SDL_SCANCODE_ESCAPE:
quit = true;
break;
case SDL_SCANCODE_W:
cont.camera_pos += camera_speed * cont.camera_front;
break;
@ -457,12 +550,14 @@ int main(int argc, char **argv) { @@ -457,12 +550,14 @@ int main(int argc, char **argv) {
continue;
}
cont.cam_pitch -= e.motion.yrel * 0.1f;
cont.cam_yaw += e.motion.xrel * 0.1f;
cont.update_camera();
if (mouse_mode) {
cont.cam_pitch -= e.motion.yrel * 0.1f;
cont.cam_yaw += e.motion.xrel * 0.1f;
cont.update_camera();
}
}
}
cont.update_camera();
cont.update_camera();
//Render quad
@ -473,3 +568,5 @@ int main(int argc, char **argv) { @@ -473,3 +568,5 @@ int main(int argc, char **argv) {
return 0;
}

233
src/mesh.cpp

@ -0,0 +1,233 @@ @@ -0,0 +1,233 @@
#include "mesh.h"
#include "stb_image.h"
#include <assimp/Importer.hpp>
#include <assimp/material.h>
Mesh::Mesh(std::vector<struct vertex> vertices, std::vector<unsigned int> indices,
std::vector<struct texture> textures)
{
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
}
void Mesh::setupMesh()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData( GL_ARRAY_BUFFER, vertices.size() * sizeof(vertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)offsetof(vertex, normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)offsetof(vertex, texture_coords));
glBindVertexArray(0);
}
void Mesh::draw(Shader &shader) {
unsigned int specularNr = 1;
unsigned int diffuseNr = 1;
/*
for(unsigned int i = 0; i < textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
// retrieve texture number (the N in diffuse_textureN)
std::string number;
std::string name = textures[i].type;
if(name == "texture_diffuse")
number = std::to_string(diffuseNr++);
else if(name == "texture_specular")
number = std::to_string(specularNr++);
shader.setFloat(("material." + name + number).c_str(), i);
glBindTexture(GL_TEXTURE_2D, textures[i].id);
}
glActiveTexture(GL_TEXTURE0);
*/
// draw mesh
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
/** Model */
void Model::draw(Shader &shader)
{
for(auto mesh : meshes) {
mesh.draw(shader);
}
}
void Model::load_model(std::string path) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
throw std::exception();
return;
}
directory = path.substr(0, path.find_last_of('/'));
process_node(scene->mRootNode, scene);
}
void Model::process_node(aiNode *node, const aiScene *scene)
{
for (unsigned int i = 0; i < node->mNumMeshes; i++) {
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(process_mesh(mesh, scene));
}
// recurse
for (unsigned int i = 0; i < node->mNumChildren; i++) {
process_node(node->mChildren[i], scene);
}
}
Mesh Model::process_mesh(aiMesh *mesh, const aiScene *scene)
{
std::vector<vertex> vertices;
std::vector<unsigned int> indices;
std::vector<texture> textures;
for (unsigned int i = 0 ; i < mesh->mNumVertices; i++) {
glm::vec3 pos = glm::vec3(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
glm::vec3 norm = glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
vertex v;
v.position = pos;
v.normal = norm;
if(mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
{
glm::vec2 vec;
vec.x = mesh->mTextureCoords[0][i].x;
vec.y = mesh->mTextureCoords[0][i].y;
v.texture_coords = vec;
} else {
v.texture_coords = glm::vec2(0.0f);
}
vertices.push_back(v);
}
for(unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
for(unsigned int j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}
if (mesh->mMaterialIndex >= 0) {
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
std::vector<texture> diffuseMaps = load_material_textures(material, aiTextureType_DIFFUSE, "texture_diffuse");
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
std::vector<texture> specularMaps = load_material_textures(material, aiTextureType_SPECULAR, "texture_specular");
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
}
return Mesh(vertices, indices, textures);
}
unsigned int Model::texture_from_file(const char *fname, std::string directory) {
std::string filename = std::string(fname);
filename = directory + '/' + filename;
unsigned int textureID;
glGenTextures(1, &textureID);
int width, height, nrComponents;
unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
if (data)
{
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
{
stbi_image_free(data);
}
return textureID;
}
std::vector<texture> Model::load_material_textures(aiMaterial *mat, aiTextureType type, std::string typeName) {
std::vector<texture> textures;
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++) {
aiString str;
mat->GetTexture(type, i, &str);
bool skip = false;
for (unsigned int j = 0; j < textures_loaded.size(); j++) {
if (std::strcmp(textures_loaded[j].path.data(), str.C_Str()) == 0) {
textures.push_back(textures_loaded[j]);
skip = true;
break;
}
}
if (!skip) {
texture texture;
texture.id = texture_from_file(str.C_Str(), directory);
texture.type = typeName;
texture.path = str.C_Str();
textures.push_back(texture);
textures_loaded.push_back(texture);
}
}
return textures;
}

60
src/mesh.h

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
#ifndef MESH_H
#define MESH_H
#include <vector>
#include <string>
#include "shaders.h"
#include <glm/glm.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
struct vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texture_coords;
};
struct texture {
unsigned int id;
std::string type;
std::string path;
};
class Mesh {
public:
std::vector<struct vertex> vertices;
std::vector<unsigned int> indices;
std::vector<struct texture> textures;
Mesh(std::vector<struct vertex> vertices,
std::vector<unsigned int> indices,
std::vector<struct texture> textures);
void draw(Shader &shader);
private:
unsigned int VAO, VBO, EBO;
void setupMesh();
};
class Model {
public:
Model(std::string path) {
load_model(path);
}
void draw(Shader &shader);
private:
std::vector<Mesh> meshes;
std::string directory;
std::vector<texture> textures_loaded;
unsigned int texture_from_file(const char *fname, std::string directory);
void load_model(std::string path);
void process_node(aiNode *node, const aiScene *scene);
Mesh process_mesh(aiMesh *mesh, const aiScene *scene);
std::vector<texture> load_material_textures(aiMaterial *mat, aiTextureType type, std::string type_name);
};
#endif

4
src/shaders.cpp

@ -95,3 +95,7 @@ void Shader::set(const std::string &name, float value) { @@ -95,3 +95,7 @@ void Shader::set(const std::string &name, float value) {
setFloat(name, value);
}
void Shader::setVec3(const std::string &name, glm::vec3 vec) {
glUniform3f(glGetUniformLocation(program, name.c_str()), vec.x, vec.y, vec.z);
}

3
src/shaders.h

@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
#include <string>
#include <iostream>
#include <glm/vec3.hpp>
class Shader {
std::string source;
@ -35,5 +37,6 @@ class Shader { @@ -35,5 +37,6 @@ class Shader {
void setFloat(const std::string &name, float value);
void setBool(const std::string &name, bool value);
void setInt(const std::string &name, int value);
void setVec3(const std::string &name, glm::vec3 vec);
};
#endif

102
src/shaders/test.frag

@ -3,12 +3,108 @@ @@ -3,12 +3,108 @@
out vec4 LFragment;
in vec2 theTexCoord;
in vec3 Normal;
in vec3 FragPos;
uniform sampler2D texture1;
uniform sampler2D texture2;
//uniform vec3 objectColour;
//uniform vec3 lightColour;
uniform int lighting_emit;
//uniform vec3 lightPosition;
uniform vec3 cameraPosition;
struct Material {
sampler2D diffusemap;
sampler2D specularmap;
sampler2D texture_diffuse1;
sampler2D texture_diffuse2;
sampler2D texture_diffuse3;
sampler2D texture_specular1;
sampler2D texture_specular2;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
#define DIRECTIONAL_LIGHT 0
#define POINT_LIGHT 1
#define SPOT_LIGHT 2
struct Light {
int type;
vec3 direction;
vec3 position;
float angle_cutoff;
float outer_angle_cutoff;
vec3 ambient;
vec3 diffuse;
vec3 specular;
bool attenuate;
vec3 attenuation;
};
#define MAX_LIGHTS 10
uniform Light lights[MAX_LIGHTS];
uniform int num_lights;
uniform Material material;
// uniform Light light;
void main()
{
LFragment = mix(texture(texture1, theTexCoord), texture(texture2, theTexCoord), 0.2);
vec3 endResult;
for (int i = 0; i < num_lights; i++) {
vec3 ambient = lights[i].ambient * material.ambient;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir;
if (lights[i].type == POINT_LIGHT || lights[i].type == SPOT_LIGHT) {
lightDir = normalize(lights[i].position - FragPos);
} else if (lights[i].type == DIRECTIONAL_LIGHT) {
lightDir = normalize(-lights[i].direction);
}
float diff_val = max(dot(norm, lightDir), 0.0);
vec3 diffuse = lights[i].diffuse * (diff_val * material.diffuse);
// specular
float spec = max(dot(normalize(cameraPosition - FragPos), reflect(-lightDir, norm)), 0.0);
spec = pow(spec, material.shininess);
vec3 specular = lights[i].specular * (spec * vec3(texture(material.specularmap, theTexCoord)));
vec3 result;
// spotlight
if (lights[i].type == POINT_LIGHT || lights[i].type == DIRECTIONAL_LIGHT)
result = diffuse + ambient + specular;
else if (lights[i].type == SPOT_LIGHT) {
result = ambient;
float theta = dot(lightDir, normalize(-lights[i].direction));
float epsilon = lights[i].angle_cutoff - lights[i].outer_angle_cutoff;
float intensity = clamp((theta - lights[i].outer_angle_cutoff)/epsilon, 0.0, 1.0);
result += (diffuse + specular) * intensity;
}
// attenuation
if (lights[i].attenuate) {
float dist = length(lights[i].position - FragPos);
float attenuation = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y *
dist + lights[i].attenuation.y * (dist * dist));
result *= attenuation;
}
endResult += result;
}
LFragment = (vec4(endResult, 1.0)) * texture(material.diffusemap, theTexCoord);
}

5
src/shaders/test.vert

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
layout (location = 0) in vec3 LVertexPos2D;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 aNormal;
out vec2 theTexCoord;
@ -9,9 +10,13 @@ uniform mat4 model; @@ -9,9 +10,13 @@ uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 Normal;
out vec3 FragPos;
void main()
{
gl_Position = projection * view * model * vec4( LVertexPos2D, 1.0);
theTexCoord = texCoord;
Normal = mat3(transpose(inverse(model))) * aNormal;
FragPos = vec3(model * vec4(LVertexPos2D, 1.0));
}

Loading…
Cancel
Save