init commit
This commit is contained in:
commit
0e406f71c8
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Ignore everything
|
||||
*
|
||||
|
||||
# But not these files...
|
||||
!.gitignore
|
||||
!*/
|
||||
!/*cw\ */src/**
|
||||
!/*cw\ */shaders/**
|
8
cw 1/shaders/shader_1_1.frag
Normal file
8
cw 1/shaders/shader_1_1.frag
Normal file
@ -0,0 +1,8 @@
|
||||
#version 430 core
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec4(0.0, 0.6, 0.95, 1.0);
|
||||
}
|
8
cw 1/shaders/shader_1_1.vert
Normal file
8
cw 1/shaders/shader_1_1.vert
Normal file
@ -0,0 +1,8 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vertexPosition;
|
||||
}
|
6
cw 1/shaders/shader_1_2.frag
Normal file
6
cw 1/shaders/shader_1_2.frag
Normal file
@ -0,0 +1,6 @@
|
||||
#version 430 core
|
||||
out vec4 color;
|
||||
void main()
|
||||
{
|
||||
color = vec4(0.0, 0.6, 0.95, 1.0);
|
||||
}
|
10
cw 1/shaders/shader_1_2.vert
Normal file
10
cw 1/shaders/shader_1_2.vert
Normal file
@ -0,0 +1,10 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vertexPosition;
|
||||
}
|
10
cw 1/shaders/shader_3_1.frag
Normal file
10
cw 1/shaders/shader_3_1.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 430 core
|
||||
|
||||
in vec4 color;
|
||||
out vec4 out_color;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
14
cw 1/shaders/shader_3_1.vert
Normal file
14
cw 1/shaders/shader_3_1.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
layout(location = 1) in vec4 vertexColor;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vertexColor;
|
||||
gl_Position = transformation * vertexPosition;
|
||||
}
|
11
cw 1/shaders/shader_3_2.frag
Normal file
11
cw 1/shaders/shader_3_2.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 objectColor;
|
||||
in vec3 normal;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(normal, 1. );
|
||||
}
|
14
cw 1/shaders/shader_3_2.vert
Normal file
14
cw 1/shaders/shader_3_2.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
out vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
normal=vertexNormal;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
104
cw 1/src/Box.cpp
Normal file
104
cw 1/src/Box.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
|
||||
// dane 36 wierzcholkow i kolorow opisujace model pudelka
|
||||
const float boxPositions[] = {
|
||||
0.25f, 0.25f, 0.75f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, 0.75f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f,
|
||||
0.25f, 0.25f, -0.75f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f,
|
||||
0.25f, 0.25f, 0.75f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f,
|
||||
};
|
||||
|
||||
|
||||
const float boxColors[] = {
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
};
|
31
cw 1/src/Camera.cpp
Normal file
31
cw 1/src/Camera.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar, float frustumScale)
|
||||
{
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = 1.f;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 1/src/Camera.h
Normal file
14
cw 1/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f, float frustumScale = 1.f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
76
cw 1/src/Render_Utils.cpp
Normal file
76
cw 1/src/Render_Utils.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
void Core::drawVAO(GLuint VAO, int numVertices)
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Core::drawVAOIndexed(GLuint VAO, int numVertices)
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLuint Core::initVAO(const float* vertexArray, int numVertices, int elementSize) {
|
||||
GLuint VBO, VAO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, numVertices * elementSize * sizeof(float), vertexArray, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, GL_FALSE, elementSize * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
|
||||
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
|
||||
glBindVertexArray(0);
|
||||
return VAO;
|
||||
}
|
||||
|
||||
GLuint Core::initVAOIndexed(const float* vertexArray, const unsigned int* indexArray, int numVertices, int elementSize, int numIndexes) {
|
||||
GLuint VBO, VAO, EBO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, numVertices * elementSize * sizeof(float), vertexArray, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, GL_FALSE, elementSize * sizeof(float), (void*)0);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndexes*sizeof(unsigned int), indexArray, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
|
||||
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
|
||||
glBindVertexArray(0);
|
||||
return VAO;
|
||||
}
|
26
cw 1/src/Render_Utils.h
Normal file
26
cw 1/src/Render_Utils.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
// VAO - zmienna zawierajaca wskaznik do VAO
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
void drawVAO(GLuint VAO, int numVertices);
|
||||
|
||||
// VAO - zmienna zawierajaca wskaznik do VAO
|
||||
// numIndexes - liczba indeksow do naryowania
|
||||
void drawVAOIndexed(GLuint VAO, int numVertices);
|
||||
|
||||
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
GLuint initVAO(const float* vertexArray, int numVertices, int elementSize);
|
||||
|
||||
|
||||
// indexArray - jednowymiarowa tablica zawierajaca indeksy wierzcholkow kolejnych trojkatow w jednym ciagu (t1_i1, t1_i2, t1_i3, t2_i1, t2_i2, t2_i3, ...)
|
||||
// numIndexes - liczba indeksow w tablicy indexArray
|
||||
GLuint initVAOIndexed(const float* vertexArray, const unsigned int* indexArray, int numVertices, int elementSize, int numIndexes);
|
||||
|
||||
void deleteVAO(GLuint VAO);
|
||||
}
|
102
cw 1/src/Shader_Loader.cpp
Normal file
102
cw 1/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy kompilacji
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy linkowania
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 1/src/Shader_Loader.h
Normal file
29
cw 1/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
56
cw 1/src/ex_1_1.hpp
Normal file
56
cw 1/src/ex_1_1.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
// funkcja renderujaca scene
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
|
||||
// ZADANIE: Przesledz kod i komentarze
|
||||
// ZADANIE: Zmien kolor tla sceny, przyjmujac zmiennoprzecinkowy standard RGBA
|
||||
glClearColor(1.0f, 0.3f, 0.3f, 1.0f);
|
||||
//ZADAMOE 1b*
|
||||
float time = glfwGetTime();
|
||||
glClearColor(glm::sin(time), glm::cos(time), 0.3f, 1.0f);
|
||||
//ZADAMOE 1b* END
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Powinno byc wywolane po kazdej klatce
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
74
cw 1/src/ex_1_2.hpp
Normal file
74
cw 1/src/ex_1_2.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint triangleVAO;
|
||||
GLuint squareVAO;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.5f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Aktywowanie shadera
|
||||
glUseProgram(program);
|
||||
|
||||
//wywolaj funkcje Core::drawVAO z render utils z parametrem wejściowym GLuint triangleVAO
|
||||
Core::drawVAO(triangleVAO, 3);
|
||||
// Wylaczenie shadera
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_1.vert", "shaders/shader_1_1.frag");
|
||||
|
||||
//stworz tablice wierzcholkow i zaladuj je do GPU za pomoca funkcji initVAO, wynik zapisz w triangleVAO
|
||||
float triangle[]={
|
||||
-0.5, -0.5, 0, 1,
|
||||
0.5, -0.5, 0, 1,
|
||||
-0.5, 0.5, 0, 1,
|
||||
};
|
||||
triangleVAO = Core::initVAO(triangle, 3, 4);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
78
cw 1/src/ex_1_3.hpp
Normal file
78
cw 1/src/ex_1_3.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint quadVAO;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Aktywowanie shadera
|
||||
glUseProgram(program);
|
||||
|
||||
//wywolaj funkcje drawVAOIndexed na quadVAO
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
// Wylaczenie shadera
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_1.vert", "shaders/shader_1_1.frag");
|
||||
|
||||
//Stworz czworokat przy uzyciu 4 wierzcholkow i 6 indeksow (typ: const int []) zaladuj go do za pomoca initVAOIndexed do quadVAO
|
||||
float quad[] = {
|
||||
-0.5, -0.5, 0, 1,
|
||||
0.5, -0.5, 0, 1,
|
||||
0.5, 0.5, 0, 1,
|
||||
-0.5, 0.5, 0, 1,
|
||||
};
|
||||
unsigned int quadIndexes[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
quadVAO = Core::initVAOIndexed(quad, quadIndexes, 4, 4, 6);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
100
cw 1/src/ex_1_4.hpp
Normal file
100
cw 1/src/ex_1_4.hpp
Normal file
@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint quadVAO;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
// Zmienna "time" przechowuje czas ktory uplynal od uruchomienia aplikacji
|
||||
float time = glfwGetTime();
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// "translation" jest automatycznie zainicjalizowana macierza 4x4
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// ! Macierz translation jest definiowana wierszowo dla poprawy czytelnosci. OpenGL i GLM domyslnie stosuje macierze kolumnowe, dlatego musimy ja transponowac !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
glm::mat4 translation =
|
||||
{ 1,0,0,0,
|
||||
0,1,0,sin(time)/2.0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
translation = glm::transpose(translation);
|
||||
|
||||
// ZADANIE: Narysuj ruszajacy sie czworokat
|
||||
//
|
||||
// Uzyj zmiennej "time" do zdefiniowania macierzy translacji w taki sposob, aby czworokat przesuwal sie w gore i w dol ekranu (wartosci wspolrzednej y powinny zmieniac sie pomiedzy -0.5 i 0.5)
|
||||
// Wykorzystaj funkcje sinus: sin(float x)
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
|
||||
// glUniformMatrix4fv przekazuje macierz "translation" do GPU i powiazuje ja w shaderze ze zmienna typu mat4 o nazwie "transformation"
|
||||
// Shader uzywa tej macierzy to transformacji wierzcholkow podczas renderowania
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&translation);
|
||||
|
||||
// Uzyj kodu z poprzednich cwiczen do narysowania czworokata
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_2.vert", "shaders/shader_1_2.frag");
|
||||
|
||||
//Przekopiuj kod do ladowania z poprzedniego zadania
|
||||
float quad[] = {
|
||||
-0.5, -0.5, 0, 1,
|
||||
0.5, -0.5, 0, 1,
|
||||
0.5, 0.5, 0, 1,
|
||||
-0.5, 0.5, 0, 1,
|
||||
};
|
||||
unsigned int quadIndexes[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
quadVAO = Core::initVAOIndexed(quad, quadIndexes, 4, 4, 6);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
114
cw 1/src/ex_1_5.hpp
Normal file
114
cw 1/src/ex_1_5.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint quadVAO;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
// Zmienna "time" przechowuje czas ktory uplynal od uruchomienia aplikacji
|
||||
float time = glfwGetTime();
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// ! Macierz translation jest definiowana wierszowo dla poprawy czytelnosci. OpenGL i GLM domyslnie stosuje macierze kolumnowe, dlatego musimy ja transponowac !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
double alpha = time;
|
||||
glm::mat4 rotation =
|
||||
{ glm::cos(alpha),-glm::sin(alpha),0,0,
|
||||
-glm::sin(alpha),-glm::cos(alpha),0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
|
||||
// ZADANIE: Narysuj dwa czworokaty, jeden ruszajacy sie, drugi obracajacy sie
|
||||
// Do rysowania ruszajacego sie czworokatu mozesz uzyc kodu z poprzedniego zadania, zmodyfikuj tylko macierz translacji, zeby byly obok siebie, nie jeden na drugim
|
||||
// Uzyj zmiennej "time" do zdefiniowania takiej macierzy rotacji, aby czworokat obracal sie wokol srodka (znajdz odpowiednia macierz 4x4 w internecie)
|
||||
// Kat obrotu podajemy w radianach
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
|
||||
rotation = glm::transpose(rotation);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&rotation);
|
||||
|
||||
// Uzyj kodu z poprzednich cwiczen do narysowania czworokata
|
||||
glm::mat4 translation =
|
||||
{ 1,0,0,0.5,
|
||||
0,1,0,sin(time) / 2.0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
translation = glm::transpose(translation);
|
||||
|
||||
// ZADANIE: Narysuj ruszajacy sie czworokat
|
||||
//
|
||||
// Uzyj zmiennej "time" do zdefiniowania macierzy translacji w taki sposob, aby czworokat przesuwal sie w gore i w dol ekranu (wartosci wspolrzednej y powinny zmieniac sie pomiedzy -0.5 i 0.5)
|
||||
// Wykorzystaj funkcje sinus: sin(float x)
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
|
||||
// glUniformMatrix4fv przekazuje macierz "translation" do GPU i powiazuje ja w shaderze ze zmienna typu mat4 o nazwie "transformation"
|
||||
// Shader uzywa tej macierzy to transformacji wierzcholkow podczas renderowania
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&translation);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_2.vert", "shaders/shader_1_2.frag");
|
||||
|
||||
//Przekopiuj kod do ladowania z poprzedniego zadania
|
||||
float quad[] = {
|
||||
-0.5, -0.5, 0, 1,
|
||||
0.5, -0.5, 0, 1,
|
||||
0.5, 0.5, 0, 1,
|
||||
-0.5, 0.5, 0, 1,
|
||||
};
|
||||
unsigned int quadIndexes[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
quadVAO = Core::initVAOIndexed(quad, quadIndexes, 4, 4, 6);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
112
cw 1/src/ex_1_6.hpp
Normal file
112
cw 1/src/ex_1_6.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint quadVAO;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
// Zmienna "time" przechowuje czas ktory uplynal od uruchomienia aplikacji
|
||||
float time = glfwGetTime();
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// ZADANIE: Wyswietl czworokat, ktory jednoczesnie przesuwa sie i obraca.
|
||||
//
|
||||
// Uzyj kodu do translacji i rotacji czworokatu z poprzednich zadan
|
||||
//
|
||||
// Stworz taka macierz transformacji, ktora powoduje ze czworokat przesuwa sie w gore i w dol ekranu, jednoczesnie obracajac sie.
|
||||
// Wyslij stworzona macierz do GPU za pomoca funkcji glUniformMatrix4fv zamiast macierzy "translation" i "rotation" z poprzednich zadan
|
||||
glm::mat4 translation =
|
||||
{ 1,0,0,0,
|
||||
0,1,0,sin(time) / 2.0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
translation = glm::transpose(translation);
|
||||
|
||||
double alpha = time;
|
||||
glm::mat4 rotation =
|
||||
{ glm::cos(alpha),-glm::sin(alpha),0,0,
|
||||
-glm::sin(alpha),-glm::cos(alpha),0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
rotation = glm::transpose(rotation);
|
||||
|
||||
glm::mat4 res = translation * rotation;
|
||||
|
||||
// ZADANIE: Narysuj ruszajacy sie czworokat
|
||||
//
|
||||
// Uzyj zmiennej "time" do zdefiniowania macierzy translacji w taki sposob, aby czworokat przesuwal sie w gore i w dol ekranu (wartosci wspolrzednej y powinny zmieniac sie pomiedzy -0.5 i 0.5)
|
||||
// Wykorzystaj funkcje sinus: sin(float x)
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
|
||||
// glUniformMatrix4fv przekazuje macierz "translation" do GPU i powiazuje ja w shaderze ze zmienna typu mat4 o nazwie "transformation"
|
||||
// Shader uzywa tej macierzy to transformacji wierzcholkow podczas renderowania
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&res);
|
||||
|
||||
// Uzyj kodu z poprzednich cwiczen do narysowania czworokata
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_2.vert", "shaders/shader_1_2.frag");
|
||||
|
||||
//Przekopiuj kod do ladowania z poprzedniego zadania
|
||||
float quad[] = {
|
||||
-0.5, -0.5, 0, 1,
|
||||
0.5, -0.5, 0, 1,
|
||||
0.5, 0.5, 0, 1,
|
||||
-0.5, 0.5, 0, 1,
|
||||
};
|
||||
unsigned int quadIndexes[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
quadVAO = Core::initVAOIndexed(quad, quadIndexes, 4, 4, 6);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
160
cw 1/src/ex_1_7.hpp
Normal file
160
cw 1/src/ex_1_7.hpp
Normal file
@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <vector>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include "gtc/matrix_transform.hpp"
|
||||
#include "gtc/type_ptr.hpp"
|
||||
|
||||
|
||||
GLuint program; // Shader ID
|
||||
|
||||
GLuint quadVAO;
|
||||
|
||||
glm::vec3 quadPos;
|
||||
float alpha = 0;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
std::vector<glm::vec3> quadsPositions;
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
float time = glfwGetTime();
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
glm::mat4 transformation = glm::mat4(1.0f);
|
||||
/*
|
||||
//Zad 5
|
||||
transformation = glm::translate(transformation, glm::vec3(0.0f, (float)glm::sin(time), 0.0f));
|
||||
transformation = glm::rotate(transformation, time, glm::vec3(0.0, 0.0, 1.0));
|
||||
*/
|
||||
|
||||
//Zad 7b*
|
||||
for (const glm::vec3& pos : quadsPositions) {
|
||||
glm::mat4 currTransform = glm::mat4(1.0f);
|
||||
currTransform = glm::translate(currTransform, pos);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&currTransform);
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
}
|
||||
//Zad 7b* END
|
||||
|
||||
// Zad 6
|
||||
transformation = glm::translate(transformation, quadPos);
|
||||
//Zad 6b*
|
||||
glm::mat4 rotation =
|
||||
{ glm::cos(alpha),-glm::sin(alpha),0,0,
|
||||
-glm::sin(alpha),-glm::cos(alpha),0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1 };
|
||||
rotation = glm::transpose(rotation);
|
||||
|
||||
transformation = transformation * rotation;
|
||||
//Zad 6b* END
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
Core::drawVAOIndexed(quadVAO, 6);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
//zad 7
|
||||
quadPos = glm::vec3(2 * xpos / 500 - 1, -(2*ypos/500 - 1), 0.0f);
|
||||
}
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
printf("%f,%f\n", xpos, ypos);
|
||||
|
||||
if (button == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
|
||||
quadsPositions.push_back(glm::vec3(2 * xpos / 500 - 1, -(2 * ypos / 500 - 1), 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init(GLFWwindow* window) {
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_1_2.vert", "shaders/shader_1_2.frag");
|
||||
|
||||
float points[] = {
|
||||
-0.1,-0.1,0.0,1.0,
|
||||
0.1,-0.1,0.0,1.0,
|
||||
0.1, 0.1,0.0,1.0,
|
||||
-0.1, 0.1,0.0,1.0,
|
||||
};
|
||||
unsigned int indices[] = {
|
||||
0,1,3,
|
||||
1,2,3,
|
||||
};
|
||||
quadVAO = Core::initVAOIndexed(points, indices, 4, 4, 6);
|
||||
|
||||
//Przekopiuj kod do ladowania z poprzedniego zadania
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
//Zad 6
|
||||
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
|
||||
quadPos += glm::vec3(0.0f, 0.001f, 0.0f);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
|
||||
quadPos += glm::vec3(0.0f, -0.001f, 0.0f);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
|
||||
quadPos += glm::vec3(0.001f, 0.0f, 0.0f);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
|
||||
quadPos += glm::vec3(-0.001f, 0.0f, 0.0f);
|
||||
}
|
||||
//zad 6 end
|
||||
//zad 6b*
|
||||
if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
|
||||
alpha += 0.001;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) {
|
||||
alpha -= 0.001;
|
||||
}
|
||||
//zad 6b* END
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
45
cw 1/src/main.cpp
Normal file
45
cw 1/src/main.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "ex_1_1.hpp"
|
||||
|
||||
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
// inicjalizacja glfw
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// tworzenie okna za pomocą glfw
|
||||
GLFWwindow* window = glfwCreateWindow(500, 500, "FirstWindow", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// ladowanie OpenGL za pomoca glew
|
||||
glewInit();
|
||||
glViewport(0, 0, 500, 500);
|
||||
|
||||
init(window);
|
||||
|
||||
// uruchomienie glownej petli
|
||||
renderLoop(window);
|
||||
|
||||
shutdown(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
291
cw 1/src/objload.h
Normal file
291
cw 1/src/objload.h
Normal file
@ -0,0 +1,291 @@
|
||||
/* Copyright (c) 2012, Gerhard Reitmayr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef OBJLOAD_H_
|
||||
#define OBJLOAD_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace obj {
|
||||
|
||||
struct Model {
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, std::vector<unsigned short> > faces; //< assume triangels and uniform indexing
|
||||
};
|
||||
|
||||
struct ObjModel {
|
||||
struct FaceVertex {
|
||||
FaceVertex() : v(-1), t(-1), n(-1) {}
|
||||
int v, t, n;
|
||||
|
||||
bool operator<( const FaceVertex & other ) const;
|
||||
bool operator==( const FaceVertex & other ) const;
|
||||
};
|
||||
|
||||
typedef std::pair<std::vector<FaceVertex>, std::vector<unsigned> > FaceList;
|
||||
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, FaceList > faces;
|
||||
};
|
||||
|
||||
inline ObjModel parseObjModel( std::istream & in);
|
||||
inline void tesselateObjModel( ObjModel & obj);
|
||||
inline ObjModel tesselateObjModel( const ObjModel & obj );
|
||||
inline Model convertToModel( const ObjModel & obj );
|
||||
|
||||
inline Model loadModel( std::istream & in );
|
||||
inline Model loadModelFromString( const std::string & in );
|
||||
inline Model loadModelFromFile( const std::string & in );
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const Model & m );
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f);
|
||||
|
||||
// ---------------------------- Implementation starts here -----------------------
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator<( const ObjModel::FaceVertex & other ) const {
|
||||
return (v < other.v) || (v == other.v && t < other.t ) || (v == other.v && t == other.t && n < other.n);
|
||||
}
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator==( const ObjModel::FaceVertex & other ) const {
|
||||
return (v == other.v && t == other.t && n == other.n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::vector<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.push_back(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::set<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.insert(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
inline std::istream & operator>>( std::istream & in, ObjModel::FaceVertex & f){
|
||||
if(in >> f.v){
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.t;
|
||||
in.clear();
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.n;
|
||||
in.clear();
|
||||
}
|
||||
}
|
||||
in.clear();
|
||||
--f.v;
|
||||
--f.t;
|
||||
--f.n;
|
||||
}
|
||||
// std::cout << f << std::endl;
|
||||
return in;
|
||||
}
|
||||
|
||||
ObjModel parseObjModel( std::istream & in ){
|
||||
char line[1024];
|
||||
std::string op;
|
||||
std::istringstream line_in;
|
||||
std::set<std::string> groups;
|
||||
groups.insert("default");
|
||||
|
||||
ObjModel data;
|
||||
|
||||
while(in.good()){
|
||||
in.getline(line, 1023);
|
||||
line_in.clear();
|
||||
line_in.str(line);
|
||||
|
||||
if(!(line_in >> op))
|
||||
continue;
|
||||
if(op == "v")
|
||||
line_in >> data.vertex >> data.vertex >> data.vertex;
|
||||
else if(op == "vt")
|
||||
line_in >> data.texCoord >> data.texCoord >> data.texCoord;
|
||||
else if(op == "vn")
|
||||
line_in >> data.normal >> data.normal >> data.normal;
|
||||
else if(op == "g"){
|
||||
groups.clear();
|
||||
while(line_in >> groups) ;
|
||||
groups.insert("default");
|
||||
}
|
||||
else if(op == "f") {
|
||||
std::vector<ObjModel::FaceVertex> list;
|
||||
while(line_in >> list) ;
|
||||
|
||||
for(std::set<std::string>::const_iterator g = groups.begin(); g != groups.end(); ++g){
|
||||
ObjModel::FaceList & fl = data.faces[*g];
|
||||
fl.second.push_back(fl.first.size());
|
||||
fl.first.insert(fl.first.end(), list.begin(), list.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = data.faces.begin(); g != data.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
fl.second.push_back(fl.first.size());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
inline void tesselateObjModel( std::vector<ObjModel::FaceVertex> & input, std::vector<unsigned> & input_start){
|
||||
std::vector<ObjModel::FaceVertex> output;
|
||||
std::vector<unsigned> output_start;
|
||||
output.reserve(input.size());
|
||||
output_start.reserve(input_start.size());
|
||||
|
||||
for(std::vector<unsigned>::const_iterator s = input_start.begin(); s != input_start.end() - 1; ++s){
|
||||
const unsigned size = *(s+1) - *s;
|
||||
if(size > 3){
|
||||
const ObjModel::FaceVertex & start_vertex = input[*s];
|
||||
for( int i = 1; i < (int)size-1; ++i){
|
||||
output_start.push_back(output.size());
|
||||
output.push_back(start_vertex);
|
||||
output.push_back(input[*s+i]);
|
||||
output.push_back(input[*s+i+1]);
|
||||
}
|
||||
} else {
|
||||
output_start.push_back(output.size());
|
||||
output.insert(output.end(), input.begin() + *s, input.begin() + *(s+1));
|
||||
}
|
||||
}
|
||||
output_start.push_back(output.size());
|
||||
input.swap(output);
|
||||
input_start.swap(output_start);
|
||||
}
|
||||
|
||||
void tesselateObjModel( ObjModel & obj){
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
tesselateObjModel(fl.first, fl.second);
|
||||
}
|
||||
}
|
||||
|
||||
Model convertToModel( const ObjModel & obj ) {
|
||||
// insert all face vertices into a vector and make unique
|
||||
std::vector<ObjModel::FaceVertex> unique(obj.faces.find("default")->second.first);
|
||||
std::sort(unique.begin(), unique.end());
|
||||
unique.erase( std::unique(unique.begin(), unique.end()), unique.end());
|
||||
|
||||
// build a new model with repeated vertices/texcoords/normals to have single indexing
|
||||
Model model;
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = unique.begin(); f != unique.end(); ++f){
|
||||
model.vertex.insert(model.vertex.end(), obj.vertex.begin() + 3*f->v, obj.vertex.begin() + 3*f->v + 3);
|
||||
if(!obj.texCoord.empty()){
|
||||
const int index = (f->t > -1) ? f->t : f->v;
|
||||
model.texCoord.insert(model.texCoord.end(), obj.texCoord.begin() + 2*index, obj.texCoord.begin() + 2*index + 2);
|
||||
}
|
||||
if(!obj.normal.empty()){
|
||||
const int index = (f->n > -1) ? f->n : f->v;
|
||||
model.normal.insert(model.normal.end(), obj.normal.begin() + 3*index, obj.normal.begin() + 3*index + 3);
|
||||
}
|
||||
}
|
||||
// look up unique index and transform face descriptions
|
||||
for(std::map<std::string, ObjModel::FaceList>::const_iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
const std::string & name = g->first;
|
||||
const ObjModel::FaceList & fl = g->second;
|
||||
std::vector<unsigned short> & v = model.faces[g->first];
|
||||
v.reserve(fl.first.size());
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = fl.first.begin(); f != fl.first.end(); ++f){
|
||||
const unsigned short index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
|
||||
v.push_back(index);
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
ObjModel tesselateObjModel( const ObjModel & obj ){
|
||||
ObjModel result = obj;
|
||||
tesselateObjModel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Model loadModel( std::istream & in ){
|
||||
ObjModel model = parseObjModel(in);
|
||||
tesselateObjModel(model);
|
||||
return convertToModel(model);
|
||||
}
|
||||
|
||||
Model loadModelFromString( const std::string & str ){
|
||||
std::istringstream in(str);
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
Model loadModelFromFile( const std::string & str) {
|
||||
std::ifstream in(str.c_str());
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f){
|
||||
out << f.v << "\t" << f.t << "\t" << f.n;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<( std::ostream & out, const Model & m ){
|
||||
if(!m.vertex.empty()){
|
||||
out << "vertex\n";
|
||||
for(int i = 0; i < (int)m.vertex.size(); ++i)
|
||||
out << m.vertex[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.texCoord.empty()){
|
||||
out << "texCoord\n";
|
||||
for(int i = 0; i < (int)m.texCoord.size(); ++i)
|
||||
out << m.texCoord[i] << (((i % 2) == 1)?"\n":"\t");
|
||||
}
|
||||
if(!m.normal.empty()){
|
||||
out << "normal\n";
|
||||
for(int i = 0; i < (int)m.normal.size(); ++i)
|
||||
out << m.normal[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.faces.empty()){
|
||||
out << "faces\t";
|
||||
for(std::map<std::string, std::vector<unsigned short> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
|
||||
out << g->first << " ";
|
||||
}
|
||||
out << "\n";
|
||||
// for(int i = 0; i < m.face.size(); ++i)
|
||||
// out << m.face[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace obj
|
||||
|
||||
#endif // OBJLOAD_H_
|
30
cw 2/shaders/shader_2_1.frag
Normal file
30
cw 2/shaders/shader_2_1.frag
Normal file
@ -0,0 +1,30 @@
|
||||
#version 430 core
|
||||
|
||||
uniform float time;
|
||||
uniform vec4 background_color;
|
||||
|
||||
flat in vec4 color;
|
||||
out vec4 out_color;
|
||||
in vec4 pos_local;
|
||||
in vec4 pos_global;
|
||||
|
||||
void main()
|
||||
{
|
||||
// out_color = color;
|
||||
// out_color = color / time;
|
||||
// out_color = mix(color, background_color, abs(sin(time / 4.0)));
|
||||
//zad 7
|
||||
// out_color = pos_local;
|
||||
// out_color = pos_global;
|
||||
//zad 8*
|
||||
vec4 final_color = color;
|
||||
|
||||
float stripe_width = 0.04;
|
||||
float stripe_every = 0.1;
|
||||
float stripe = mod(pos_local.x + time * 0.02, stripe_every);
|
||||
//float stripe = mod(pos_local.x, stripe_every);
|
||||
//final_color.rgb *= smoothstep(0.02, 0.2, stripe);
|
||||
float jump_effect = step(stripe, stripe_every - stripe_width) * step(stripe_width, stripe);
|
||||
final_color.rgb *= jump_effect;
|
||||
out_color = final_color;
|
||||
}
|
18
cw 2/shaders/shader_2_1.vert
Normal file
18
cw 2/shaders/shader_2_1.vert
Normal file
@ -0,0 +1,18 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
layout(location = 1) in vec4 vertexColor;
|
||||
|
||||
uniform mat4 transformation;
|
||||
flat out vec4 color;
|
||||
out vec4 pos_local;
|
||||
out vec4 pos_global;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vertexColor;
|
||||
gl_Position = transformation * vertexPosition;
|
||||
|
||||
pos_local = vertexPosition;
|
||||
pos_global = transformation * vertexPosition;
|
||||
}
|
16
cw 2/shaders/shader_2_1b.frag
Normal file
16
cw 2/shaders/shader_2_1b.frag
Normal file
@ -0,0 +1,16 @@
|
||||
#version 430 core
|
||||
out vec4 fragColor;
|
||||
|
||||
in float hue;
|
||||
out vec4 out_color;
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(hsv2rgb(vec3(hue,1,1)), 1.0);
|
||||
}
|
11
cw 2/shaders/shader_2_1b.vert
Normal file
11
cw 2/shaders/shader_2_1b.vert
Normal file
@ -0,0 +1,11 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
layout(location = 1) in float vertexHue;
|
||||
|
||||
out float hue;
|
||||
void main()
|
||||
{
|
||||
hue = vertexHue;
|
||||
gl_Position = vertexPosition;
|
||||
}
|
7
cw 2/shaders/shader_2_2.frag
Normal file
7
cw 2/shaders/shader_2_2.frag
Normal file
@ -0,0 +1,7 @@
|
||||
#version 430 core
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
12
cw 2/shaders/shader_2_2.vert
Normal file
12
cw 2/shaders/shader_2_2.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec2 vertexTexCoord;
|
||||
layout(location = 2) in vec3 vertexNormal;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
7
cw 2/shaders/shader_2_3.frag
Normal file
7
cw 2/shaders/shader_2_3.frag
Normal file
@ -0,0 +1,7 @@
|
||||
#version 430 core
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
13
cw 2/shaders/shader_2_3.vert
Normal file
13
cw 2/shaders/shader_2_3.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec2 vertexTexCoord;
|
||||
layout(location = 2) in vec3 vertexNormal;
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * model * vec4(vertexPosition, 1.0);
|
||||
}
|
55
cw 2/src/Box.cpp
Normal file
55
cw 2/src/Box.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
// dane 36 wierzcholkow i kolorow opisujace model pudelka
|
||||
const float box[] = {
|
||||
|
||||
// points colors
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.2f, 0.0f, 0.2f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.2f, 0.0f, 0.2f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.2f, 0.0f, 0.2f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.2f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.2f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
32
cw 2/src/Camera.cpp
Normal file
32
cw 2/src/Camera.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar)
|
||||
{
|
||||
const float frustumScale = 1.0f;
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = frustumScale;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 2/src/Camera.h
Normal file
14
cw 2/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
36
cw 2/src/Render_Utils.cpp
Normal file
36
cw 2/src/Render_Utils.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
|
||||
|
||||
void Core::DrawContext(Core::RenderContext& context)
|
||||
{
|
||||
|
||||
glBindVertexArray(context.vertexArray);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, // mode
|
||||
context.size, // count
|
||||
GL_UNSIGNED_SHORT, // type
|
||||
(void*)0 // element array buffer offset
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
void Core::deleteVAO(GLuint VAO) {
|
||||
GLint nAttr = 0;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nAttr);
|
||||
glBindVertexArray(VAO);
|
||||
for (int iAttr = 0; iAttr < nAttr; ++iAttr) {
|
||||
GLint vboId = 0;
|
||||
glGetVertexAttribiv(iAttr, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vboId);
|
||||
if (vboId > 0) {
|
||||
GLuint _v = GLuint(vboId);
|
||||
glDeleteBuffers(1, &_v);
|
||||
}
|
||||
}
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
}
|
72
cw 2/src/Render_Utils.h
Normal file
72
cw 2/src/Render_Utils.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "glm.hpp"
|
||||
#include "glew.h"
|
||||
//#include "objload.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
|
||||
struct RenderContext {
|
||||
GLuint vertexArray;
|
||||
GLuint vertexBuffer;
|
||||
GLuint vertexIndexBuffer;
|
||||
unsigned int size = 0;
|
||||
|
||||
void initFromAiMesh(aiMesh* mesh) {
|
||||
vertexArray = 0;
|
||||
vertexBuffer = 0;
|
||||
vertexIndexBuffer = 0;
|
||||
|
||||
|
||||
std::vector<float> textureCoord;
|
||||
std::vector<unsigned int> indices;
|
||||
//tex coord must be converted to 2d vecs
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mTextureCoords[0] != nullptr) {
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].x);
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].y);
|
||||
}
|
||||
else {
|
||||
textureCoord.push_back(0.0f);
|
||||
textureCoord.push_back(0.0f);
|
||||
}
|
||||
}
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
std::cout << "no uv coords\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
unsigned int vertexDataBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexNormalBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexTexBufferSize = sizeof(float) * mesh->mNumVertices * 2;
|
||||
|
||||
}
|
||||
|
||||
~RenderContext() {
|
||||
glDeleteBuffers(1, &vertexBuffer);
|
||||
glDeleteBuffers(1, &vertexIndexBuffer);
|
||||
glDeleteVertexArrays(1, &vertexArray);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void DrawContext(RenderContext& context);
|
||||
|
||||
void deleteVAO(GLuint VAO);
|
||||
}
|
||||
|
102
cw 2/src/Shader_Loader.cpp
Normal file
102
cw 2/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy w linkerze
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 2/src/Shader_Loader.h
Normal file
29
cw 2/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
120
cw 2/src/ex_2_1a.hpp
Normal file
120
cw 2/src/ex_2_1a.hpp
Normal file
@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
|
||||
|
||||
GLuint program;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
glm::vec4 background_color = glm::vec4(0.3, 0.3, 0.5, 1.0);
|
||||
|
||||
GLuint VAO,VBO;
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
float time = glfwGetTime();
|
||||
//glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glClearColor(background_color[0], background_color[1], background_color[2], background_color[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// ZADANIE: W zalaczonym wyzej pliku Box.cpp znajduja sie tablice pozycji i kolorow wierzcholkow prostopadloscianu. Przesun go o wektor (0.5, 0.5, -0.2) i wyswietl go.
|
||||
//
|
||||
// Do shadera uzytego w tym zadaniu nalezy przeslac nie tylko pozycje, ale rowniez kolory wierzcholkow.
|
||||
// W funkcji init należy przesłać pozycje i kolory do GPU
|
||||
|
||||
//Zad 5
|
||||
|
||||
|
||||
glUseProgram(program);
|
||||
glUniform1f(glGetUniformLocation(program, "time"), time);
|
||||
//zad 6*
|
||||
glUniform4fv(glGetUniformLocation(program, "background_color"), 1, (GLfloat*)&background_color);
|
||||
|
||||
|
||||
glm::mat4 transformation = glm::eulerAngleXYZ(1.0f, 0.f, 50.f);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
|
||||
|
||||
// Powiąż stworzone VAO za pomocą funkcji glBindVertexArray
|
||||
glBindVertexArray(VAO);
|
||||
// wykorzystaj glDrawArrays do narysowania prostopadłościanu
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_2_1.vert", "shaders/shader_2_1.frag");
|
||||
// Dokładny opis działania funkcji z poniższych punktów można znaleźć na slajdach z wykładu, w dokumentacji https://www.khronos.org/registry/OpenGL-Refpages/gl4/ funkcje są opisane także na stronach https://learnopengl.com/Getting-started/Hello-Triangle https://learnopengl.com/Getting-started/Shaders oraz https://open.gl/drawing
|
||||
// W tablicy box są pozycje i kolory kostki, celem zajęć jest narysowanie tej kostki
|
||||
// Zainicjalizuj VertexArrayObject (VAO) i zapisz w nim atrybuty prostopadłościanu
|
||||
// I Stwórz VAO
|
||||
// 1. Stwórz nowy VAO za pomocą glGenVertexArrays i przypisz jego adres do zmiennej globalnej
|
||||
glGenVertexArrays(1, &VAO);
|
||||
// 2. Powiąż stworzone VAO za pomocą funkcji glBindVertexArray
|
||||
glBindVertexArray(VAO);
|
||||
// II Zainicjalizuj VBO
|
||||
// 3. Stwórz VertexBufferObject do przechowywania pozycji wierzchołków za pomocą funkcji glGenBuffers
|
||||
glGenBuffers(1, &VBO);
|
||||
// 4. Powiąż stworzone VBO za pomocą funkcji glBindBuffer(GLenum target, GLuint )
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
// 5. Zaalokuj w GPU miejsce na tablice box i zaalakokuj ją za pomocą glBufferData
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(box), box, GL_STATIC_DRAW);
|
||||
//std::cout << sizeof(box);
|
||||
// II Stwórz definicję danych w buforze
|
||||
// 6. Aktywuj atrybut powiązany z pozycją wierchołków za pomocą glEnableVertexAttribArray(GLuint index). Indeks jest zapisany w shaderze wierzchołków w 3. lini. Można odpytać shader o indeks za pomocą funkcji glGetAttribLocation(GL uint program, const GLchar *name)
|
||||
glEnableVertexAttribArray(0);
|
||||
// 6. Aktywuj atrybut powiązany z kolorem wierchołków za pomocą glEnableVertexAttribArray(GLuint index). Indeks jest zapisany w shaderze wierzchołków w 4. lini. Można odpytać shader o indeks za pomocą funkcji glGetAttribLocation(GL uint program, const GLchar *name)
|
||||
glEnableVertexAttribArray(1);
|
||||
// 8. Zdefiniuj jak OpenGL powinien interpretować dane za pomocą glVertexAttribPointer
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (4 * sizeof(float)));
|
||||
// w renderScene!
|
||||
//glBindVertexArray(VAO);
|
||||
///glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// 9. Uwolnij VAO za pomocą funkcji glBindVertexArray(0)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
116
cw 2/src/ex_2_1b.hpp
Normal file
116
cw 2/src/ex_2_1b.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
#include "glew.h"
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
|
||||
float points[] = {
|
||||
0.0f,1.0f,0.f,1.f,
|
||||
0.7818314824680298f,0.6234898018587336f,0.f,1.f,
|
||||
0.9749279121818236f,-0.22252093395631434f,0.f,1.f,
|
||||
0.43388373911755823f,-0.900968867902419f,0.f,1.f,
|
||||
-0.433883739117558f,-0.9009688679024191f,0.f,1.f,
|
||||
-0.9749279121818236f,-0.2225209339563146f,0.f,1.f,
|
||||
-0.7818314824680299f,0.6234898018587334f,0.f,1.f,
|
||||
};
|
||||
float hues[] = {
|
||||
0.0f,
|
||||
0.7142857142857143f,
|
||||
0.42857142857142855f,
|
||||
0.14285714285714285f,
|
||||
0.8571428571428571f,
|
||||
0.5714285714285714f,
|
||||
0.2857142857142857f
|
||||
};
|
||||
unsigned int starIndexed[] = {
|
||||
0, 3, 6, 2, 5, 1, 4
|
||||
};
|
||||
|
||||
|
||||
GLuint program;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
unsigned int VAO;
|
||||
GLuint VBO, EBO;
|
||||
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
// ZADANIE: Powyżej w tablicy points znajdują się wierzchołki 7-kąta foremnego, zadanie polega na narysowaniu gwiazdy siedmioramiennej jak na obrazku zad1b.jpg. Do shadera należy przesłać pozycje wierzchołków i ich odcienie z tablicy hues podobnie jak w zadaniu 1a.
|
||||
// Idealnie rozwiązane zadanie wymaga użycia indeksowania z użyciem Element Buffer Objects oraz trybu rysowania GL_LINE_STRIP
|
||||
// (dodatkowe) Jedna krawędź przechodzi przez wszystkie odcienie zamiast z czerwonego do magenty. Co to powoduje? W jaki sposób byś to naprawił?
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawElements(GL_LINE_STRIP, sizeof(starIndexed), GL_UNSIGNED_INT, 0);
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_2_1b.vert", "shaders/shader_2_1b.frag");
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(hues), points, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(starIndexed), starIndexed, GL_STATIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(hues), hues);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(0));
|
||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 1 * sizeof(float), (void*)(sizeof(points)));
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
107
cw 2/src/ex_2_2.hpp
Normal file
107
cw 2/src/ex_2_2.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
GLuint program;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
|
||||
float cameraAngle = 0;
|
||||
glm::vec3 cameraPos = glm::vec3(-5, 0, 0);
|
||||
glm::vec3 cameraDir;
|
||||
|
||||
|
||||
glm::mat4 createCameraMatrix()
|
||||
{
|
||||
cameraDir = glm::vec3(cosf(cameraAngle), 0.0f, sinf(cameraAngle));
|
||||
glm::vec3 up = glm::vec3(0, 1, 0);
|
||||
|
||||
return Core::createViewMatrix(cameraPos, cameraDir, up);
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
glm::mat4 camera = createCameraMatrix();
|
||||
glm::mat4 perspective = Core::createPerspectiveMatrix();
|
||||
glm::mat4 transformation = perspective * camera;
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_2_2.vert", "shaders/shader_2_2.frag");
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
|
||||
float angleSpeed = 0.1f;
|
||||
float moveSpeed = 0.1f;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
|
||||
cameraAngle -= angleSpeed;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
||||
cameraAngle += angleSpeed;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
|
||||
cameraPos += cameraDir * moveSpeed;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
||||
cameraPos -= cameraDir * moveSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
47
cw 2/src/main.cpp
Normal file
47
cw 2/src/main.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "glew.h"
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include "ex_2_1a.hpp"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// inicjalizacja glfw
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// tworzenie okna za pomocą glfw
|
||||
GLFWwindow* window = glfwCreateWindow(500, 500, "FirstWindow", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// ladowanie OpenGL za pomoca glew
|
||||
glewInit();
|
||||
glViewport(0, 0, 500, 500);
|
||||
|
||||
init(window);
|
||||
|
||||
// uruchomienie glownej petli
|
||||
renderLoop(window);
|
||||
|
||||
shutdown(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
9
cw 3/shaders/shader_2_1.frag
Normal file
9
cw 3/shaders/shader_2_1.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 430 core
|
||||
|
||||
in vec4 color;
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
14
cw 3/shaders/shader_2_1.vert
Normal file
14
cw 3/shaders/shader_2_1.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
layout(location = 1) in vec4 vertexColor;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vertexColor;
|
||||
gl_Position = transformation * vertexPosition;
|
||||
}
|
8
cw 3/shaders/shader_3_1.frag
Normal file
8
cw 3/shaders/shader_3_1.frag
Normal file
@ -0,0 +1,8 @@
|
||||
#version 430 core
|
||||
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(0.9,0.3,1.0, 1.);
|
||||
}
|
12
cw 3/shaders/shader_3_1.vert
Normal file
12
cw 3/shaders/shader_3_1.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
9
cw 3/shaders/shader_3_2.frag
Normal file
9
cw 3/shaders/shader_3_2.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 objectColor;
|
||||
in vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(normal, 1. );
|
||||
}
|
14
cw 3/shaders/shader_3_2.vert
Normal file
14
cw 3/shaders/shader_3_2.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
out vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
normal=vertexNormal;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
55
cw 3/src/Box.cpp
Normal file
55
cw 3/src/Box.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
// dane 36 wierzcholkow i kolorow opisujace model pudelka
|
||||
const float box[] = {
|
||||
|
||||
// points colors
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
31
cw 3/src/Camera.cpp
Normal file
31
cw 3/src/Camera.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar, float frustumScale)
|
||||
{
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = 1.f;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 3/src/Camera.h
Normal file
14
cw 3/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f, float frustumScale = 1.f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
86
cw 3/src/Render_Utils.cpp
Normal file
86
cw 3/src/Render_Utils.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
|
||||
|
||||
void Core::RenderContext::initFromAssimpMesh(aiMesh* mesh) {
|
||||
vertexArray = 0;
|
||||
vertexBuffer = 0;
|
||||
vertexIndexBuffer = 0;
|
||||
|
||||
std::vector<aiVector2D> textureCoord;
|
||||
std::vector<unsigned int> indices;
|
||||
//tex coord must be converted to 2d vecs
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mTextureCoords[0] != nullptr) {
|
||||
//aiVector2D()
|
||||
textureCoord.push_back(aiVector2D(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y));
|
||||
}
|
||||
else {
|
||||
textureCoord.push_back(aiVector2D(0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
std::cout << "no uv coords\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Core::DrawVertexArray(const float * vertexArray, int numVertices, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
}
|
||||
|
||||
void Core::DrawVertexArrayIndexed( const float * vertexArray, const int * indexArray, int numIndexes, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexArray);
|
||||
}
|
||||
|
||||
|
||||
void Core::DrawVertexArray( const VertexData & data )
|
||||
{
|
||||
int numAttribs = std::min(VertexData::MAX_ATTRIBS, data.NumActiveAttribs);
|
||||
for(int i = 0; i < numAttribs; i++)
|
||||
{
|
||||
glVertexAttribPointer(i, data.Attribs[i].Size, GL_FLOAT, false, 0, data.Attribs[i].Pointer);
|
||||
glEnableVertexAttribArray(i);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES, 0, data.NumVertices);
|
||||
}
|
||||
|
||||
void Core::DrawContext(Core::RenderContext& context)
|
||||
{
|
||||
|
||||
glBindVertexArray(context.vertexArray);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, // mode
|
||||
context.size, // count
|
||||
GL_UNSIGNED_INT, // type
|
||||
(void*)0 // element array buffer offset
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
72
cw 3/src/Render_Utils.h
Normal file
72
cw 3/src/Render_Utils.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "glm.hpp"
|
||||
#include "glew.h"
|
||||
#include "objload.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
namespace Core
|
||||
{
|
||||
struct RenderContext
|
||||
{
|
||||
GLuint vertexArray;
|
||||
GLuint vertexBuffer;
|
||||
GLuint vertexIndexBuffer;
|
||||
int size = 0;
|
||||
|
||||
void initFromOBJ(obj::Model& model);
|
||||
|
||||
void initFromAssimpMesh(aiMesh* mesh);
|
||||
};
|
||||
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
void DrawVertexArray(const float * vertexArray, int numVertices, int elementSize);
|
||||
|
||||
// indexArray - jednowymiarowa tablica zawierajaca indeksy wierzcholkow kolejnych trojkatow w jednym ciagu (t1_i1, t1_i2, t1_i3, t2_i1, t2_i2, t2_i3, ...)
|
||||
// numIndexes - liczba indeksow w tablicy indexArray
|
||||
void DrawVertexArrayIndexed(const float * vertexArray, const int * indexArray, int numIndexes, int elementSize);
|
||||
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
const void * Pointer;
|
||||
int Size;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
static const int MAX_ATTRIBS = 8;
|
||||
VertexAttribute Attribs[MAX_ATTRIBS];
|
||||
int NumActiveAttribs;
|
||||
int NumVertices;
|
||||
};
|
||||
|
||||
// Ta funkcja sluzy do rysowania trojkatow, ktorych wierzcholki moga byc opisane wiecej niz jednym atrybutem.
|
||||
// Funkcja przyjmuje jako parametr strukture, w ktorej nalezy zawrzec wszystkie potrzebne dane.
|
||||
//
|
||||
// Przykladowe wywolanie funkcji - narysowanie trojkata jak na pierwszych zajeciach:
|
||||
/*
|
||||
|
||||
const float vertices[] = {
|
||||
0.25f, 0.25f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
Core::VertexData vertexData;
|
||||
vertexData.NumActiveAttribs = 1; // Liczba uzywanych atrybutow wierzcholka
|
||||
vertexData.Attribs[0].Pointer = vertices; // Wskaznik na dane zerowego atrybutu
|
||||
vertexData.Attribs[0].Size = 4; // Wielkosc zerowego atrybutu (ilosc liczb opisujacych ten atrybut w pojedynczym wierzcholku)
|
||||
vertexData.NumVertices = 3; // Liczba wierzcholkow do narysowania
|
||||
Core::DrawVertexArray(vertexData);
|
||||
|
||||
*/
|
||||
void DrawVertexArray(const VertexData & data);
|
||||
|
||||
void DrawContext(RenderContext& context);
|
||||
}
|
102
cw 3/src/Shader_Loader.cpp
Normal file
102
cw 3/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy w linkerze
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 3/src/Shader_Loader.h
Normal file
29
cw 3/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
233
cw 3/src/ex_3_1.hpp
Normal file
233
cw 3/src/ex_3_1.hpp
Normal file
@ -0,0 +1,233 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
GLuint program, program_box;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(-1.f, 0, 0);
|
||||
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
GLuint VAO,VBO;
|
||||
|
||||
float aspectRatio = 1.f;
|
||||
|
||||
std::vector<glm::vec3> quadsPositions = {
|
||||
glm::vec3(0.0, 0.0, 0.0),
|
||||
glm::vec3(0.0, 0.7, 0.0),
|
||||
glm::vec3(0.7, 0.7, 0.7),
|
||||
};
|
||||
|
||||
glm::vec3 p = glm::vec3(0, 0, 0);
|
||||
|
||||
|
||||
glm::mat4 createCameraMatrix(){
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// ! Macierz translation jest definiowana wierszowo dla poprawy czytelnosci. OpenGL i GLM domyslnie stosuje macierze kolumnowe, dlatego musimy ja transponowac !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0, 1, 0)));
|
||||
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir));
|
||||
glm::mat4 cameraRotationMatrix = glm::mat4({
|
||||
cameraSide.x, cameraSide.y, cameraSide.z, 0.,
|
||||
cameraUp.x, cameraUp.y, cameraUp.z, 0.,
|
||||
-cameraDir.x, -cameraDir.y, -cameraDir.z, 0.,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
cameraRotationMatrix = glm::transpose(cameraRotationMatrix);
|
||||
|
||||
//Macierz translacji M_VT otrzymujemy przez translacje o `-cameraPos`
|
||||
glm::mat4 cameraMatrix = cameraRotationMatrix * glm::translate(glm::mat4(1.0), -cameraPos);;
|
||||
|
||||
return cameraMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 createPerspectiveMatrix(float fov, float aspectRatio){
|
||||
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// ! Macierz translation jest definiowana wierszowo dla poprawy czytelnosci. OpenGL i GLM domyslnie stosuje macierze kolumnowe, dlatego musimy ja transponowac !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
float n = 0.1f;
|
||||
//float f = 0.5f;//żeby tylna ściana sześcianu zniknęła
|
||||
float f = 100.f;
|
||||
|
||||
float s = 1 / (glm::tan(fov * glm::pi<float>() / 360));
|
||||
|
||||
//zad 4
|
||||
/*glm::mat4 perspectiveMatrix = glm::mat4({
|
||||
s, 0., 0., 0.,
|
||||
0., s * aspectRatio, 0., 0.,
|
||||
0., 0., (n+f)/(n-f),2*n*f/(n-f),
|
||||
0., 0., -1., 0,
|
||||
});*/
|
||||
//zad 4*
|
||||
float xMult = 1;
|
||||
float yMult = 1;
|
||||
if (aspectRatio > 1) {
|
||||
xMult = 1 / aspectRatio;
|
||||
} else {
|
||||
yMult = aspectRatio;
|
||||
}
|
||||
|
||||
glm::mat4 perspectiveMatrix = glm::mat4({
|
||||
s * xMult, 0., 0., 0.,
|
||||
0., s * yMult, 0., 0.,
|
||||
0., 0., (n + f) / (n - f),2 * n * f / (n - f),
|
||||
0., 0., -1., 0,
|
||||
});
|
||||
|
||||
|
||||
perspectiveMatrix=glm::transpose(perspectiveMatrix);
|
||||
|
||||
return perspectiveMatrix;
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glm::mat4 transformation;
|
||||
|
||||
glUseProgram(program_box);
|
||||
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
float fov = 90;
|
||||
transformation = createPerspectiveMatrix(fov, aspectRatio);
|
||||
//zad 5
|
||||
transformation *= createCameraMatrix();
|
||||
|
||||
//Zad 6
|
||||
for (const glm::vec3& pos : quadsPositions) {
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glm::mat4 currTransform = glm::mat4(1.0f);
|
||||
currTransform *= createPerspectiveMatrix(fov, aspectRatio);
|
||||
currTransform *= createCameraMatrix();
|
||||
|
||||
currTransform *= glm::translate(glm::mat4(1.0f), pos);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program_box, "transformation"), 1, GL_FALSE, (float*)&currTransform);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
//нафига вообще это нужно?
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//glUniformMatrix4fv(glGetUniformLocation(program_box, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
//glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
//glBindVertexArray(0);
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
aspectRatio = width / float(height);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
void loadModelToContext(std::string path, Core::RenderContext& context)
|
||||
{
|
||||
Assimp::Importer import;
|
||||
const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_3_1.vert", "shaders/shader_3_1.frag");
|
||||
program_box = shaderLoader.CreateProgram("shaders/shader_2_1.vert", "shaders/shader_2_1.frag");
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
// 2. Powiąż stworzone VAO za pomocą funkcji glBindVertexArray
|
||||
glBindVertexArray(VAO);
|
||||
// II Zainicjalizuj VBO
|
||||
// 3. Stwórz VertexBufferObject do przechowywania pozycji wierzchołków za pomocą funkcji glGenBuffers
|
||||
glGenBuffers(1, &VBO);
|
||||
// 4. Powiąż stworzone VBO za pomocą funkcji glBindBuffer(GLenum target, GLuint )
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
// 5. Zaalokuj w GPU miejsce na tablice box i zaalakokuj ją za pomocą glBufferData
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(box), box, GL_STATIC_DRAW);
|
||||
// II Stwórz definicję danych w buforze
|
||||
// 6. Aktywuj atrybut powiązany z pozycją wierchołków za pomocą glEnableVertexAttribArray(GLuint index). Indeks jest zapisany w shaderze wierzchołków w 3. lini. Można odpytać shader o indeks za pomocą funkcji glGetAttribLocation(GL uint program, const GLchar *name)
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(4 * sizeof(float)));
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f,1.f,0.f)));
|
||||
float angleSpeed = 0.05f;
|
||||
float moveSpeed = 0.05f;
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
cameraPos += cameraDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
cameraPos -= cameraDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
|
||||
cameraPos -= cameraSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
|
||||
cameraPos += cameraSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
cameraDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(cameraDir, 0));
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
cameraDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(cameraDir, 0));
|
||||
//zad 7*
|
||||
if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS)
|
||||
cameraPos += glm::vec3(0, 1, 0) * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS)
|
||||
cameraPos -= glm::vec3(0, 1, 0) * moveSpeed;
|
||||
|
||||
cameraDir = glm::normalize(p - cameraPos);
|
||||
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
47
cw 3/src/main.cpp
Normal file
47
cw 3/src/main.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "glew.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "ex_3_1.hpp"
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// inicjalizacja glfw
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// tworzenie okna za pomoca glfw
|
||||
GLFWwindow* window = glfwCreateWindow(500, 500, "FirstWindow", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// ladowanie OpenGL za pomoca glew
|
||||
glewInit();
|
||||
glViewport(0, 0, 500, 500);
|
||||
|
||||
init(window);
|
||||
|
||||
// uruchomienie glownej petli
|
||||
renderLoop(window);
|
||||
|
||||
shutdown(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
291
cw 3/src/objload.h
Normal file
291
cw 3/src/objload.h
Normal file
@ -0,0 +1,291 @@
|
||||
/* Copyright (c) 2012, Gerhard Reitmayr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef OBJLOAD_H_
|
||||
#define OBJLOAD_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace obj {
|
||||
|
||||
struct Model {
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, std::vector<unsigned short> > faces; //< assume triangels and uniform indexing
|
||||
};
|
||||
|
||||
struct ObjModel {
|
||||
struct FaceVertex {
|
||||
FaceVertex() : v(-1), t(-1), n(-1) {}
|
||||
int v, t, n;
|
||||
|
||||
bool operator<( const FaceVertex & other ) const;
|
||||
bool operator==( const FaceVertex & other ) const;
|
||||
};
|
||||
|
||||
typedef std::pair<std::vector<FaceVertex>, std::vector<unsigned> > FaceList;
|
||||
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, FaceList > faces;
|
||||
};
|
||||
|
||||
inline ObjModel parseObjModel( std::istream & in);
|
||||
inline void tesselateObjModel( ObjModel & obj);
|
||||
inline ObjModel tesselateObjModel( const ObjModel & obj );
|
||||
inline Model convertToModel( const ObjModel & obj );
|
||||
|
||||
inline Model loadModel( std::istream & in );
|
||||
inline Model loadModelFromString( const std::string & in );
|
||||
inline Model loadModelFromFile( const std::string & in );
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const Model & m );
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f);
|
||||
|
||||
// ---------------------------- Implementation starts here -----------------------
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator<( const ObjModel::FaceVertex & other ) const {
|
||||
return (v < other.v) || (v == other.v && t < other.t ) || (v == other.v && t == other.t && n < other.n);
|
||||
}
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator==( const ObjModel::FaceVertex & other ) const {
|
||||
return (v == other.v && t == other.t && n == other.n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::vector<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.push_back(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::set<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.insert(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
inline std::istream & operator>>( std::istream & in, ObjModel::FaceVertex & f){
|
||||
if(in >> f.v){
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.t;
|
||||
in.clear();
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.n;
|
||||
in.clear();
|
||||
}
|
||||
}
|
||||
in.clear();
|
||||
--f.v;
|
||||
--f.t;
|
||||
--f.n;
|
||||
}
|
||||
// std::cout << f << std::endl;
|
||||
return in;
|
||||
}
|
||||
|
||||
ObjModel parseObjModel( std::istream & in ){
|
||||
char line[1024];
|
||||
std::string op;
|
||||
std::istringstream line_in;
|
||||
std::set<std::string> groups;
|
||||
groups.insert("default");
|
||||
|
||||
ObjModel data;
|
||||
|
||||
while(in.good()){
|
||||
in.getline(line, 1023);
|
||||
line_in.clear();
|
||||
line_in.str(line);
|
||||
|
||||
if(!(line_in >> op))
|
||||
continue;
|
||||
if(op == "v")
|
||||
line_in >> data.vertex >> data.vertex >> data.vertex;
|
||||
else if(op == "vt")
|
||||
line_in >> data.texCoord >> data.texCoord >> data.texCoord;
|
||||
else if(op == "vn")
|
||||
line_in >> data.normal >> data.normal >> data.normal;
|
||||
else if(op == "g"){
|
||||
groups.clear();
|
||||
while(line_in >> groups) ;
|
||||
groups.insert("default");
|
||||
}
|
||||
else if(op == "f") {
|
||||
std::vector<ObjModel::FaceVertex> list;
|
||||
while(line_in >> list) ;
|
||||
|
||||
for(std::set<std::string>::const_iterator g = groups.begin(); g != groups.end(); ++g){
|
||||
ObjModel::FaceList & fl = data.faces[*g];
|
||||
fl.second.push_back(fl.first.size());
|
||||
fl.first.insert(fl.first.end(), list.begin(), list.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = data.faces.begin(); g != data.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
fl.second.push_back(fl.first.size());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
inline void tesselateObjModel( std::vector<ObjModel::FaceVertex> & input, std::vector<unsigned> & input_start){
|
||||
std::vector<ObjModel::FaceVertex> output;
|
||||
std::vector<unsigned> output_start;
|
||||
output.reserve(input.size());
|
||||
output_start.reserve(input_start.size());
|
||||
|
||||
for(std::vector<unsigned>::const_iterator s = input_start.begin(); s != input_start.end() - 1; ++s){
|
||||
const unsigned size = *(s+1) - *s;
|
||||
if(size > 3){
|
||||
const ObjModel::FaceVertex & start_vertex = input[*s];
|
||||
for( int i = 1; i < (int)size-1; ++i){
|
||||
output_start.push_back(output.size());
|
||||
output.push_back(start_vertex);
|
||||
output.push_back(input[*s+i]);
|
||||
output.push_back(input[*s+i+1]);
|
||||
}
|
||||
} else {
|
||||
output_start.push_back(output.size());
|
||||
output.insert(output.end(), input.begin() + *s, input.begin() + *(s+1));
|
||||
}
|
||||
}
|
||||
output_start.push_back(output.size());
|
||||
input.swap(output);
|
||||
input_start.swap(output_start);
|
||||
}
|
||||
|
||||
void tesselateObjModel( ObjModel & obj){
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
tesselateObjModel(fl.first, fl.second);
|
||||
}
|
||||
}
|
||||
|
||||
Model convertToModel( const ObjModel & obj ) {
|
||||
// insert all face vertices into a vector and make unique
|
||||
std::vector<ObjModel::FaceVertex> unique(obj.faces.find("default")->second.first);
|
||||
std::sort(unique.begin(), unique.end());
|
||||
unique.erase( std::unique(unique.begin(), unique.end()), unique.end());
|
||||
|
||||
// build a new model with repeated vertices/texcoords/normals to have single indexing
|
||||
Model model;
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = unique.begin(); f != unique.end(); ++f){
|
||||
model.vertex.insert(model.vertex.end(), obj.vertex.begin() + 3*f->v, obj.vertex.begin() + 3*f->v + 3);
|
||||
if(!obj.texCoord.empty()){
|
||||
const int index = (f->t > -1) ? f->t : f->v;
|
||||
model.texCoord.insert(model.texCoord.end(), obj.texCoord.begin() + 2*index, obj.texCoord.begin() + 2*index + 2);
|
||||
}
|
||||
if(!obj.normal.empty()){
|
||||
const int index = (f->n > -1) ? f->n : f->v;
|
||||
model.normal.insert(model.normal.end(), obj.normal.begin() + 3*index, obj.normal.begin() + 3*index + 3);
|
||||
}
|
||||
}
|
||||
// look up unique index and transform face descriptions
|
||||
for(std::map<std::string, ObjModel::FaceList>::const_iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
const std::string & name = g->first;
|
||||
const ObjModel::FaceList & fl = g->second;
|
||||
std::vector<unsigned short> & v = model.faces[g->first];
|
||||
v.reserve(fl.first.size());
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = fl.first.begin(); f != fl.first.end(); ++f){
|
||||
const unsigned short index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
|
||||
v.push_back(index);
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
ObjModel tesselateObjModel( const ObjModel & obj ){
|
||||
ObjModel result = obj;
|
||||
tesselateObjModel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Model loadModel( std::istream & in ){
|
||||
ObjModel model = parseObjModel(in);
|
||||
tesselateObjModel(model);
|
||||
return convertToModel(model);
|
||||
}
|
||||
|
||||
Model loadModelFromString( const std::string & str ){
|
||||
std::istringstream in(str);
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
Model loadModelFromFile( const std::string & str) {
|
||||
std::ifstream in(str.c_str());
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f){
|
||||
out << f.v << "\t" << f.t << "\t" << f.n;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<( std::ostream & out, const Model & m ){
|
||||
if(!m.vertex.empty()){
|
||||
out << "vertex\n";
|
||||
for(int i = 0; i < (int)m.vertex.size(); ++i)
|
||||
out << m.vertex[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.texCoord.empty()){
|
||||
out << "texCoord\n";
|
||||
for(int i = 0; i < (int)m.texCoord.size(); ++i)
|
||||
out << m.texCoord[i] << (((i % 2) == 1)?"\n":"\t");
|
||||
}
|
||||
if(!m.normal.empty()){
|
||||
out << "normal\n";
|
||||
for(int i = 0; i < (int)m.normal.size(); ++i)
|
||||
out << m.normal[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.faces.empty()){
|
||||
out << "faces\t";
|
||||
for(std::map<std::string, std::vector<unsigned short> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
|
||||
out << g->first << " ";
|
||||
}
|
||||
out << "\n";
|
||||
// for(int i = 0; i < m.face.size(); ++i)
|
||||
// out << m.face[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace obj
|
||||
|
||||
#endif // OBJLOAD_H_
|
9
cw 4/shaders/shader_2_1.frag
Normal file
9
cw 4/shaders/shader_2_1.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 430 core
|
||||
|
||||
in vec4 color;
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = color;
|
||||
}
|
14
cw 4/shaders/shader_2_1.vert
Normal file
14
cw 4/shaders/shader_2_1.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec4 vertexPosition;
|
||||
layout(location = 1) in vec4 vertexColor;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vertexColor;
|
||||
gl_Position = transformation * vertexPosition;
|
||||
}
|
8
cw 4/shaders/shader_3_1.frag
Normal file
8
cw 4/shaders/shader_3_1.frag
Normal file
@ -0,0 +1,8 @@
|
||||
#version 430 core
|
||||
|
||||
|
||||
out vec4 out_color;
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(0.9,0.3,1.0, 1.);
|
||||
}
|
12
cw 4/shaders/shader_3_1.vert
Normal file
12
cw 4/shaders/shader_3_1.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
9
cw 4/shaders/shader_3_2.frag
Normal file
9
cw 4/shaders/shader_3_2.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 objectColor;
|
||||
in vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(normal, 1. );
|
||||
}
|
14
cw 4/shaders/shader_3_2.vert
Normal file
14
cw 4/shaders/shader_3_2.vert
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
out vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
normal=vertexNormal;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
9
cw 4/shaders/shader_4_1.frag
Normal file
9
cw 4/shaders/shader_4_1.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 430 core
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(1,0,1,1);
|
||||
}
|
12
cw 4/shaders/shader_4_1.vert
Normal file
12
cw 4/shaders/shader_4_1.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
55
cw 4/src/Box.cpp
Normal file
55
cw 4/src/Box.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
// dane 36 wierzcholkow i kolorow opisujace model pudelka
|
||||
const float box[] = {
|
||||
|
||||
// points colors
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
31
cw 4/src/Camera.cpp
Normal file
31
cw 4/src/Camera.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar, float frustumScale)
|
||||
{
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = 1.f;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 4/src/Camera.h
Normal file
14
cw 4/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f, float frustumScale = 1.f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
128
cw 4/src/Render_Utils.cpp
Normal file
128
cw 4/src/Render_Utils.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
|
||||
|
||||
void Core::RenderContext::initFromAssimpMesh(aiMesh* mesh) {
|
||||
vertexArray = 0;
|
||||
vertexBuffer = 0;
|
||||
vertexIndexBuffer = 0;
|
||||
|
||||
std::vector<float> textureCoord;
|
||||
std::vector<unsigned int> indices;
|
||||
//tex coord must be converted to 2d vecs
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mTextureCoords[0] != nullptr) {
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].x);
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].y);
|
||||
}
|
||||
else {
|
||||
textureCoord.push_back(0.0f);
|
||||
textureCoord.push_back(0.0f);
|
||||
}
|
||||
}
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
std::cout << "no uv coords\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
unsigned int vertexDataBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexNormalBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexTexBufferSize = sizeof(float) * mesh->mNumVertices * 2;
|
||||
unsigned int vertexTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexBiTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
|
||||
unsigned int vertexElementBufferSize = sizeof(unsigned int) * indices.size();
|
||||
size = indices.size();
|
||||
|
||||
glGenVertexArrays(1, &vertexArray);
|
||||
glBindVertexArray(vertexArray);
|
||||
|
||||
|
||||
glGenBuffers(1, &vertexIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexElementBufferSize, &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
//std::cout << vertexBuffer;
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize + vertexBiTangentBufferSize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexDataBufferSize, mesh->mVertices);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize, vertexNormalBufferSize, mesh->mNormals);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize, vertexTexBufferSize, &textureCoord[0]);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize, vertexTangentBufferSize, mesh->mTangents);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize, vertexBiTangentBufferSize, mesh->mBitangents);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertexNormalBufferSize + vertexDataBufferSize));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize));
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize));
|
||||
|
||||
}
|
||||
|
||||
void Core::DrawVertexArray(const float * vertexArray, int numVertices, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
}
|
||||
|
||||
void Core::DrawVertexArrayIndexed( const float * vertexArray, const int * indexArray, int numIndexes, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexArray);
|
||||
}
|
||||
|
||||
|
||||
void Core::DrawVertexArray( const VertexData & data )
|
||||
{
|
||||
int numAttribs = std::min(VertexData::MAX_ATTRIBS, data.NumActiveAttribs);
|
||||
for(int i = 0; i < numAttribs; i++)
|
||||
{
|
||||
glVertexAttribPointer(i, data.Attribs[i].Size, GL_FLOAT, false, 0, data.Attribs[i].Pointer);
|
||||
glEnableVertexAttribArray(i);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES, 0, data.NumVertices);
|
||||
}
|
||||
|
||||
void Core::DrawContext(Core::RenderContext& context)
|
||||
{
|
||||
|
||||
glBindVertexArray(context.vertexArray);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, // mode
|
||||
context.size, // count
|
||||
GL_UNSIGNED_INT, // type
|
||||
(void*)0 // element array buffer offset
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
71
cw 4/src/Render_Utils.h
Normal file
71
cw 4/src/Render_Utils.h
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
#include "glm.hpp"
|
||||
#include "glew.h"
|
||||
#include "objload.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
namespace Core
|
||||
{
|
||||
struct RenderContext
|
||||
{
|
||||
GLuint vertexArray;
|
||||
GLuint vertexBuffer;
|
||||
GLuint vertexIndexBuffer;
|
||||
int size = 0;
|
||||
|
||||
|
||||
void initFromAssimpMesh(aiMesh* mesh);
|
||||
};
|
||||
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
void DrawVertexArray(const float * vertexArray, int numVertices, int elementSize);
|
||||
|
||||
// indexArray - jednowymiarowa tablica zawierajaca indeksy wierzcholkow kolejnych trojkatow w jednym ciagu (t1_i1, t1_i2, t1_i3, t2_i1, t2_i2, t2_i3, ...)
|
||||
// numIndexes - liczba indeksow w tablicy indexArray
|
||||
void DrawVertexArrayIndexed(const float * vertexArray, const int * indexArray, int numIndexes, int elementSize);
|
||||
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
const void * Pointer;
|
||||
int Size;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
static const int MAX_ATTRIBS = 8;
|
||||
VertexAttribute Attribs[MAX_ATTRIBS];
|
||||
int NumActiveAttribs;
|
||||
int NumVertices;
|
||||
};
|
||||
|
||||
// Ta funkcja sluzy do rysowania trojkatow, ktorych wierzcholki moga byc opisane wiecej niz jednym atrybutem.
|
||||
// Funkcja przyjmuje jako parametr strukture, w ktorej nalezy zawrzec wszystkie potrzebne dane.
|
||||
//
|
||||
// Przykladowe wywolanie funkcji - narysowanie trojkata jak na pierwszych zajeciach:
|
||||
/*
|
||||
|
||||
const float vertices[] = {
|
||||
0.25f, 0.25f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
Core::VertexData vertexData;
|
||||
vertexData.NumActiveAttribs = 1; // Liczba uzywanych atrybutow wierzcholka
|
||||
vertexData.Attribs[0].Pointer = vertices; // Wskaznik na dane zerowego atrybutu
|
||||
vertexData.Attribs[0].Size = 4; // Wielkosc zerowego atrybutu (ilosc liczb opisujacych ten atrybut w pojedynczym wierzcholku)
|
||||
vertexData.NumVertices = 3; // Liczba wierzcholkow do narysowania
|
||||
Core::DrawVertexArray(vertexData);
|
||||
|
||||
*/
|
||||
void DrawVertexArray(const VertexData & data);
|
||||
|
||||
void DrawContext(RenderContext& context);
|
||||
}
|
102
cw 4/src/Shader_Loader.cpp
Normal file
102
cw 4/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy w linkerze
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 4/src/Shader_Loader.h
Normal file
29
cw 4/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
176
cw 4/src/ex_4_1.hpp
Normal file
176
cw 4/src/ex_4_1.hpp
Normal file
@ -0,0 +1,176 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
GLuint program;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
GLuint VAO,VBO;
|
||||
|
||||
float aspectRatio = 1.f;
|
||||
|
||||
glm::vec3 lightColor = glm::vec3(0.9, 0.7, 0.8);
|
||||
|
||||
glm::mat4 createCameraMatrix()
|
||||
{
|
||||
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir,glm::vec3(0.f,1.f,0.f)));
|
||||
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide,cameraDir));
|
||||
//glm::vec3 cameraUp = glm::vec3(0.f, 1.f, 0.f);
|
||||
glm::mat4 cameraRotrationMatrix = glm::mat4({
|
||||
cameraSide.x,cameraSide.y,cameraSide.z,0,
|
||||
cameraUp.x,cameraUp.y,cameraUp.z ,0,
|
||||
-cameraDir.x,-cameraDir.y,-cameraDir.z,0,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
|
||||
cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix);
|
||||
|
||||
glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos);
|
||||
|
||||
//cameraMatrix = glm::mat4({
|
||||
// 1.,0.,0.,cameraPos.x,
|
||||
// 0.,1.,0.,cameraPos.y,
|
||||
// 0.,0.,1.,cameraPos.z,
|
||||
// 0.,0.,0.,1.,
|
||||
// });
|
||||
|
||||
//cameraMatrix = glm::transpose(cameraMatrix);
|
||||
//return Core::createViewMatrix(cameraPos, cameraDir, up);
|
||||
|
||||
return cameraMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 createPerspectiveMatrix()
|
||||
{
|
||||
|
||||
glm::mat4 perspectiveMatrix;
|
||||
float n = 0.05;
|
||||
float f = 20.;
|
||||
float a1 = glm::min(aspectRatio, 1.f);
|
||||
float a2 = glm::min(1 / aspectRatio, 1.f);
|
||||
perspectiveMatrix = glm::mat4({
|
||||
1,0.,0.,0.,
|
||||
0.,1,0.,0.,
|
||||
0.,0.,(f+n) / (n - f),2*f * n / (n - f),
|
||||
0.,0.,-1.,0.,
|
||||
});
|
||||
|
||||
|
||||
perspectiveMatrix=glm::transpose(perspectiveMatrix);
|
||||
|
||||
return perspectiveMatrix;
|
||||
}
|
||||
|
||||
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
|
||||
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
Core::DrawContext(context);
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glm::mat4 transformation;
|
||||
float time = glfwGetTime();
|
||||
|
||||
|
||||
glUseProgram(program);
|
||||
drawObjectColor(sphereContext, glm::mat4(), glm::vec3(0.3, 0.3, 0.2));
|
||||
drawObjectColor(sphereContext, glm::translate(glm::vec3(0, 2, 0)), glm::vec3(0.9, 0.9, 0.2));
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
aspectRatio = width / float(height);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
void loadModelToContext(std::string path, Core::RenderContext& context)
|
||||
{
|
||||
Assimp::Importer import;
|
||||
const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
context.initFromAssimpMesh(scene->mMeshes[0]);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_4_1.vert", "shaders/shader_4_1.frag");
|
||||
|
||||
loadModelToContext("./models/sphere.obj",sphereContext);
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f,1.f,0.f)));
|
||||
float angleSpeed = 0.05f;
|
||||
float moveSpeed = 0.05f;
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
cameraPos += cameraDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
cameraPos -= cameraDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
|
||||
cameraPos += cameraSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
|
||||
cameraPos -= cameraSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
cameraDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(cameraDir, 0));
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
cameraDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(cameraDir, 0));
|
||||
|
||||
//cameraDir = glm::normalize(-cameraPos);
|
||||
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
47
cw 4/src/main.cpp
Normal file
47
cw 4/src/main.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "glew.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "ex_4_1.hpp"
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// inicjalizacja glfw
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// tworzenie okna za pomoca glfw
|
||||
GLFWwindow* window = glfwCreateWindow(500, 500, "FirstWindow", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// ladowanie OpenGL za pomoca glew
|
||||
glewInit();
|
||||
glViewport(0, 0, 500, 500);
|
||||
|
||||
init(window);
|
||||
|
||||
// uruchomienie glownej petli
|
||||
renderLoop(window);
|
||||
|
||||
shutdown(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
291
cw 4/src/objload.h
Normal file
291
cw 4/src/objload.h
Normal file
@ -0,0 +1,291 @@
|
||||
/* Copyright (c) 2012, Gerhard Reitmayr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef OBJLOAD_H_
|
||||
#define OBJLOAD_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace obj {
|
||||
|
||||
struct Model {
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, std::vector<unsigned short> > faces; //< assume triangels and uniform indexing
|
||||
};
|
||||
|
||||
struct ObjModel {
|
||||
struct FaceVertex {
|
||||
FaceVertex() : v(-1), t(-1), n(-1) {}
|
||||
int v, t, n;
|
||||
|
||||
bool operator<( const FaceVertex & other ) const;
|
||||
bool operator==( const FaceVertex & other ) const;
|
||||
};
|
||||
|
||||
typedef std::pair<std::vector<FaceVertex>, std::vector<unsigned> > FaceList;
|
||||
|
||||
std::vector<float> vertex; //< 3 * N entries
|
||||
std::vector<float> texCoord; //< 2 * N entries
|
||||
std::vector<float> normal; //< 3 * N entries
|
||||
|
||||
std::map<std::string, FaceList > faces;
|
||||
};
|
||||
|
||||
inline ObjModel parseObjModel( std::istream & in);
|
||||
inline void tesselateObjModel( ObjModel & obj);
|
||||
inline ObjModel tesselateObjModel( const ObjModel & obj );
|
||||
inline Model convertToModel( const ObjModel & obj );
|
||||
|
||||
inline Model loadModel( std::istream & in );
|
||||
inline Model loadModelFromString( const std::string & in );
|
||||
inline Model loadModelFromFile( const std::string & in );
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const Model & m );
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f);
|
||||
|
||||
// ---------------------------- Implementation starts here -----------------------
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator<( const ObjModel::FaceVertex & other ) const {
|
||||
return (v < other.v) || (v == other.v && t < other.t ) || (v == other.v && t == other.t && n < other.n);
|
||||
}
|
||||
|
||||
inline bool ObjModel::FaceVertex::operator==( const ObjModel::FaceVertex & other ) const {
|
||||
return (v == other.v && t == other.t && n == other.n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::vector<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.push_back(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::istream & operator>>(std::istream & in, std::set<T> & vec ){
|
||||
T temp;
|
||||
if(in >> temp)
|
||||
vec.insert(temp);
|
||||
return in;
|
||||
}
|
||||
|
||||
inline std::istream & operator>>( std::istream & in, ObjModel::FaceVertex & f){
|
||||
if(in >> f.v){
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.t;
|
||||
in.clear();
|
||||
if(in.peek() == '/'){
|
||||
in.get();
|
||||
in >> f.n;
|
||||
in.clear();
|
||||
}
|
||||
}
|
||||
in.clear();
|
||||
--f.v;
|
||||
--f.t;
|
||||
--f.n;
|
||||
}
|
||||
// std::cout << f << std::endl;
|
||||
return in;
|
||||
}
|
||||
|
||||
ObjModel parseObjModel( std::istream & in ){
|
||||
char line[1024];
|
||||
std::string op;
|
||||
std::istringstream line_in;
|
||||
std::set<std::string> groups;
|
||||
groups.insert("default");
|
||||
|
||||
ObjModel data;
|
||||
|
||||
while(in.good()){
|
||||
in.getline(line, 1023);
|
||||
line_in.clear();
|
||||
line_in.str(line);
|
||||
|
||||
if(!(line_in >> op))
|
||||
continue;
|
||||
if(op == "v")
|
||||
line_in >> data.vertex >> data.vertex >> data.vertex;
|
||||
else if(op == "vt")
|
||||
line_in >> data.texCoord >> data.texCoord >> data.texCoord;
|
||||
else if(op == "vn")
|
||||
line_in >> data.normal >> data.normal >> data.normal;
|
||||
else if(op == "g"){
|
||||
groups.clear();
|
||||
while(line_in >> groups) ;
|
||||
groups.insert("default");
|
||||
}
|
||||
else if(op == "f") {
|
||||
std::vector<ObjModel::FaceVertex> list;
|
||||
while(line_in >> list) ;
|
||||
|
||||
for(std::set<std::string>::const_iterator g = groups.begin(); g != groups.end(); ++g){
|
||||
ObjModel::FaceList & fl = data.faces[*g];
|
||||
fl.second.push_back(fl.first.size());
|
||||
fl.first.insert(fl.first.end(), list.begin(), list.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = data.faces.begin(); g != data.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
fl.second.push_back(fl.first.size());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
inline void tesselateObjModel( std::vector<ObjModel::FaceVertex> & input, std::vector<unsigned> & input_start){
|
||||
std::vector<ObjModel::FaceVertex> output;
|
||||
std::vector<unsigned> output_start;
|
||||
output.reserve(input.size());
|
||||
output_start.reserve(input_start.size());
|
||||
|
||||
for(std::vector<unsigned>::const_iterator s = input_start.begin(); s != input_start.end() - 1; ++s){
|
||||
const unsigned size = *(s+1) - *s;
|
||||
if(size > 3){
|
||||
const ObjModel::FaceVertex & start_vertex = input[*s];
|
||||
for( int i = 1; i < (int)size-1; ++i){
|
||||
output_start.push_back(output.size());
|
||||
output.push_back(start_vertex);
|
||||
output.push_back(input[*s+i]);
|
||||
output.push_back(input[*s+i+1]);
|
||||
}
|
||||
} else {
|
||||
output_start.push_back(output.size());
|
||||
output.insert(output.end(), input.begin() + *s, input.begin() + *(s+1));
|
||||
}
|
||||
}
|
||||
output_start.push_back(output.size());
|
||||
input.swap(output);
|
||||
input_start.swap(output_start);
|
||||
}
|
||||
|
||||
void tesselateObjModel( ObjModel & obj){
|
||||
for(std::map<std::string, ObjModel::FaceList>::iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
ObjModel::FaceList & fl = g->second;
|
||||
tesselateObjModel(fl.first, fl.second);
|
||||
}
|
||||
}
|
||||
|
||||
Model convertToModel( const ObjModel & obj ) {
|
||||
// insert all face vertices into a vector and make unique
|
||||
std::vector<ObjModel::FaceVertex> unique(obj.faces.find("default")->second.first);
|
||||
std::sort(unique.begin(), unique.end());
|
||||
unique.erase( std::unique(unique.begin(), unique.end()), unique.end());
|
||||
|
||||
// build a new model with repeated vertices/texcoords/normals to have single indexing
|
||||
Model model;
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = unique.begin(); f != unique.end(); ++f){
|
||||
model.vertex.insert(model.vertex.end(), obj.vertex.begin() + 3*f->v, obj.vertex.begin() + 3*f->v + 3);
|
||||
if(!obj.texCoord.empty()){
|
||||
const int index = (f->t > -1) ? f->t : f->v;
|
||||
model.texCoord.insert(model.texCoord.end(), obj.texCoord.begin() + 2*index, obj.texCoord.begin() + 2*index + 2);
|
||||
}
|
||||
if(!obj.normal.empty()){
|
||||
const int index = (f->n > -1) ? f->n : f->v;
|
||||
model.normal.insert(model.normal.end(), obj.normal.begin() + 3*index, obj.normal.begin() + 3*index + 3);
|
||||
}
|
||||
}
|
||||
// look up unique index and transform face descriptions
|
||||
for(std::map<std::string, ObjModel::FaceList>::const_iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
|
||||
const std::string & name = g->first;
|
||||
const ObjModel::FaceList & fl = g->second;
|
||||
std::vector<unsigned short> & v = model.faces[g->first];
|
||||
v.reserve(fl.first.size());
|
||||
for(std::vector<ObjModel::FaceVertex>::const_iterator f = fl.first.begin(); f != fl.first.end(); ++f){
|
||||
const unsigned short index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
|
||||
v.push_back(index);
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
ObjModel tesselateObjModel( const ObjModel & obj ){
|
||||
ObjModel result = obj;
|
||||
tesselateObjModel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Model loadModel( std::istream & in ){
|
||||
ObjModel model = parseObjModel(in);
|
||||
tesselateObjModel(model);
|
||||
return convertToModel(model);
|
||||
}
|
||||
|
||||
Model loadModelFromString( const std::string & str ){
|
||||
std::istringstream in(str);
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
Model loadModelFromFile( const std::string & str) {
|
||||
std::ifstream in(str.c_str());
|
||||
return loadModel(in);
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<( std::ostream & out, const ObjModel::FaceVertex & f){
|
||||
out << f.v << "\t" << f.t << "\t" << f.n;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<( std::ostream & out, const Model & m ){
|
||||
if(!m.vertex.empty()){
|
||||
out << "vertex\n";
|
||||
for(int i = 0; i < (int)m.vertex.size(); ++i)
|
||||
out << m.vertex[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.texCoord.empty()){
|
||||
out << "texCoord\n";
|
||||
for(int i = 0; i < (int)m.texCoord.size(); ++i)
|
||||
out << m.texCoord[i] << (((i % 2) == 1)?"\n":"\t");
|
||||
}
|
||||
if(!m.normal.empty()){
|
||||
out << "normal\n";
|
||||
for(int i = 0; i < (int)m.normal.size(); ++i)
|
||||
out << m.normal[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
if(!m.faces.empty()){
|
||||
out << "faces\t";
|
||||
for(std::map<std::string, std::vector<unsigned short> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
|
||||
out << g->first << " ";
|
||||
}
|
||||
out << "\n";
|
||||
// for(int i = 0; i < m.face.size(); ++i)
|
||||
// out << m.face[i] << (((i % 3) == 2)?"\n":"\t");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace obj
|
||||
|
||||
#endif // OBJLOAD_H_
|
29
cw 5/shaders/shader_5_1.frag
Normal file
29
cw 5/shaders/shader_5_1.frag
Normal file
@ -0,0 +1,29 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
uniform float time;
|
||||
|
||||
in vec3 vertexNormalOut;
|
||||
out vec3 vertexPosOut;
|
||||
out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normalizedVertexNormal = normalize(vertexNormalOut);
|
||||
float intensity = dot(normalizedVertexNormal, -lightDir);
|
||||
intensity = max(intensity, 0.0);
|
||||
|
||||
vec3 viewDir = normalize(cameraPos - vertexPosOut);
|
||||
vec3 reflectDir = reflect(lightDir, normalizedVertexNormal);
|
||||
|
||||
float glossPow = 8;
|
||||
float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow);
|
||||
|
||||
float diffuse = intensity;
|
||||
//outColor = vec4(lightColor * (color * diffuse + specular ), 1.0);
|
||||
outColor = vec4(1.0);
|
||||
}
|
19
cw 5/shaders/shader_5_1.vert
Normal file
19
cw 5/shaders/shader_5_1.vert
Normal file
@ -0,0 +1,19 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 modelMat;
|
||||
|
||||
out vec3 vertexNormalOut;
|
||||
out vec3 vertexPosOut;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0);
|
||||
vertexNormalOut = worldNormal.xyz;
|
||||
vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
||||
}
|
12
cw 5/shaders/shader_5_sun.frag
Normal file
12
cw 5/shaders/shader_5_sun.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
in vec3 interpNormal;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = vec4(color, 1.0);
|
||||
}
|
15
cw 5/shaders/shader_5_sun.vert
Normal file
15
cw 5/shaders/shader_5_sun.vert
Normal file
@ -0,0 +1,15 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
|
||||
}
|
55
cw 5/src/Box.cpp
Normal file
55
cw 5/src/Box.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
// dane 36 wierzcholkow i kolorow opisujace model pudelka
|
||||
const float box[] = {
|
||||
|
||||
// points colors
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, 0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.25f, 0.25f, -0.75f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
|
||||
0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, -0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.75f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
31
cw 5/src/Camera.cpp
Normal file
31
cw 5/src/Camera.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "Camera.h"
|
||||
|
||||
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar, float frustumScale)
|
||||
{
|
||||
glm::mat4 perspective;
|
||||
perspective[0][0] = 1.f;
|
||||
perspective[1][1] = frustumScale;
|
||||
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
|
||||
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
|
||||
perspective[2][3] = -1;
|
||||
perspective[3][3] = 0;
|
||||
|
||||
return perspective;
|
||||
}
|
||||
|
||||
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
|
||||
{
|
||||
glm::vec3 side = glm::cross(forward, up);
|
||||
|
||||
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
|
||||
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
|
||||
glm::mat4 cameraRotation;
|
||||
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
|
||||
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
|
||||
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
|
||||
|
||||
glm::mat4 cameraTranslation;
|
||||
cameraTranslation[3] = glm::vec4(-position, 1.0f);
|
||||
|
||||
return cameraRotation * cameraTranslation;
|
||||
}
|
14
cw 5/src/Camera.h
Normal file
14
cw 5/src/Camera.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f, float frustumScale = 1.f);
|
||||
|
||||
// position - pozycja kamery
|
||||
// forward - wektor "do przodu" kamery (jednostkowy)
|
||||
// up - wektor "w gore" kamery (jednostkowy)
|
||||
// up i forward musza byc ortogonalne!
|
||||
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
|
||||
}
|
128
cw 5/src/Render_Utils.cpp
Normal file
128
cw 5/src/Render_Utils.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "Render_Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
|
||||
|
||||
void Core::RenderContext::initFromAssimpMesh(aiMesh* mesh) {
|
||||
vertexArray = 0;
|
||||
vertexBuffer = 0;
|
||||
vertexIndexBuffer = 0;
|
||||
|
||||
std::vector<float> textureCoord;
|
||||
std::vector<unsigned int> indices;
|
||||
//tex coord must be converted to 2d vecs
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
if (mesh->mTextureCoords[0] != nullptr) {
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].x);
|
||||
textureCoord.push_back(mesh->mTextureCoords[0][i].y);
|
||||
}
|
||||
else {
|
||||
textureCoord.push_back(0.0f);
|
||||
textureCoord.push_back(0.0f);
|
||||
}
|
||||
}
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
std::cout << "no uv coords\n";
|
||||
}
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
unsigned int vertexDataBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexNormalBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexTexBufferSize = sizeof(float) * mesh->mNumVertices * 2;
|
||||
unsigned int vertexTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
unsigned int vertexBiTangentBufferSize = sizeof(float) * mesh->mNumVertices * 3;
|
||||
|
||||
unsigned int vertexElementBufferSize = sizeof(unsigned int) * indices.size();
|
||||
size = indices.size();
|
||||
|
||||
glGenVertexArrays(1, &vertexArray);
|
||||
glBindVertexArray(vertexArray);
|
||||
|
||||
|
||||
glGenBuffers(1, &vertexIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexElementBufferSize, &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
//std::cout << vertexBuffer;
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize + vertexBiTangentBufferSize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexDataBufferSize, mesh->mVertices);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize, vertexNormalBufferSize, mesh->mNormals);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize, vertexTexBufferSize, &textureCoord[0]);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize, vertexTangentBufferSize, mesh->mTangents);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize, vertexBiTangentBufferSize, mesh->mBitangents);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertexNormalBufferSize + vertexDataBufferSize));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize));
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertexDataBufferSize + vertexNormalBufferSize + vertexTexBufferSize + vertexTangentBufferSize));
|
||||
|
||||
}
|
||||
|
||||
void Core::DrawVertexArray(const float * vertexArray, int numVertices, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
}
|
||||
|
||||
void Core::DrawVertexArrayIndexed( const float * vertexArray, const int * indexArray, int numIndexes, int elementSize )
|
||||
{
|
||||
glVertexAttribPointer(0, elementSize, GL_FLOAT, false, 0, vertexArray);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexArray);
|
||||
}
|
||||
|
||||
|
||||
void Core::DrawVertexArray( const VertexData & data )
|
||||
{
|
||||
int numAttribs = std::min(VertexData::MAX_ATTRIBS, data.NumActiveAttribs);
|
||||
for(int i = 0; i < numAttribs; i++)
|
||||
{
|
||||
glVertexAttribPointer(i, data.Attribs[i].Size, GL_FLOAT, false, 0, data.Attribs[i].Pointer);
|
||||
glEnableVertexAttribArray(i);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES, 0, data.NumVertices);
|
||||
}
|
||||
|
||||
void Core::DrawContext(Core::RenderContext& context)
|
||||
{
|
||||
|
||||
glBindVertexArray(context.vertexArray);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES, // mode
|
||||
context.size, // count
|
||||
GL_UNSIGNED_INT, // type
|
||||
(void*)0 // element array buffer offset
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
72
cw 5/src/Render_Utils.h
Normal file
72
cw 5/src/Render_Utils.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "glm.hpp"
|
||||
#include "glew.h"
|
||||
#include "objload.h"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
namespace Core
|
||||
{
|
||||
struct RenderContext
|
||||
{
|
||||
GLuint vertexArray;
|
||||
GLuint vertexBuffer;
|
||||
GLuint vertexIndexBuffer;
|
||||
int size = 0;
|
||||
|
||||
void initFromOBJ(obj::Model& model);
|
||||
|
||||
void initFromAssimpMesh(aiMesh* mesh);
|
||||
};
|
||||
|
||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||
// numVertices - liczba wierzcholkow do narysowania
|
||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||
void DrawVertexArray(const float * vertexArray, int numVertices, int elementSize);
|
||||
|
||||
// indexArray - jednowymiarowa tablica zawierajaca indeksy wierzcholkow kolejnych trojkatow w jednym ciagu (t1_i1, t1_i2, t1_i3, t2_i1, t2_i2, t2_i3, ...)
|
||||
// numIndexes - liczba indeksow w tablicy indexArray
|
||||
void DrawVertexArrayIndexed(const float * vertexArray, const int * indexArray, int numIndexes, int elementSize);
|
||||
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
const void * Pointer;
|
||||
int Size;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
static const int MAX_ATTRIBS = 8;
|
||||
VertexAttribute Attribs[MAX_ATTRIBS];
|
||||
int NumActiveAttribs;
|
||||
int NumVertices;
|
||||
};
|
||||
|
||||
// Ta funkcja sluzy do rysowania trojkatow, ktorych wierzcholki moga byc opisane wiecej niz jednym atrybutem.
|
||||
// Funkcja przyjmuje jako parametr strukture, w ktorej nalezy zawrzec wszystkie potrzebne dane.
|
||||
//
|
||||
// Przykladowe wywolanie funkcji - narysowanie trojkata jak na pierwszych zajeciach:
|
||||
/*
|
||||
|
||||
const float vertices[] = {
|
||||
0.25f, 0.25f, 0.0f, 1.0f,
|
||||
0.25f, -0.25f, 0.0f, 1.0f,
|
||||
-0.25f, -0.25f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
Core::VertexData vertexData;
|
||||
vertexData.NumActiveAttribs = 1; // Liczba uzywanych atrybutow wierzcholka
|
||||
vertexData.Attribs[0].Pointer = vertices; // Wskaznik na dane zerowego atrybutu
|
||||
vertexData.Attribs[0].Size = 4; // Wielkosc zerowego atrybutu (ilosc liczb opisujacych ten atrybut w pojedynczym wierzcholku)
|
||||
vertexData.NumVertices = 3; // Liczba wierzcholkow do narysowania
|
||||
Core::DrawVertexArray(vertexData);
|
||||
|
||||
*/
|
||||
void DrawVertexArray(const VertexData & data);
|
||||
|
||||
void DrawContext(RenderContext& context);
|
||||
}
|
2024
cw 5/src/SOIL/SOIL.c
Normal file
2024
cw 5/src/SOIL/SOIL.c
Normal file
File diff suppressed because it is too large
Load Diff
433
cw 5/src/SOIL/SOIL.h
Normal file
433
cw 5/src/SOIL/SOIL.h
Normal file
@ -0,0 +1,433 @@
|
||||
/**
|
||||
@mainpage SOIL
|
||||
|
||||
Jonathan Dummer
|
||||
2007-07-26-10.36
|
||||
|
||||
Simple OpenGL Image Library
|
||||
|
||||
A tiny c library for uploading images as
|
||||
textures into OpenGL. Also saving and
|
||||
loading of images is supported.
|
||||
|
||||
I'm using Sean's Tool Box image loader as a base:
|
||||
http://www.nothings.org/
|
||||
|
||||
I'm upgrading it to load TGA and DDS files, and a direct
|
||||
path for loading DDS files straight into OpenGL textures,
|
||||
when applicable.
|
||||
|
||||
Image Formats:
|
||||
- BMP load & save
|
||||
- TGA load & save
|
||||
- DDS load & save
|
||||
- PNG load
|
||||
- JPG load
|
||||
|
||||
OpenGL Texture Features:
|
||||
- resample to power-of-two sizes
|
||||
- MIPmap generation
|
||||
- compressed texture S3TC formats (if supported)
|
||||
- can pre-multiply alpha for you, for better compositing
|
||||
- can flip image about the y-axis (except pre-compressed DDS files)
|
||||
|
||||
Thanks to:
|
||||
* Sean Barret - for the awesome stb_image
|
||||
* Dan Venkitachalam - for finding some non-compliant DDS files, and patching some explicit casts
|
||||
* everybody at gamedev.net
|
||||
**/
|
||||
|
||||
#ifndef HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY
|
||||
#define HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
The format of images that may be loaded (force_channels).
|
||||
SOIL_LOAD_AUTO leaves the image in whatever format it was found.
|
||||
SOIL_LOAD_L forces the image to load as Luminous (greyscale)
|
||||
SOIL_LOAD_LA forces the image to load as Luminous with Alpha
|
||||
SOIL_LOAD_RGB forces the image to load as Red Green Blue
|
||||
SOIL_LOAD_RGBA forces the image to load as Red Green Blue Alpha
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_LOAD_AUTO = 0,
|
||||
SOIL_LOAD_L = 1,
|
||||
SOIL_LOAD_LA = 2,
|
||||
SOIL_LOAD_RGB = 3,
|
||||
SOIL_LOAD_RGBA = 4
|
||||
};
|
||||
|
||||
/**
|
||||
Passed in as reuse_texture_ID, will cause SOIL to
|
||||
register a new texture ID using glGenTextures().
|
||||
If the value passed into reuse_texture_ID > 0 then
|
||||
SOIL will just re-use that texture ID (great for
|
||||
reloading image assets in-game!)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_CREATE_NEW_ID = 0
|
||||
};
|
||||
|
||||
/**
|
||||
flags you can pass into SOIL_load_OGL_texture()
|
||||
and SOIL_create_OGL_texture().
|
||||
(note that if SOIL_FLAG_DDS_LOAD_DIRECT is used
|
||||
the rest of the flags with the exception of
|
||||
SOIL_FLAG_TEXTURE_REPEATS will be ignored while
|
||||
loading already-compressed DDS files.)
|
||||
|
||||
SOIL_FLAG_POWER_OF_TWO: force the image to be POT
|
||||
SOIL_FLAG_MIPMAPS: generate mipmaps for the texture
|
||||
SOIL_FLAG_TEXTURE_REPEATS: otherwise will clamp
|
||||
SOIL_FLAG_MULTIPLY_ALPHA: for using (GL_ONE,GL_ONE_MINUS_SRC_ALPHA) blending
|
||||
SOIL_FLAG_INVERT_Y: flip the image vertically
|
||||
SOIL_FLAG_COMPRESS_TO_DXT: if the card can display them, will convert RGB to DXT1, RGBA to DXT5
|
||||
SOIL_FLAG_DDS_LOAD_DIRECT: will load DDS files directly without _ANY_ additional processing
|
||||
SOIL_FLAG_NTSC_SAFE_RGB: clamps RGB components to the range [16,235]
|
||||
SOIL_FLAG_CoCg_Y: Google YCoCg; RGB=>CoYCg, RGBA=>CoCgAY
|
||||
SOIL_FLAG_TEXTURE_RECTANGE: uses ARB_texture_rectangle ; pixel indexed & no repeat or MIPmaps or cubemaps
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_FLAG_POWER_OF_TWO = 1,
|
||||
SOIL_FLAG_MIPMAPS = 2,
|
||||
SOIL_FLAG_TEXTURE_REPEATS = 4,
|
||||
SOIL_FLAG_MULTIPLY_ALPHA = 8,
|
||||
SOIL_FLAG_INVERT_Y = 16,
|
||||
SOIL_FLAG_COMPRESS_TO_DXT = 32,
|
||||
SOIL_FLAG_DDS_LOAD_DIRECT = 64,
|
||||
SOIL_FLAG_NTSC_SAFE_RGB = 128,
|
||||
SOIL_FLAG_CoCg_Y = 256,
|
||||
SOIL_FLAG_TEXTURE_RECTANGLE = 512
|
||||
};
|
||||
|
||||
/**
|
||||
The types of images that may be saved.
|
||||
(TGA supports uncompressed RGB / RGBA)
|
||||
(BMP supports uncompressed RGB)
|
||||
(DDS supports DXT1 and DXT5)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_SAVE_TYPE_TGA = 0,
|
||||
SOIL_SAVE_TYPE_BMP = 1,
|
||||
SOIL_SAVE_TYPE_DDS = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Defines the order of faces in a DDS cubemap.
|
||||
I recommend that you use the same order in single
|
||||
image cubemap files, so they will be interchangeable
|
||||
with DDS cubemaps when using SOIL.
|
||||
**/
|
||||
#define SOIL_DDS_CUBEMAP_FACE_ORDER "EWUDNS"
|
||||
|
||||
/**
|
||||
The types of internal fake HDR representations
|
||||
|
||||
SOIL_HDR_RGBE: RGB * pow( 2.0, A - 128.0 )
|
||||
SOIL_HDR_RGBdivA: RGB / A
|
||||
SOIL_HDR_RGBdivA2: RGB / (A*A)
|
||||
**/
|
||||
enum
|
||||
{
|
||||
SOIL_HDR_RGBE = 0,
|
||||
SOIL_HDR_RGBdivA = 1,
|
||||
SOIL_HDR_RGBdivA2 = 2
|
||||
};
|
||||
|
||||
/**
|
||||
Loads an image from disk into an OpenGL texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_texture
|
||||
(
|
||||
const char *filename,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 6 images from disk into an OpenGL cubemap texture.
|
||||
\param x_pos_file the name of the file to upload as the +x cube face
|
||||
\param x_neg_file the name of the file to upload as the -x cube face
|
||||
\param y_pos_file the name of the file to upload as the +y cube face
|
||||
\param y_neg_file the name of the file to upload as the -y cube face
|
||||
\param z_pos_file the name of the file to upload as the +z cube face
|
||||
\param z_neg_file the name of the file to upload as the -z cube face
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_cubemap
|
||||
(
|
||||
const char *x_pos_file,
|
||||
const char *x_neg_file,
|
||||
const char *y_pos_file,
|
||||
const char *y_neg_file,
|
||||
const char *z_pos_file,
|
||||
const char *z_neg_file,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 1 image from disk and splits it into an OpenGL cubemap texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc.
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_single_cubemap
|
||||
(
|
||||
const char *filename,
|
||||
const char face_order[6],
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an HDR image from disk into an OpenGL texture.
|
||||
\param filename the name of the file to upload as a texture
|
||||
\param fake_HDR_format SOIL_HDR_RGBE, SOIL_HDR_RGBdivA, SOIL_HDR_RGBdivA2
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_HDR_texture
|
||||
(
|
||||
const char *filename,
|
||||
int fake_HDR_format,
|
||||
int rescale_to_max,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from RAM into an OpenGL texture.
|
||||
\param buffer the image data in RAM just as if it were still in a file
|
||||
\param buffer_length the size of the buffer in bytes
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_texture_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 6 images from memory into an OpenGL cubemap texture.
|
||||
\param x_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param x_pos_buffer_length the size of the above buffer
|
||||
\param x_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param x_neg_buffer_length the size of the above buffer
|
||||
\param y_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param y_pos_buffer_length the size of the above buffer
|
||||
\param y_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param y_neg_buffer_length the size of the above buffer
|
||||
\param z_pos_buffer the image data in RAM to upload as the +x cube face
|
||||
\param z_pos_buffer_length the size of the above buffer
|
||||
\param z_neg_buffer the image data in RAM to upload as the +x cube face
|
||||
\param z_neg_buffer_length the size of the above buffer
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_cubemap_from_memory
|
||||
(
|
||||
const unsigned char *const x_pos_buffer,
|
||||
int x_pos_buffer_length,
|
||||
const unsigned char *const x_neg_buffer,
|
||||
int x_neg_buffer_length,
|
||||
const unsigned char *const y_pos_buffer,
|
||||
int y_pos_buffer_length,
|
||||
const unsigned char *const y_neg_buffer,
|
||||
int y_neg_buffer_length,
|
||||
const unsigned char *const z_pos_buffer,
|
||||
int z_pos_buffer_length,
|
||||
const unsigned char *const z_neg_buffer,
|
||||
int z_neg_buffer_length,
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Loads 1 image from RAM and splits it into an OpenGL cubemap texture.
|
||||
\param buffer the image data in RAM just as if it were still in a file
|
||||
\param buffer_length the size of the buffer in bytes
|
||||
\param face_order the order of the faces in the file, any combination of NSWEUD, for North, South, Up, etc.
|
||||
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_load_OGL_single_cubemap_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
const char face_order[6],
|
||||
int force_channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a 2D OpenGL texture from raw image data. Note that the raw data is
|
||||
_NOT_ freed after the upload (so the user can load various versions).
|
||||
\param data the raw data to be uploaded as an OpenGL texture
|
||||
\param width the width of the image in pixels
|
||||
\param height the height of the image in pixels
|
||||
\param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_create_OGL_texture
|
||||
(
|
||||
const unsigned char *const data,
|
||||
int width, int height, int channels,
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Creates an OpenGL cubemap texture by splitting up 1 image into 6 parts.
|
||||
\param data the raw data to be uploaded as an OpenGL texture
|
||||
\param width the width of the image in pixels
|
||||
\param height the height of the image in pixels
|
||||
\param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
|
||||
\param face_order the order of the faces in the file, and combination of NSWEUD, for North, South, Up, etc.
|
||||
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
|
||||
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
|
||||
\return 0-failed, otherwise returns the OpenGL texture handle
|
||||
**/
|
||||
unsigned int
|
||||
SOIL_create_OGL_single_cubemap
|
||||
(
|
||||
const unsigned char *const data,
|
||||
int width, int height, int channels,
|
||||
const char face_order[6],
|
||||
unsigned int reuse_texture_ID,
|
||||
unsigned int flags
|
||||
);
|
||||
|
||||
/**
|
||||
Captures the OpenGL window (RGB) and saves it to disk
|
||||
\return 0 if it failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
SOIL_save_screenshot
|
||||
(
|
||||
const char *filename,
|
||||
int image_type,
|
||||
int x, int y,
|
||||
int width, int height
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from disk into an array of unsigned chars.
|
||||
Note that *channels return the original channel count of the
|
||||
image. If force_channels was other than SOIL_LOAD_AUTO,
|
||||
the resulting image has force_channels, but *channels may be
|
||||
different (if the original image had a different channel
|
||||
count).
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
unsigned char*
|
||||
SOIL_load_image
|
||||
(
|
||||
const char *filename,
|
||||
int *width, int *height, int *channels,
|
||||
int force_channels
|
||||
);
|
||||
|
||||
/**
|
||||
Loads an image from memory into an array of unsigned chars.
|
||||
Note that *channels return the original channel count of the
|
||||
image. If force_channels was other than SOIL_LOAD_AUTO,
|
||||
the resulting image has force_channels, but *channels may be
|
||||
different (if the original image had a different channel
|
||||
count).
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
unsigned char*
|
||||
SOIL_load_image_from_memory
|
||||
(
|
||||
const unsigned char *const buffer,
|
||||
int buffer_length,
|
||||
int *width, int *height, int *channels,
|
||||
int force_channels
|
||||
);
|
||||
|
||||
/**
|
||||
Saves an image from an array of unsigned chars (RGBA) to disk
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
SOIL_save_image
|
||||
(
|
||||
const char *filename,
|
||||
int image_type,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
);
|
||||
|
||||
/**
|
||||
Frees the image data (note, this is just C's "free()"...this function is
|
||||
present mostly so C++ programmers don't forget to use "free()" and call
|
||||
"delete []" instead [8^)
|
||||
**/
|
||||
void
|
||||
SOIL_free_image_data
|
||||
(
|
||||
unsigned char *img_data
|
||||
);
|
||||
|
||||
/**
|
||||
This function resturn a pointer to a string describing the last thing
|
||||
that happened inside SOIL. It can be used to determine why an image
|
||||
failed to load.
|
||||
**/
|
||||
const char*
|
||||
SOIL_last_result
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_SIMPLE_OPENGL_IMAGE_LIBRARY */
|
632
cw 5/src/SOIL/image_DXT.c
Normal file
632
cw 5/src/SOIL/image_DXT.c
Normal file
@ -0,0 +1,632 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
2007-07-31-10.32
|
||||
|
||||
simple DXT compression / decompression code
|
||||
|
||||
public domain
|
||||
*/
|
||||
|
||||
#include "image_DXT.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* set this =1 if you want to use the covarince matrix method...
|
||||
which is better than my method of using standard deviations
|
||||
overall, except on the infintesimal chance that the power
|
||||
method fails for finding the largest eigenvector */
|
||||
#define USE_COV_MAT 1
|
||||
|
||||
/********* Function Prototypes *********/
|
||||
/*
|
||||
Takes a 4x4 block of pixels and compresses it into 8 bytes
|
||||
in DXT1 format (color only, no alpha). Speed is valued
|
||||
over prettyness, at least for now.
|
||||
*/
|
||||
void compress_DDS_color_block(
|
||||
int channels,
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8] );
|
||||
/*
|
||||
Takes a 4x4 block of pixels and compresses the alpha
|
||||
component it into 8 bytes for use in DXT5 DDS files.
|
||||
Speed is valued over prettyness, at least for now.
|
||||
*/
|
||||
void compress_DDS_alpha_block(
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8] );
|
||||
|
||||
/********* Actual Exposed Functions *********/
|
||||
int
|
||||
save_image_as_DDS
|
||||
(
|
||||
const char *filename,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
FILE *fout;
|
||||
unsigned char *DDS_data;
|
||||
DDS_header header;
|
||||
int DDS_size;
|
||||
/* error check */
|
||||
if( (NULL == filename) ||
|
||||
(width < 1) || (height < 1) ||
|
||||
(channels < 1) || (channels > 4) ||
|
||||
(data == NULL ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Convert the image */
|
||||
if( (channels & 1) == 1 )
|
||||
{
|
||||
/* no alpha, just use DXT1 */
|
||||
DDS_data = convert_image_to_DXT1( data, width, height, channels, &DDS_size );
|
||||
} else
|
||||
{
|
||||
/* has alpha, so use DXT5 */
|
||||
DDS_data = convert_image_to_DXT5( data, width, height, channels, &DDS_size );
|
||||
}
|
||||
/* save it */
|
||||
memset( &header, 0, sizeof( DDS_header ) );
|
||||
header.dwMagic = ('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24);
|
||||
header.dwSize = 124;
|
||||
header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_LINEARSIZE;
|
||||
header.dwWidth = width;
|
||||
header.dwHeight = height;
|
||||
header.dwPitchOrLinearSize = DDS_size;
|
||||
header.sPixelFormat.dwSize = 32;
|
||||
header.sPixelFormat.dwFlags = DDPF_FOURCC;
|
||||
if( (channels & 1) == 1 )
|
||||
{
|
||||
header.sPixelFormat.dwFourCC = ('D' << 0) | ('X' << 8) | ('T' << 16) | ('1' << 24);
|
||||
} else
|
||||
{
|
||||
header.sPixelFormat.dwFourCC = ('D' << 0) | ('X' << 8) | ('T' << 16) | ('5' << 24);
|
||||
}
|
||||
header.sCaps.dwCaps1 = DDSCAPS_TEXTURE;
|
||||
/* write it out */
|
||||
fout = fopen( filename, "wb");
|
||||
fwrite( &header, sizeof( DDS_header ), 1, fout );
|
||||
fwrite( DDS_data, 1, DDS_size, fout );
|
||||
fclose( fout );
|
||||
/* done */
|
||||
free( DDS_data );
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char* convert_image_to_DXT1(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size )
|
||||
{
|
||||
unsigned char *compressed;
|
||||
int i, j, x, y;
|
||||
unsigned char ublock[16*3];
|
||||
unsigned char cblock[8];
|
||||
int index = 0, chan_step = 1;
|
||||
int block_count = 0;
|
||||
/* error check */
|
||||
*out_size = 0;
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(NULL == uncompressed) ||
|
||||
(channels < 1) || (channels > 4) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* for channels == 1 or 2, I do not step forward for R,G,B values */
|
||||
if( channels < 3 )
|
||||
{
|
||||
chan_step = 0;
|
||||
}
|
||||
/* get the RAM for the compressed image
|
||||
(8 bytes per 4x4 pixel block) */
|
||||
*out_size = ((width+3) >> 2) * ((height+3) >> 2) * 8;
|
||||
compressed = (unsigned char*)malloc( *out_size );
|
||||
/* go through each block */
|
||||
for( j = 0; j < height; j += 4 )
|
||||
{
|
||||
for( i = 0; i < width; i += 4 )
|
||||
{
|
||||
/* copy this block into a new one */
|
||||
int idx = 0;
|
||||
int mx = 4, my = 4;
|
||||
if( j+4 >= height )
|
||||
{
|
||||
my = height - j;
|
||||
}
|
||||
if( i+4 >= width )
|
||||
{
|
||||
mx = width - i;
|
||||
}
|
||||
for( y = 0; y < my; ++y )
|
||||
{
|
||||
for( x = 0; x < mx; ++x )
|
||||
{
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step+chan_step];
|
||||
}
|
||||
for( x = mx; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
}
|
||||
}
|
||||
for( y = my; y < 4; ++y )
|
||||
{
|
||||
for( x = 0; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
}
|
||||
}
|
||||
/* compress the block */
|
||||
++block_count;
|
||||
compress_DDS_color_block( 3, ublock, cblock );
|
||||
/* copy the data from the block into the main block */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return compressed;
|
||||
}
|
||||
|
||||
unsigned char* convert_image_to_DXT5(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size )
|
||||
{
|
||||
unsigned char *compressed;
|
||||
int i, j, x, y;
|
||||
unsigned char ublock[16*4];
|
||||
unsigned char cblock[8];
|
||||
int index = 0, chan_step = 1;
|
||||
int block_count = 0, has_alpha;
|
||||
/* error check */
|
||||
*out_size = 0;
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(NULL == uncompressed) ||
|
||||
(channels < 1) || ( channels > 4) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* for channels == 1 or 2, I do not step forward for R,G,B vales */
|
||||
if( channels < 3 )
|
||||
{
|
||||
chan_step = 0;
|
||||
}
|
||||
/* # channels = 1 or 3 have no alpha, 2 & 4 do have alpha */
|
||||
has_alpha = 1 - (channels & 1);
|
||||
/* get the RAM for the compressed image
|
||||
(16 bytes per 4x4 pixel block) */
|
||||
*out_size = ((width+3) >> 2) * ((height+3) >> 2) * 16;
|
||||
compressed = (unsigned char*)malloc( *out_size );
|
||||
/* go through each block */
|
||||
for( j = 0; j < height; j += 4 )
|
||||
{
|
||||
for( i = 0; i < width; i += 4 )
|
||||
{
|
||||
/* local variables, and my block counter */
|
||||
int idx = 0;
|
||||
int mx = 4, my = 4;
|
||||
if( j+4 >= height )
|
||||
{
|
||||
my = height - j;
|
||||
}
|
||||
if( i+4 >= width )
|
||||
{
|
||||
mx = width - i;
|
||||
}
|
||||
for( y = 0; y < my; ++y )
|
||||
{
|
||||
for( x = 0; x < mx; ++x )
|
||||
{
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step];
|
||||
ublock[idx++] = uncompressed[(j+y)*width*channels+(i+x)*channels+chan_step+chan_step];
|
||||
ublock[idx++] =
|
||||
has_alpha * uncompressed[(j+y)*width*channels+(i+x)*channels+channels-1]
|
||||
+ (1-has_alpha)*255;
|
||||
}
|
||||
for( x = mx; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
ublock[idx++] = ublock[3];
|
||||
}
|
||||
}
|
||||
for( y = my; y < 4; ++y )
|
||||
{
|
||||
for( x = 0; x < 4; ++x )
|
||||
{
|
||||
ublock[idx++] = ublock[0];
|
||||
ublock[idx++] = ublock[1];
|
||||
ublock[idx++] = ublock[2];
|
||||
ublock[idx++] = ublock[3];
|
||||
}
|
||||
}
|
||||
/* now compress the alpha block */
|
||||
compress_DDS_alpha_block( ublock, cblock );
|
||||
/* copy the data from the compressed alpha block into the main buffer */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
/* then compress the color block */
|
||||
++block_count;
|
||||
compress_DDS_color_block( 4, ublock, cblock );
|
||||
/* copy the data from the compressed color block into the main buffer */
|
||||
for( x = 0; x < 8; ++x )
|
||||
{
|
||||
compressed[index++] = cblock[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return compressed;
|
||||
}
|
||||
|
||||
/********* Helper Functions *********/
|
||||
int convert_bit_range( int c, int from_bits, int to_bits )
|
||||
{
|
||||
int b = (1 << (from_bits - 1)) + c * ((1 << to_bits) - 1);
|
||||
return (b + (b >> from_bits)) >> from_bits;
|
||||
}
|
||||
|
||||
int rgb_to_565( int r, int g, int b )
|
||||
{
|
||||
return
|
||||
(convert_bit_range( r, 8, 5 ) << 11) |
|
||||
(convert_bit_range( g, 8, 6 ) << 05) |
|
||||
(convert_bit_range( b, 8, 5 ) << 00);
|
||||
}
|
||||
|
||||
void rgb_888_from_565( unsigned int c, int *r, int *g, int *b )
|
||||
{
|
||||
*r = convert_bit_range( (c >> 11) & 31, 5, 8 );
|
||||
*g = convert_bit_range( (c >> 05) & 63, 6, 8 );
|
||||
*b = convert_bit_range( (c >> 00) & 31, 5, 8 );
|
||||
}
|
||||
|
||||
void compute_color_line_STDEV(
|
||||
const unsigned char *const uncompressed,
|
||||
int channels,
|
||||
float point[3], float direction[3] )
|
||||
{
|
||||
const float inv_16 = 1.0f / 16.0f;
|
||||
int i;
|
||||
float sum_r = 0.0f, sum_g = 0.0f, sum_b = 0.0f;
|
||||
float sum_rr = 0.0f, sum_gg = 0.0f, sum_bb = 0.0f;
|
||||
float sum_rg = 0.0f, sum_rb = 0.0f, sum_gb = 0.0f;
|
||||
/* calculate all data needed for the covariance matrix
|
||||
( to compare with _rygdxt code) */
|
||||
for( i = 0; i < 16*channels; i += channels )
|
||||
{
|
||||
sum_r += uncompressed[i+0];
|
||||
sum_rr += uncompressed[i+0] * uncompressed[i+0];
|
||||
sum_g += uncompressed[i+1];
|
||||
sum_gg += uncompressed[i+1] * uncompressed[i+1];
|
||||
sum_b += uncompressed[i+2];
|
||||
sum_bb += uncompressed[i+2] * uncompressed[i+2];
|
||||
sum_rg += uncompressed[i+0] * uncompressed[i+1];
|
||||
sum_rb += uncompressed[i+0] * uncompressed[i+2];
|
||||
sum_gb += uncompressed[i+1] * uncompressed[i+2];
|
||||
}
|
||||
/* convert the sums to averages */
|
||||
sum_r *= inv_16;
|
||||
sum_g *= inv_16;
|
||||
sum_b *= inv_16;
|
||||
/* and convert the squares to the squares of the value - avg_value */
|
||||
sum_rr -= 16.0f * sum_r * sum_r;
|
||||
sum_gg -= 16.0f * sum_g * sum_g;
|
||||
sum_bb -= 16.0f * sum_b * sum_b;
|
||||
sum_rg -= 16.0f * sum_r * sum_g;
|
||||
sum_rb -= 16.0f * sum_r * sum_b;
|
||||
sum_gb -= 16.0f * sum_g * sum_b;
|
||||
/* the point on the color line is the average */
|
||||
point[0] = sum_r;
|
||||
point[1] = sum_g;
|
||||
point[2] = sum_b;
|
||||
#if USE_COV_MAT
|
||||
/*
|
||||
The following idea was from ryg.
|
||||
(https://mollyrocket.com/forums/viewtopic.php?t=392)
|
||||
The method worked great (less RMSE than mine) most of
|
||||
the time, but had some issues handling some simple
|
||||
boundary cases, like full green next to full red,
|
||||
which would generate a covariance matrix like this:
|
||||
|
||||
| 1 -1 0 |
|
||||
| -1 1 0 |
|
||||
| 0 0 0 |
|
||||
|
||||
For a given starting vector, the power method can
|
||||
generate all zeros! So no starting with {1,1,1}
|
||||
as I was doing! This kind of error is still a
|
||||
slight posibillity, but will be very rare.
|
||||
*/
|
||||
/* use the covariance matrix directly
|
||||
(1st iteration, don't use all 1.0 values!) */
|
||||
sum_r = 1.0f;
|
||||
sum_g = 2.718281828f;
|
||||
sum_b = 3.141592654f;
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
/* 2nd iteration, use results from the 1st guy */
|
||||
sum_r = direction[0];
|
||||
sum_g = direction[1];
|
||||
sum_b = direction[2];
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
/* 3rd iteration, use results from the 2nd guy */
|
||||
sum_r = direction[0];
|
||||
sum_g = direction[1];
|
||||
sum_b = direction[2];
|
||||
direction[0] = sum_r*sum_rr + sum_g*sum_rg + sum_b*sum_rb;
|
||||
direction[1] = sum_r*sum_rg + sum_g*sum_gg + sum_b*sum_gb;
|
||||
direction[2] = sum_r*sum_rb + sum_g*sum_gb + sum_b*sum_bb;
|
||||
#else
|
||||
/* use my standard deviation method
|
||||
(very robust, a tiny bit slower and less accurate) */
|
||||
direction[0] = sqrt( sum_rr );
|
||||
direction[1] = sqrt( sum_gg );
|
||||
direction[2] = sqrt( sum_bb );
|
||||
/* which has a greater component */
|
||||
if( sum_gg > sum_rr )
|
||||
{
|
||||
/* green has greater component, so base the other signs off of green */
|
||||
if( sum_rg < 0.0f )
|
||||
{
|
||||
direction[0] = -direction[0];
|
||||
}
|
||||
if( sum_gb < 0.0f )
|
||||
{
|
||||
direction[2] = -direction[2];
|
||||
}
|
||||
} else
|
||||
{
|
||||
/* red has a greater component */
|
||||
if( sum_rg < 0.0f )
|
||||
{
|
||||
direction[1] = -direction[1];
|
||||
}
|
||||
if( sum_rb < 0.0f )
|
||||
{
|
||||
direction[2] = -direction[2];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LSE_master_colors_max_min(
|
||||
int *cmax, int *cmin,
|
||||
int channels,
|
||||
const unsigned char *const uncompressed )
|
||||
{
|
||||
int i, j;
|
||||
/* the master colors */
|
||||
int c0[3], c1[3];
|
||||
/* used for fitting the line */
|
||||
float sum_x[] = { 0.0f, 0.0f, 0.0f };
|
||||
float sum_x2[] = { 0.0f, 0.0f, 0.0f };
|
||||
float dot_max = 1.0f, dot_min = -1.0f;
|
||||
float vec_len2 = 0.0f;
|
||||
float dot;
|
||||
/* error check */
|
||||
if( (channels < 3) || (channels > 4) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
compute_color_line_STDEV( uncompressed, channels, sum_x, sum_x2 );
|
||||
vec_len2 = 1.0f / ( 0.00001f +
|
||||
sum_x2[0]*sum_x2[0] + sum_x2[1]*sum_x2[1] + sum_x2[2]*sum_x2[2] );
|
||||
/* finding the max and min vector values */
|
||||
dot_max =
|
||||
(
|
||||
sum_x2[0] * uncompressed[0] +
|
||||
sum_x2[1] * uncompressed[1] +
|
||||
sum_x2[2] * uncompressed[2]
|
||||
);
|
||||
dot_min = dot_max;
|
||||
for( i = 1; i < 16; ++i )
|
||||
{
|
||||
dot =
|
||||
(
|
||||
sum_x2[0] * uncompressed[i*channels+0] +
|
||||
sum_x2[1] * uncompressed[i*channels+1] +
|
||||
sum_x2[2] * uncompressed[i*channels+2]
|
||||
);
|
||||
if( dot < dot_min )
|
||||
{
|
||||
dot_min = dot;
|
||||
} else if( dot > dot_max )
|
||||
{
|
||||
dot_max = dot;
|
||||
}
|
||||
}
|
||||
/* and the offset (from the average location) */
|
||||
dot = sum_x2[0]*sum_x[0] + sum_x2[1]*sum_x[1] + sum_x2[2]*sum_x[2];
|
||||
dot_min -= dot;
|
||||
dot_max -= dot;
|
||||
/* post multiply by the scaling factor */
|
||||
dot_min *= vec_len2;
|
||||
dot_max *= vec_len2;
|
||||
/* OK, build the master colors */
|
||||
for( i = 0; i < 3; ++i )
|
||||
{
|
||||
/* color 0 */
|
||||
c0[i] = (int)(0.5f + sum_x[i] + dot_max * sum_x2[i]);
|
||||
if( c0[i] < 0 )
|
||||
{
|
||||
c0[i] = 0;
|
||||
} else if( c0[i] > 255 )
|
||||
{
|
||||
c0[i] = 255;
|
||||
}
|
||||
/* color 1 */
|
||||
c1[i] = (int)(0.5f + sum_x[i] + dot_min * sum_x2[i]);
|
||||
if( c1[i] < 0 )
|
||||
{
|
||||
c1[i] = 0;
|
||||
} else if( c1[i] > 255 )
|
||||
{
|
||||
c1[i] = 255;
|
||||
}
|
||||
}
|
||||
/* down_sample (with rounding?) */
|
||||
i = rgb_to_565( c0[0], c0[1], c0[2] );
|
||||
j = rgb_to_565( c1[0], c1[1], c1[2] );
|
||||
if( i > j )
|
||||
{
|
||||
*cmax = i;
|
||||
*cmin = j;
|
||||
} else
|
||||
{
|
||||
*cmax = j;
|
||||
*cmin = i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
compress_DDS_color_block
|
||||
(
|
||||
int channels,
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8]
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
int i;
|
||||
int next_bit;
|
||||
int enc_c0, enc_c1;
|
||||
int c0[4], c1[4];
|
||||
float color_line[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
float vec_len2 = 0.0f, dot_offset = 0.0f;
|
||||
/* stupid order */
|
||||
int swizzle4[] = { 0, 2, 3, 1 };
|
||||
/* get the master colors */
|
||||
LSE_master_colors_max_min( &enc_c0, &enc_c1, channels, uncompressed );
|
||||
/* store the 565 color 0 and color 1 */
|
||||
compressed[0] = (enc_c0 >> 0) & 255;
|
||||
compressed[1] = (enc_c0 >> 8) & 255;
|
||||
compressed[2] = (enc_c1 >> 0) & 255;
|
||||
compressed[3] = (enc_c1 >> 8) & 255;
|
||||
/* zero out the compressed data */
|
||||
compressed[4] = 0;
|
||||
compressed[5] = 0;
|
||||
compressed[6] = 0;
|
||||
compressed[7] = 0;
|
||||
/* reconstitute the master color vectors */
|
||||
rgb_888_from_565( enc_c0, &c0[0], &c0[1], &c0[2] );
|
||||
rgb_888_from_565( enc_c1, &c1[0], &c1[1], &c1[2] );
|
||||
/* the new vector */
|
||||
vec_len2 = 0.0f;
|
||||
for( i = 0; i < 3; ++i )
|
||||
{
|
||||
color_line[i] = (float)(c1[i] - c0[i]);
|
||||
vec_len2 += color_line[i] * color_line[i];
|
||||
}
|
||||
if( vec_len2 > 0.0f )
|
||||
{
|
||||
vec_len2 = 1.0f / vec_len2;
|
||||
}
|
||||
/* pre-proform the scaling */
|
||||
color_line[0] *= vec_len2;
|
||||
color_line[1] *= vec_len2;
|
||||
color_line[2] *= vec_len2;
|
||||
/* compute the offset (constant) portion of the dot product */
|
||||
dot_offset = color_line[0]*c0[0] + color_line[1]*c0[1] + color_line[2]*c0[2];
|
||||
/* store the rest of the bits */
|
||||
next_bit = 8*4;
|
||||
for( i = 0; i < 16; ++i )
|
||||
{
|
||||
/* find the dot product of this color, to place it on the line
|
||||
(should be [-1,1]) */
|
||||
int next_value = 0;
|
||||
float dot_product =
|
||||
color_line[0] * uncompressed[i*channels+0] +
|
||||
color_line[1] * uncompressed[i*channels+1] +
|
||||
color_line[2] * uncompressed[i*channels+2] -
|
||||
dot_offset;
|
||||
/* map to [0,3] */
|
||||
next_value = (int)( dot_product * 3.0f + 0.5f );
|
||||
if( next_value > 3 )
|
||||
{
|
||||
next_value = 3;
|
||||
} else if( next_value < 0 )
|
||||
{
|
||||
next_value = 0;
|
||||
}
|
||||
/* OK, store this value */
|
||||
compressed[next_bit >> 3] |= swizzle4[ next_value ] << (next_bit & 7);
|
||||
next_bit += 2;
|
||||
}
|
||||
/* done compressing to DXT1 */
|
||||
}
|
||||
|
||||
void
|
||||
compress_DDS_alpha_block
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
unsigned char compressed[8]
|
||||
)
|
||||
{
|
||||
/* variables */
|
||||
int i;
|
||||
int next_bit;
|
||||
int a0, a1;
|
||||
float scale_me;
|
||||
/* stupid order */
|
||||
int swizzle8[] = { 1, 7, 6, 5, 4, 3, 2, 0 };
|
||||
/* get the alpha limits (a0 > a1) */
|
||||
a0 = a1 = uncompressed[3];
|
||||
for( i = 4+3; i < 16*4; i += 4 )
|
||||
{
|
||||
if( uncompressed[i] > a0 )
|
||||
{
|
||||
a0 = uncompressed[i];
|
||||
} else if( uncompressed[i] < a1 )
|
||||
{
|
||||
a1 = uncompressed[i];
|
||||
}
|
||||
}
|
||||
/* store those limits, and zero the rest of the compressed dataset */
|
||||
compressed[0] = a0;
|
||||
compressed[1] = a1;
|
||||
/* zero out the compressed data */
|
||||
compressed[2] = 0;
|
||||
compressed[3] = 0;
|
||||
compressed[4] = 0;
|
||||
compressed[5] = 0;
|
||||
compressed[6] = 0;
|
||||
compressed[7] = 0;
|
||||
/* store the all of the alpha values */
|
||||
next_bit = 8*2;
|
||||
scale_me = 7.9999f / (a0 - a1);
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
/* convert this alpha value to a 3 bit number */
|
||||
int svalue;
|
||||
int value = (int)((uncompressed[i] - a1) * scale_me);
|
||||
svalue = swizzle8[ value&7 ];
|
||||
/* OK, store this value, start with the 1st byte */
|
||||
compressed[next_bit >> 3] |= svalue << (next_bit & 7);
|
||||
if( (next_bit & 7) > 5 )
|
||||
{
|
||||
/* spans 2 bytes, fill in the start of the 2nd byte */
|
||||
compressed[1 + (next_bit >> 3)] |= svalue >> (8 - (next_bit & 7) );
|
||||
}
|
||||
next_bit += 3;
|
||||
}
|
||||
/* done compressing to DXT1 */
|
||||
}
|
123
cw 5/src/SOIL/image_DXT.h
Normal file
123
cw 5/src/SOIL/image_DXT.h
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
2007-07-31-10.32
|
||||
|
||||
simple DXT compression / decompression code
|
||||
|
||||
public domain
|
||||
*/
|
||||
|
||||
#ifndef HEADER_IMAGE_DXT
|
||||
#define HEADER_IMAGE_DXT
|
||||
|
||||
/**
|
||||
Converts an image from an array of unsigned chars (RGB or RGBA) to
|
||||
DXT1 or DXT5, then saves the converted image to disk.
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
save_image_as_DDS
|
||||
(
|
||||
const char *filename,
|
||||
int width, int height, int channels,
|
||||
const unsigned char *const data
|
||||
);
|
||||
|
||||
/**
|
||||
take an image and convert it to DXT1 (no alpha)
|
||||
**/
|
||||
unsigned char*
|
||||
convert_image_to_DXT1
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size
|
||||
);
|
||||
|
||||
/**
|
||||
take an image and convert it to DXT5 (with alpha)
|
||||
**/
|
||||
unsigned char*
|
||||
convert_image_to_DXT5
|
||||
(
|
||||
const unsigned char *const uncompressed,
|
||||
int width, int height, int channels,
|
||||
int *out_size
|
||||
);
|
||||
|
||||
/** A bunch of DirectDraw Surface structures and flags **/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int dwMagic;
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwHeight;
|
||||
unsigned int dwWidth;
|
||||
unsigned int dwPitchOrLinearSize;
|
||||
unsigned int dwDepth;
|
||||
unsigned int dwMipMapCount;
|
||||
unsigned int dwReserved1[ 11 ];
|
||||
|
||||
/* DDPIXELFORMAT */
|
||||
struct
|
||||
{
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwFourCC;
|
||||
unsigned int dwRGBBitCount;
|
||||
unsigned int dwRBitMask;
|
||||
unsigned int dwGBitMask;
|
||||
unsigned int dwBBitMask;
|
||||
unsigned int dwAlphaBitMask;
|
||||
}
|
||||
sPixelFormat;
|
||||
|
||||
/* DDCAPS2 */
|
||||
struct
|
||||
{
|
||||
unsigned int dwCaps1;
|
||||
unsigned int dwCaps2;
|
||||
unsigned int dwDDSX;
|
||||
unsigned int dwReserved;
|
||||
}
|
||||
sCaps;
|
||||
unsigned int dwReserved2;
|
||||
}
|
||||
DDS_header ;
|
||||
|
||||
/* the following constants were copied directly off the MSDN website */
|
||||
|
||||
/* The dwFlags member of the original DDSURFACEDESC2 structure
|
||||
can be set to one or more of the following values. */
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
/* DirectDraw Pixel Format */
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_RGB 0x00000040
|
||||
|
||||
/* The dwCaps1 member of the DDSCAPS2 structure can be
|
||||
set to one or more of the following values. */
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
|
||||
/* The dwCaps2 member of the DDSCAPS2 structure can be
|
||||
set to one or more of the following values. */
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
|
||||
#endif /* HEADER_IMAGE_DXT */
|
435
cw 5/src/SOIL/image_helper.c
Normal file
435
cw 5/src/SOIL/image_helper.c
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
|
||||
image helper functions
|
||||
|
||||
MIT license
|
||||
*/
|
||||
|
||||
#include "image_helper.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Upscaling the image uses simple bilinear interpolation */
|
||||
int
|
||||
up_scale_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int resampled_width, int resampled_height
|
||||
)
|
||||
{
|
||||
float dx, dy;
|
||||
int x, y, c;
|
||||
|
||||
/* error(s) check */
|
||||
if ( (width < 1) || (height < 1) ||
|
||||
(resampled_width < 2) || (resampled_height < 2) ||
|
||||
(channels < 1) ||
|
||||
(NULL == orig) || (NULL == resampled) )
|
||||
{
|
||||
/* signify badness */
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
for each given pixel in the new map, find the exact location
|
||||
from the original map which would contribute to this guy
|
||||
*/
|
||||
dx = (width - 1.0f) / (resampled_width - 1.0f);
|
||||
dy = (height - 1.0f) / (resampled_height - 1.0f);
|
||||
for ( y = 0; y < resampled_height; ++y )
|
||||
{
|
||||
/* find the base y index and fractional offset from that */
|
||||
float sampley = y * dy;
|
||||
int inty = (int)sampley;
|
||||
/* if( inty < 0 ) { inty = 0; } else */
|
||||
if( inty > height - 2 ) { inty = height - 2; }
|
||||
sampley -= inty;
|
||||
for ( x = 0; x < resampled_width; ++x )
|
||||
{
|
||||
float samplex = x * dx;
|
||||
int intx = (int)samplex;
|
||||
int base_index;
|
||||
/* find the base x index and fractional offset from that */
|
||||
/* if( intx < 0 ) { intx = 0; } else */
|
||||
if( intx > width - 2 ) { intx = width - 2; }
|
||||
samplex -= intx;
|
||||
/* base index into the original image */
|
||||
base_index = (inty * width + intx) * channels;
|
||||
for ( c = 0; c < channels; ++c )
|
||||
{
|
||||
/* do the sampling */
|
||||
float value = 0.5f;
|
||||
value += orig[base_index]
|
||||
*(1.0f-samplex)*(1.0f-sampley);
|
||||
value += orig[base_index+channels]
|
||||
*(samplex)*(1.0f-sampley);
|
||||
value += orig[base_index+width*channels]
|
||||
*(1.0f-samplex)*(sampley);
|
||||
value += orig[base_index+width*channels+channels]
|
||||
*(samplex)*(sampley);
|
||||
/* move to the next channel */
|
||||
++base_index;
|
||||
/* save the new value */
|
||||
resampled[y*resampled_width*channels+x*channels+c] =
|
||||
(unsigned char)(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mipmap_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int block_size_x, int block_size_y
|
||||
)
|
||||
{
|
||||
int mip_width, mip_height;
|
||||
int i, j, c;
|
||||
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 1) || (orig == NULL) ||
|
||||
(resampled == NULL) ||
|
||||
(block_size_x < 1) || (block_size_y < 1) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
mip_width = width / block_size_x;
|
||||
mip_height = height / block_size_y;
|
||||
if( mip_width < 1 )
|
||||
{
|
||||
mip_width = 1;
|
||||
}
|
||||
if( mip_height < 1 )
|
||||
{
|
||||
mip_height = 1;
|
||||
}
|
||||
for( j = 0; j < mip_height; ++j )
|
||||
{
|
||||
for( i = 0; i < mip_width; ++i )
|
||||
{
|
||||
for( c = 0; c < channels; ++c )
|
||||
{
|
||||
const int index = (j*block_size_y)*width*channels + (i*block_size_x)*channels + c;
|
||||
int sum_value;
|
||||
int u,v;
|
||||
int u_block = block_size_x;
|
||||
int v_block = block_size_y;
|
||||
int block_area;
|
||||
/* do a bit of checking so we don't over-run the boundaries
|
||||
(necessary for non-square textures!) */
|
||||
if( block_size_x * (i+1) > width )
|
||||
{
|
||||
u_block = width - i*block_size_y;
|
||||
}
|
||||
if( block_size_y * (j+1) > height )
|
||||
{
|
||||
v_block = height - j*block_size_y;
|
||||
}
|
||||
block_area = u_block*v_block;
|
||||
/* for this pixel, see what the average
|
||||
of all the values in the block are.
|
||||
note: start the sum at the rounding value, not at 0 */
|
||||
sum_value = block_area >> 1;
|
||||
for( v = 0; v < v_block; ++v )
|
||||
for( u = 0; u < u_block; ++u )
|
||||
{
|
||||
sum_value += orig[index + v*width*channels + u*channels];
|
||||
}
|
||||
resampled[j*mip_width*channels + i*channels + c] = sum_value / block_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
scale_image_RGB_to_NTSC_safe
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
const float scale_lo = 16.0f - 0.499f;
|
||||
const float scale_hi = 235.0f + 0.499f;
|
||||
int i, j;
|
||||
int nc = channels;
|
||||
unsigned char scale_LUT[256];
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 1) || (orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
/* set up the scaling Look Up Table */
|
||||
for( i = 0; i < 256; ++i )
|
||||
{
|
||||
scale_LUT[i] = (unsigned char)((scale_hi - scale_lo) * i / 255.0f + scale_lo);
|
||||
}
|
||||
/* for channels = 2 or 4, ignore the alpha component */
|
||||
nc -= 1 - (channels & 1);
|
||||
/* OK, go through the image and scale any non-alpha components */
|
||||
for( i = 0; i < width*height*channels; i += channels )
|
||||
{
|
||||
for( j = 0; j < nc; ++j )
|
||||
{
|
||||
orig[i+j] = scale_LUT[orig[i+j]];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char clamp_byte( int x ) { return ( (x) < 0 ? (0) : ( (x) > 255 ? 255 : (x) ) ); }
|
||||
|
||||
/*
|
||||
This function takes the RGB components of the image
|
||||
and converts them into YCoCg. 3 components will be
|
||||
re-ordered to CoYCg (for optimum DXT1 compression),
|
||||
while 4 components will be ordered CoCgAY (for DXT5
|
||||
compression).
|
||||
*/
|
||||
int
|
||||
convert_RGB_to_YCoCg
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
int i;
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 3) || (channels > 4) ||
|
||||
(orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return -1;
|
||||
}
|
||||
/* do the conversion */
|
||||
if( channels == 3 )
|
||||
{
|
||||
for( i = 0; i < width*height*3; i += 3 )
|
||||
{
|
||||
int r = orig[i+0];
|
||||
int g = (orig[i+1] + 1) >> 1;
|
||||
int b = orig[i+2];
|
||||
int tmp = (2 + r + b) >> 2;
|
||||
/* Co */
|
||||
orig[i+0] = clamp_byte( 128 + ((r - b + 1) >> 1) );
|
||||
/* Y */
|
||||
orig[i+1] = clamp_byte( g + tmp );
|
||||
/* Cg */
|
||||
orig[i+2] = clamp_byte( 128 + g - tmp );
|
||||
}
|
||||
} else
|
||||
{
|
||||
for( i = 0; i < width*height*4; i += 4 )
|
||||
{
|
||||
int r = orig[i+0];
|
||||
int g = (orig[i+1] + 1) >> 1;
|
||||
int b = orig[i+2];
|
||||
unsigned char a = orig[i+3];
|
||||
int tmp = (2 + r + b) >> 2;
|
||||
/* Co */
|
||||
orig[i+0] = clamp_byte( 128 + ((r - b + 1) >> 1) );
|
||||
/* Cg */
|
||||
orig[i+1] = clamp_byte( 128 + g - tmp );
|
||||
/* Alpha */
|
||||
orig[i+2] = a;
|
||||
/* Y */
|
||||
orig[i+3] = clamp_byte( g + tmp );
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
This function takes the YCoCg components of the image
|
||||
and converts them into RGB. See above.
|
||||
*/
|
||||
int
|
||||
convert_YCoCg_to_RGB
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
)
|
||||
{
|
||||
int i;
|
||||
/* error check */
|
||||
if( (width < 1) || (height < 1) ||
|
||||
(channels < 3) || (channels > 4) ||
|
||||
(orig == NULL) )
|
||||
{
|
||||
/* nothing to do */
|
||||
return -1;
|
||||
}
|
||||
/* do the conversion */
|
||||
if( channels == 3 )
|
||||
{
|
||||
for( i = 0; i < width*height*3; i += 3 )
|
||||
{
|
||||
int co = orig[i+0] - 128;
|
||||
int y = orig[i+1];
|
||||
int cg = orig[i+2] - 128;
|
||||
/* R */
|
||||
orig[i+0] = clamp_byte( y + co - cg );
|
||||
/* G */
|
||||
orig[i+1] = clamp_byte( y + cg );
|
||||
/* B */
|
||||
orig[i+2] = clamp_byte( y - co - cg );
|
||||
}
|
||||
} else
|
||||
{
|
||||
for( i = 0; i < width*height*4; i += 4 )
|
||||
{
|
||||
int co = orig[i+0] - 128;
|
||||
int cg = orig[i+1] - 128;
|
||||
unsigned char a = orig[i+2];
|
||||
int y = orig[i+3];
|
||||
/* R */
|
||||
orig[i+0] = clamp_byte( y + co - cg );
|
||||
/* G */
|
||||
orig[i+1] = clamp_byte( y + cg );
|
||||
/* B */
|
||||
orig[i+2] = clamp_byte( y - co - cg );
|
||||
/* A */
|
||||
orig[i+3] = a;
|
||||
}
|
||||
}
|
||||
/* done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
find_max_RGBE
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height
|
||||
)
|
||||
{
|
||||
float max_val = 0.0f;
|
||||
unsigned char *img = image;
|
||||
int i, j;
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* float scale = powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
float scale = ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
for( j = 0; j < 3; ++j )
|
||||
{
|
||||
if( img[j] * scale > max_val )
|
||||
{
|
||||
max_val = img[j] * scale;
|
||||
}
|
||||
}
|
||||
/* next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return max_val;
|
||||
}
|
||||
|
||||
int
|
||||
RGBE_to_RGBdivA
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
)
|
||||
{
|
||||
/* local variables */
|
||||
int i, iv;
|
||||
unsigned char *img = image;
|
||||
float scale = 1.0f;
|
||||
/* error check */
|
||||
if( (!image) || (width < 1) || (height < 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* convert (note: no negative numbers, but 0.0 is possible) */
|
||||
if( rescale_to_max )
|
||||
{
|
||||
scale = 255.0f / find_max_RGBE( image, width, height );
|
||||
}
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* decode this pixel, and find the max */
|
||||
float r,g,b,e, m;
|
||||
/* e = scale * powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
e = scale * ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
r = e * img[0];
|
||||
g = e * img[1];
|
||||
b = e * img[2];
|
||||
m = (r > g) ? r : g;
|
||||
m = (b > m) ? b : m;
|
||||
/* and encode it into RGBdivA */
|
||||
iv = (m != 0.0f) ? (int)(255.0f / m) : 1.0f;
|
||||
iv = (iv < 1) ? 1 : iv;
|
||||
img[3] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * r + 0.5f);
|
||||
img[0] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * g + 0.5f);
|
||||
img[1] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * b + 0.5f);
|
||||
img[2] = (iv > 255) ? 255 : iv;
|
||||
/* and on to the next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
RGBE_to_RGBdivA2
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
)
|
||||
{
|
||||
/* local variables */
|
||||
int i, iv;
|
||||
unsigned char *img = image;
|
||||
float scale = 1.0f;
|
||||
/* error check */
|
||||
if( (!image) || (width < 1) || (height < 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* convert (note: no negative numbers, but 0.0 is possible) */
|
||||
if( rescale_to_max )
|
||||
{
|
||||
scale = 255.0f * 255.0f / find_max_RGBE( image, width, height );
|
||||
}
|
||||
for( i = width * height; i > 0; --i )
|
||||
{
|
||||
/* decode this pixel, and find the max */
|
||||
float r,g,b,e, m;
|
||||
/* e = scale * powf( 2.0f, img[3] - 128.0f ) / 255.0f; */
|
||||
e = scale * ldexp( 1.0f / 255.0f, (int)(img[3]) - 128 );
|
||||
r = e * img[0];
|
||||
g = e * img[1];
|
||||
b = e * img[2];
|
||||
m = (r > g) ? r : g;
|
||||
m = (b > m) ? b : m;
|
||||
/* and encode it into RGBdivA */
|
||||
iv = (m != 0.0f) ? (int)sqrtf( 255.0f * 255.0f / m ) : 1.0f;
|
||||
iv = (iv < 1) ? 1 : iv;
|
||||
img[3] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * r / 255.0f + 0.5f);
|
||||
img[0] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * g / 255.0f + 0.5f);
|
||||
img[1] = (iv > 255) ? 255 : iv;
|
||||
iv = (int)(img[3] * img[3] * b / 255.0f + 0.5f);
|
||||
img[2] = (iv > 255) ? 255 : iv;
|
||||
/* and on to the next pixel */
|
||||
img += 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
115
cw 5/src/SOIL/image_helper.h
Normal file
115
cw 5/src/SOIL/image_helper.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Jonathan Dummer
|
||||
|
||||
Image helper functions
|
||||
|
||||
MIT license
|
||||
*/
|
||||
|
||||
#ifndef HEADER_IMAGE_HELPER
|
||||
#define HEADER_IMAGE_HELPER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
This function upscales an image.
|
||||
Not to be used to create MIPmaps,
|
||||
but to make it square,
|
||||
or to make it a power-of-two sized.
|
||||
**/
|
||||
int
|
||||
up_scale_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int resampled_width, int resampled_height
|
||||
);
|
||||
|
||||
/**
|
||||
This function downscales an image.
|
||||
Used for creating MIPmaps,
|
||||
the incoming image should be a
|
||||
power-of-two sized.
|
||||
**/
|
||||
int
|
||||
mipmap_image
|
||||
(
|
||||
const unsigned char* const orig,
|
||||
int width, int height, int channels,
|
||||
unsigned char* resampled,
|
||||
int block_size_x, int block_size_y
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the RGB components of the image
|
||||
and scales each channel from [0,255] to [16,235].
|
||||
This makes the colors "Safe" for display on NTSC
|
||||
displays. Note that this is _NOT_ a good idea for
|
||||
loading images like normal- or height-maps!
|
||||
**/
|
||||
int
|
||||
scale_image_RGB_to_NTSC_safe
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the RGB components of the image
|
||||
and converts them into YCoCg. 3 components will be
|
||||
re-ordered to CoYCg (for optimum DXT1 compression),
|
||||
while 4 components will be ordered CoCgAY (for DXT5
|
||||
compression).
|
||||
**/
|
||||
int
|
||||
convert_RGB_to_YCoCg
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
This function takes the YCoCg components of the image
|
||||
and converts them into RGB. See above.
|
||||
**/
|
||||
int
|
||||
convert_YCoCg_to_RGB
|
||||
(
|
||||
unsigned char* orig,
|
||||
int width, int height, int channels
|
||||
);
|
||||
|
||||
/**
|
||||
Converts an HDR image from an array
|
||||
of unsigned chars (RGBE) to RGBdivA
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
RGBE_to_RGBdivA
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
);
|
||||
|
||||
/**
|
||||
Converts an HDR image from an array
|
||||
of unsigned chars (RGBE) to RGBdivA2
|
||||
\return 0 if failed, otherwise returns 1
|
||||
**/
|
||||
int
|
||||
RGBE_to_RGBdivA2
|
||||
(
|
||||
unsigned char *image,
|
||||
int width, int height,
|
||||
int rescale_to_max
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_IMAGE_HELPER */
|
3682
cw 5/src/SOIL/stb_image_aug.c
Normal file
3682
cw 5/src/SOIL/stb_image_aug.c
Normal file
File diff suppressed because it is too large
Load Diff
354
cw 5/src/SOIL/stb_image_aug.h
Normal file
354
cw 5/src/SOIL/stb_image_aug.h
Normal file
@ -0,0 +1,354 @@
|
||||
/* stbi-1.16 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
||||
when you control the images you're loading
|
||||
|
||||
QUICK NOTES:
|
||||
Primarily of interest to game developers and other people who can
|
||||
avoid problematic images and only need the trivial interface
|
||||
|
||||
JPEG baseline (no JPEG progressive, no oddball channel decimations)
|
||||
PNG non-interlaced
|
||||
BMP non-1bpp, non-RLE
|
||||
TGA (not sure what subset, if a subset)
|
||||
PSD (composited view only, no extra channels)
|
||||
HDR (radiance rgbE format)
|
||||
writes BMP,TGA (define STBI_NO_WRITE to remove code)
|
||||
decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code)
|
||||
supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
|
||||
|
||||
TODO:
|
||||
stbi_info_*
|
||||
|
||||
history:
|
||||
1.16 major bugfix - convert_format converted one too many pixels
|
||||
1.15 initialize some fields for thread safety
|
||||
1.14 fix threadsafe conversion bug; header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
|
||||
1.13 threadsafe
|
||||
1.12 const qualifiers in the API
|
||||
1.11 Support installable IDCT, colorspace conversion routines
|
||||
1.10 Fixes for 64-bit (don't use "unsigned long")
|
||||
optimized upsampling by Fabian "ryg" Giesen
|
||||
1.09 Fix format-conversion for PSD code (bad global variables!)
|
||||
1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz
|
||||
1.07 attempt to fix C++ warning/errors again
|
||||
1.06 attempt to fix C++ warning/errors again
|
||||
1.05 fix TGA loading to return correct *comp and use good luminance calc
|
||||
1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free
|
||||
1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR
|
||||
1.02 support for (subset of) HDR files, float interface for preferred access to them
|
||||
1.01 fix bug: possible bug in handling right-side up bmps... not sure
|
||||
fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all
|
||||
1.00 interface to zlib that skips zlib header
|
||||
0.99 correct handling of alpha in palette
|
||||
0.98 TGA loader by lonesock; dynamically add loaders (untested)
|
||||
0.97 jpeg errors on too large a file; also catch another malloc failure
|
||||
0.96 fix detection of invalid v value - particleman@mollyrocket forum
|
||||
0.95 during header scan, seek to markers in case of padding
|
||||
0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same
|
||||
0.93 handle jpegtran output; verbose errors
|
||||
0.92 read 4,8,16,24,32-bit BMP files of several formats
|
||||
0.91 output 24-bit Windows 3.0 BMP files
|
||||
0.90 fix a few more warnings; bump version number to approach 1.0
|
||||
0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd
|
||||
0.60 fix compiling as c++
|
||||
0.59 fix warnings: merge Dave Moore's -Wall fixes
|
||||
0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian
|
||||
0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less
|
||||
than 16 available
|
||||
0.56 fix bug: zlib uncompressed mode len vs. nlen
|
||||
0.55 fix bug: restart_interval not initialized to 0
|
||||
0.54 allow NULL for 'int *comp'
|
||||
0.53 fix bug in png 3->4; speedup png decoding
|
||||
0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
|
||||
0.51 obey req_comp requests, 1-component jpegs return as 1-component,
|
||||
on 'test' only check type, not whether we support this variant
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STB_IMAGE_AUGMENTED
|
||||
#define HEADER_STB_IMAGE_AUGMENTED
|
||||
|
||||
//// begin header file ////////////////////////////////////////////////////
|
||||
//
|
||||
// Limitations:
|
||||
// - no progressive/interlaced support (jpeg, png)
|
||||
// - 8-bit samples only (jpeg, png)
|
||||
// - not threadsafe
|
||||
// - channel subsampling of at most 2 in each dimension (jpeg)
|
||||
// - no delayed line count (jpeg) -- IJG doesn't support either
|
||||
//
|
||||
// Basic usage (see HDR discussion below):
|
||||
// int x,y,n;
|
||||
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
|
||||
// // ... process data if not NULL ...
|
||||
// // ... x = width, y = height, n = # 8-bit components per pixel ...
|
||||
// // ... replace '0' with '1'..'4' to force that many components per pixel
|
||||
// stbi_image_free(data)
|
||||
//
|
||||
// Standard parameters:
|
||||
// int *x -- outputs image width in pixels
|
||||
// int *y -- outputs image height in pixels
|
||||
// int *comp -- outputs # of image components in image file
|
||||
// int req_comp -- if non-zero, # of image components requested in result
|
||||
//
|
||||
// The return value from an image loader is an 'unsigned char *' which points
|
||||
// to the pixel data. The pixel data consists of *y scanlines of *x pixels,
|
||||
// with each pixel consisting of N interleaved 8-bit components; the first
|
||||
// pixel pointed to is top-left-most in the image. There is no padding between
|
||||
// image scanlines or between pixels, regardless of format. The number of
|
||||
// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise.
|
||||
// If req_comp is non-zero, *comp has the number of components that _would_
|
||||
// have been output otherwise. E.g. if you set req_comp to 4, you will always
|
||||
// get RGBA output, but you can check *comp to easily see if it's opaque.
|
||||
//
|
||||
// An output image with N components has the following components interleaved
|
||||
// in this order in each pixel:
|
||||
//
|
||||
// N=#comp components
|
||||
// 1 grey
|
||||
// 2 grey, alpha
|
||||
// 3 red, green, blue
|
||||
// 4 red, green, blue, alpha
|
||||
//
|
||||
// If image loading fails for any reason, the return value will be NULL,
|
||||
// and *x, *y, *comp will be unchanged. The function stbi_failure_reason()
|
||||
// can be queried for an extremely brief, end-user unfriendly explanation
|
||||
// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid
|
||||
// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
|
||||
// more user-friendly ones.
|
||||
//
|
||||
// Paletted PNG and BMP images are automatically depalettized.
|
||||
//
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// HDR image support (disable by defining STBI_NO_HDR)
|
||||
//
|
||||
// stb_image now supports loading HDR images in general, and currently
|
||||
// the Radiance .HDR file format, although the support is provided
|
||||
// generically. You can still load any file through the existing interface;
|
||||
// if you attempt to load an HDR file, it will be automatically remapped to
|
||||
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// both of these constants can be reconfigured through this interface:
|
||||
//
|
||||
// stbi_hdr_to_ldr_gamma(2.2f);
|
||||
// stbi_hdr_to_ldr_scale(1.0f);
|
||||
//
|
||||
// (note, do not use _inverse_ constants; stbi_image will invert them
|
||||
// appropriately).
|
||||
//
|
||||
// Additionally, there is a new, parallel interface for loading files as
|
||||
// (linear) floats to preserve the full dynamic range:
|
||||
//
|
||||
// float *data = stbi_loadf(filename, &x, &y, &n, 0);
|
||||
//
|
||||
// If you load LDR images through this interface, those images will
|
||||
// be promoted to floating point values, run through the inverse of
|
||||
// constants corresponding to the above:
|
||||
//
|
||||
// stbi_ldr_to_hdr_scale(1.0f);
|
||||
// stbi_ldr_to_hdr_gamma(2.2f);
|
||||
//
|
||||
// Finally, given a filename (or an open file or memory block--see header
|
||||
// file for details) containing image data, you can query for the "most
|
||||
// appropriate" interface to use (that is, whether the image is HDR or
|
||||
// not), using:
|
||||
//
|
||||
// stbi_is_hdr(char *filename);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define STBI_VERSION 1
|
||||
|
||||
enum
|
||||
{
|
||||
STBI_default = 0, // only used for req_comp
|
||||
|
||||
STBI_grey = 1,
|
||||
STBI_grey_alpha = 2,
|
||||
STBI_rgb = 3,
|
||||
STBI_rgb_alpha = 4,
|
||||
};
|
||||
|
||||
typedef unsigned char stbi_uc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// WRITING API
|
||||
|
||||
#if !defined(STBI_NO_WRITE) && !defined(STBI_NO_STDIO)
|
||||
// write a BMP/TGA file given tightly packed 'comp' channels (no padding, nor bmp-stride-padding)
|
||||
// (you must include the appropriate extension in the filename).
|
||||
// returns TRUE on success, FALSE if couldn't open file, error writing file
|
||||
extern int stbi_write_bmp (char const *filename, int x, int y, int comp, void *data);
|
||||
extern int stbi_write_tga (char const *filename, int x, int y, int comp, void *data);
|
||||
#endif
|
||||
|
||||
// PRIMARY API - works on images of any type
|
||||
|
||||
// load image by filename, open file, or memory buffer
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
||||
|
||||
#ifndef STBI_NO_HDR
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
|
||||
extern void stbi_hdr_to_ldr_gamma(float gamma);
|
||||
extern void stbi_hdr_to_ldr_scale(float scale);
|
||||
|
||||
extern void stbi_ldr_to_hdr_gamma(float gamma);
|
||||
extern void stbi_ldr_to_hdr_scale(float scale);
|
||||
|
||||
#endif // STBI_NO_HDR
|
||||
|
||||
// get a VERY brief reason for failure
|
||||
// NOT THREADSAFE
|
||||
extern char *stbi_failure_reason (void);
|
||||
|
||||
// free the loaded image -- this is just free()
|
||||
extern void stbi_image_free (void *retval_from_stbi_load);
|
||||
|
||||
// get image dimensions & components without fully decoding
|
||||
extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_is_hdr (char const *filename);
|
||||
extern int stbi_is_hdr_from_file(FILE *f);
|
||||
#endif
|
||||
|
||||
// ZLIB client - used by PNG, available for other purposes
|
||||
|
||||
extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
|
||||
extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
|
||||
extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
|
||||
|
||||
extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
|
||||
extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
|
||||
|
||||
// TYPE-SPECIFIC ACCESS
|
||||
|
||||
// is it a jpeg?
|
||||
extern int stbi_jpeg_test_memory (stbi_uc const *buffer, int len);
|
||||
extern stbi_uc *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_jpeg_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_jpeg_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_jpeg_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
|
||||
extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
|
||||
// is it a png?
|
||||
extern int stbi_png_test_memory (stbi_uc const *buffer, int len);
|
||||
extern stbi_uc *stbi_png_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern stbi_uc *stbi_png_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info (char const *filename, int *x, int *y, int *comp);
|
||||
extern int stbi_png_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_png_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp);
|
||||
#endif
|
||||
|
||||
// is it a bmp?
|
||||
extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_bmp_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it a tga?
|
||||
extern int stbi_tga_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_tga_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it a psd?
|
||||
extern int stbi_psd_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_psd_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// is it an hdr?
|
||||
extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_hdr_load_rgbe (char const *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_hdr_test_file (FILE *f);
|
||||
extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_hdr_load_rgbe_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
// define new loaders
|
||||
typedef struct
|
||||
{
|
||||
int (*test_memory)(stbi_uc const *buffer, int len);
|
||||
stbi_uc * (*load_from_memory)(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
int (*test_file)(FILE *f);
|
||||
stbi_uc * (*load_from_file)(FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
} stbi_loader;
|
||||
|
||||
// register a loader by filling out the above structure (you must defined ALL functions)
|
||||
// returns 1 if added or already added, 0 if not added (too many loaders)
|
||||
// NOT THREADSAFE
|
||||
extern int stbi_register_loader(stbi_loader *loader);
|
||||
|
||||
// define faster low-level operations (typically SIMD support)
|
||||
#if STBI_SIMD
|
||||
typedef void (*stbi_idct_8x8)(uint8 *out, int out_stride, short data[64], unsigned short *dequantize);
|
||||
// compute an integer IDCT on "input"
|
||||
// input[x] = data[x] * dequantize[x]
|
||||
// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride'
|
||||
// CLAMP results to 0..255
|
||||
typedef void (*stbi_YCbCr_to_RGB_run)(uint8 *output, uint8 const *y, uint8 const *cb, uint8 const *cr, int count, int step);
|
||||
// compute a conversion from YCbCr to RGB
|
||||
// 'count' pixels
|
||||
// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B
|
||||
// y: Y input channel
|
||||
// cb: Cb input channel; scale/biased to be 0..255
|
||||
// cr: Cr input channel; scale/biased to be 0..255
|
||||
|
||||
extern void stbi_install_idct(stbi_idct_8x8 func);
|
||||
extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
|
||||
#endif // STBI_SIMD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
//// end header file /////////////////////////////////////////////////////
|
||||
#endif // STBI_INCLUDE_STB_IMAGE_H
|
21
cw 5/src/SOIL/stbi_DDS_aug.h
Normal file
21
cw 5/src/SOIL/stbi_DDS_aug.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
adding DDS loading support to stbi
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STB_IMAGE_DDS_AUGMENTATION
|
||||
#define HEADER_STB_IMAGE_DDS_AUGMENTATION
|
||||
|
||||
// is it a DDS file?
|
||||
extern int stbi_dds_test_memory (stbi_uc const *buffer, int len);
|
||||
|
||||
extern stbi_uc *stbi_dds_load (char *filename, int *x, int *y, int *comp, int req_comp);
|
||||
extern stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
|
||||
#ifndef STBI_NO_STDIO
|
||||
extern int stbi_dds_test_file (FILE *f);
|
||||
extern stbi_uc *stbi_dds_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
//// end header file /////////////////////////////////////////////////////
|
||||
#endif // HEADER_STB_IMAGE_DDS_AUGMENTATION
|
511
cw 5/src/SOIL/stbi_DDS_aug_c.h
Normal file
511
cw 5/src/SOIL/stbi_DDS_aug_c.h
Normal file
@ -0,0 +1,511 @@
|
||||
|
||||
/// DDS file support, does decoding, _not_ direct uploading
|
||||
/// (use SOIL for that ;-)
|
||||
|
||||
/// A bunch of DirectDraw Surface structures and flags
|
||||
typedef struct {
|
||||
unsigned int dwMagic;
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwHeight;
|
||||
unsigned int dwWidth;
|
||||
unsigned int dwPitchOrLinearSize;
|
||||
unsigned int dwDepth;
|
||||
unsigned int dwMipMapCount;
|
||||
unsigned int dwReserved1[ 11 ];
|
||||
|
||||
// DDPIXELFORMAT
|
||||
struct {
|
||||
unsigned int dwSize;
|
||||
unsigned int dwFlags;
|
||||
unsigned int dwFourCC;
|
||||
unsigned int dwRGBBitCount;
|
||||
unsigned int dwRBitMask;
|
||||
unsigned int dwGBitMask;
|
||||
unsigned int dwBBitMask;
|
||||
unsigned int dwAlphaBitMask;
|
||||
} sPixelFormat;
|
||||
|
||||
// DDCAPS2
|
||||
struct {
|
||||
unsigned int dwCaps1;
|
||||
unsigned int dwCaps2;
|
||||
unsigned int dwDDSX;
|
||||
unsigned int dwReserved;
|
||||
} sCaps;
|
||||
unsigned int dwReserved2;
|
||||
} DDS_header ;
|
||||
|
||||
// the following constants were copied directly off the MSDN website
|
||||
|
||||
// The dwFlags member of the original DDSURFACEDESC2 structure
|
||||
// can be set to one or more of the following values.
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
// DirectDraw Pixel Format
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_RGB 0x00000040
|
||||
|
||||
// The dwCaps1 member of the DDSCAPS2 structure can be
|
||||
// set to one or more of the following values.
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
|
||||
// The dwCaps2 member of the DDSCAPS2 structure can be
|
||||
// set to one or more of the following values.
|
||||
#define DDSCAPS2_CUBEMAP 0x00000200
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
|
||||
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
|
||||
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
|
||||
#define DDSCAPS2_VOLUME 0x00200000
|
||||
|
||||
static int dds_test(stbi *s)
|
||||
{
|
||||
// check the magic number
|
||||
if (get8(s) != 'D') return 0;
|
||||
if (get8(s) != 'D') return 0;
|
||||
if (get8(s) != 'S') return 0;
|
||||
if (get8(s) != ' ') return 0;
|
||||
// check header size
|
||||
if (get32le(s) != 124) return 0;
|
||||
return 1;
|
||||
}
|
||||
#ifndef STBI_NO_STDIO
|
||||
int stbi_dds_test_file (FILE *f)
|
||||
{
|
||||
stbi s;
|
||||
int r,n = ftell(f);
|
||||
start_file(&s,f);
|
||||
r = dds_test(&s);
|
||||
fseek(f,n,SEEK_SET);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
int stbi_dds_test_memory (stbi_uc const *buffer, int len)
|
||||
{
|
||||
stbi s;
|
||||
start_mem(&s,buffer, len);
|
||||
return dds_test(&s);
|
||||
}
|
||||
|
||||
// helper functions
|
||||
int stbi_convert_bit_range( int c, int from_bits, int to_bits )
|
||||
{
|
||||
int b = (1 << (from_bits - 1)) + c * ((1 << to_bits) - 1);
|
||||
return (b + (b >> from_bits)) >> from_bits;
|
||||
}
|
||||
void stbi_rgb_888_from_565( unsigned int c, int *r, int *g, int *b )
|
||||
{
|
||||
*r = stbi_convert_bit_range( (c >> 11) & 31, 5, 8 );
|
||||
*g = stbi_convert_bit_range( (c >> 05) & 63, 6, 8 );
|
||||
*b = stbi_convert_bit_range( (c >> 00) & 31, 5, 8 );
|
||||
}
|
||||
void stbi_decode_DXT1_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int next_bit = 4*8;
|
||||
int i, r, g, b;
|
||||
int c0, c1;
|
||||
unsigned char decode_colors[4*4];
|
||||
// find the 2 primary colors
|
||||
c0 = compressed[0] + (compressed[1] << 8);
|
||||
c1 = compressed[2] + (compressed[3] << 8);
|
||||
stbi_rgb_888_from_565( c0, &r, &g, &b );
|
||||
decode_colors[0] = r;
|
||||
decode_colors[1] = g;
|
||||
decode_colors[2] = b;
|
||||
decode_colors[3] = 255;
|
||||
stbi_rgb_888_from_565( c1, &r, &g, &b );
|
||||
decode_colors[4] = r;
|
||||
decode_colors[5] = g;
|
||||
decode_colors[6] = b;
|
||||
decode_colors[7] = 255;
|
||||
if( c0 > c1 )
|
||||
{
|
||||
// no alpha, 2 interpolated colors
|
||||
decode_colors[8] = (2*decode_colors[0] + decode_colors[4]) / 3;
|
||||
decode_colors[9] = (2*decode_colors[1] + decode_colors[5]) / 3;
|
||||
decode_colors[10] = (2*decode_colors[2] + decode_colors[6]) / 3;
|
||||
decode_colors[11] = 255;
|
||||
decode_colors[12] = (decode_colors[0] + 2*decode_colors[4]) / 3;
|
||||
decode_colors[13] = (decode_colors[1] + 2*decode_colors[5]) / 3;
|
||||
decode_colors[14] = (decode_colors[2] + 2*decode_colors[6]) / 3;
|
||||
decode_colors[15] = 255;
|
||||
} else
|
||||
{
|
||||
// 1 interpolated color, alpha
|
||||
decode_colors[8] = (decode_colors[0] + decode_colors[4]) / 2;
|
||||
decode_colors[9] = (decode_colors[1] + decode_colors[5]) / 2;
|
||||
decode_colors[10] = (decode_colors[2] + decode_colors[6]) / 2;
|
||||
decode_colors[11] = 255;
|
||||
decode_colors[12] = 0;
|
||||
decode_colors[13] = 0;
|
||||
decode_colors[14] = 0;
|
||||
decode_colors[15] = 0;
|
||||
}
|
||||
// decode the block
|
||||
for( i = 0; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 4;
|
||||
next_bit += 2;
|
||||
uncompressed[i+0] = decode_colors[idx+0];
|
||||
uncompressed[i+1] = decode_colors[idx+1];
|
||||
uncompressed[i+2] = decode_colors[idx+2];
|
||||
uncompressed[i+3] = decode_colors[idx+3];
|
||||
}
|
||||
// done
|
||||
}
|
||||
void stbi_decode_DXT23_alpha_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int i, next_bit = 0;
|
||||
// each alpha value gets 4 bits
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
uncompressed[i] = stbi_convert_bit_range(
|
||||
(compressed[next_bit>>3] >> (next_bit&7)) & 15,
|
||||
4, 8 );
|
||||
next_bit += 4;
|
||||
}
|
||||
}
|
||||
void stbi_decode_DXT45_alpha_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int i, next_bit = 8*2;
|
||||
unsigned char decode_alpha[8];
|
||||
// each alpha value gets 3 bits, and the 1st 2 bytes are the range
|
||||
decode_alpha[0] = compressed[0];
|
||||
decode_alpha[1] = compressed[1];
|
||||
if( decode_alpha[0] > decode_alpha[1] )
|
||||
{
|
||||
// 6 step intermediate
|
||||
decode_alpha[2] = (6*decode_alpha[0] + 1*decode_alpha[1]) / 7;
|
||||
decode_alpha[3] = (5*decode_alpha[0] + 2*decode_alpha[1]) / 7;
|
||||
decode_alpha[4] = (4*decode_alpha[0] + 3*decode_alpha[1]) / 7;
|
||||
decode_alpha[5] = (3*decode_alpha[0] + 4*decode_alpha[1]) / 7;
|
||||
decode_alpha[6] = (2*decode_alpha[0] + 5*decode_alpha[1]) / 7;
|
||||
decode_alpha[7] = (1*decode_alpha[0] + 6*decode_alpha[1]) / 7;
|
||||
} else
|
||||
{
|
||||
// 4 step intermediate, pluss full and none
|
||||
decode_alpha[2] = (4*decode_alpha[0] + 1*decode_alpha[1]) / 5;
|
||||
decode_alpha[3] = (3*decode_alpha[0] + 2*decode_alpha[1]) / 5;
|
||||
decode_alpha[4] = (2*decode_alpha[0] + 3*decode_alpha[1]) / 5;
|
||||
decode_alpha[5] = (1*decode_alpha[0] + 4*decode_alpha[1]) / 5;
|
||||
decode_alpha[6] = 0;
|
||||
decode_alpha[7] = 255;
|
||||
}
|
||||
for( i = 3; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = 0, bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 0;
|
||||
++next_bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 1;
|
||||
++next_bit;
|
||||
bit = (compressed[next_bit>>3] >> (next_bit&7)) & 1;
|
||||
idx += bit << 2;
|
||||
++next_bit;
|
||||
uncompressed[i] = decode_alpha[idx & 7];
|
||||
}
|
||||
// done
|
||||
}
|
||||
void stbi_decode_DXT_color_block(
|
||||
unsigned char uncompressed[16*4],
|
||||
unsigned char compressed[8] )
|
||||
{
|
||||
int next_bit = 4*8;
|
||||
int i, r, g, b;
|
||||
int c0, c1;
|
||||
unsigned char decode_colors[4*3];
|
||||
// find the 2 primary colors
|
||||
c0 = compressed[0] + (compressed[1] << 8);
|
||||
c1 = compressed[2] + (compressed[3] << 8);
|
||||
stbi_rgb_888_from_565( c0, &r, &g, &b );
|
||||
decode_colors[0] = r;
|
||||
decode_colors[1] = g;
|
||||
decode_colors[2] = b;
|
||||
stbi_rgb_888_from_565( c1, &r, &g, &b );
|
||||
decode_colors[3] = r;
|
||||
decode_colors[4] = g;
|
||||
decode_colors[5] = b;
|
||||
// Like DXT1, but no choicees:
|
||||
// no alpha, 2 interpolated colors
|
||||
decode_colors[6] = (2*decode_colors[0] + decode_colors[3]) / 3;
|
||||
decode_colors[7] = (2*decode_colors[1] + decode_colors[4]) / 3;
|
||||
decode_colors[8] = (2*decode_colors[2] + decode_colors[5]) / 3;
|
||||
decode_colors[9] = (decode_colors[0] + 2*decode_colors[3]) / 3;
|
||||
decode_colors[10] = (decode_colors[1] + 2*decode_colors[4]) / 3;
|
||||
decode_colors[11] = (decode_colors[2] + 2*decode_colors[5]) / 3;
|
||||
// decode the block
|
||||
for( i = 0; i < 16*4; i += 4 )
|
||||
{
|
||||
int idx = ((compressed[next_bit>>3] >> (next_bit & 7)) & 3) * 3;
|
||||
next_bit += 2;
|
||||
uncompressed[i+0] = decode_colors[idx+0];
|
||||
uncompressed[i+1] = decode_colors[idx+1];
|
||||
uncompressed[i+2] = decode_colors[idx+2];
|
||||
}
|
||||
// done
|
||||
}
|
||||
static stbi_uc *dds_load(stbi *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
// all variables go up front
|
||||
stbi_uc *dds_data = NULL;
|
||||
stbi_uc block[16*4];
|
||||
stbi_uc compressed[8];
|
||||
int flags, DXT_family;
|
||||
int has_alpha, has_mipmap;
|
||||
int is_compressed, cubemap_faces;
|
||||
int block_pitch, num_blocks;
|
||||
DDS_header header;
|
||||
int i, sz, cf;
|
||||
// load the header
|
||||
if( sizeof( DDS_header ) != 128 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
getn( s, (stbi_uc*)(&header), 128 );
|
||||
// and do some checking
|
||||
if( header.dwMagic != (('D' << 0) | ('D' << 8) | ('S' << 16) | (' ' << 24)) ) return NULL;
|
||||
if( header.dwSize != 124 ) return NULL;
|
||||
flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||
if( (header.dwFlags & flags) != flags ) return NULL;
|
||||
/* According to the MSDN spec, the dwFlags should contain
|
||||
DDSD_LINEARSIZE if it's compressed, or DDSD_PITCH if
|
||||
uncompressed. Some DDS writers do not conform to the
|
||||
spec, so I need to make my reader more tolerant */
|
||||
if( header.sPixelFormat.dwSize != 32 ) return NULL;
|
||||
flags = DDPF_FOURCC | DDPF_RGB;
|
||||
if( (header.sPixelFormat.dwFlags & flags) == 0 ) return NULL;
|
||||
if( (header.sCaps.dwCaps1 & DDSCAPS_TEXTURE) == 0 ) return NULL;
|
||||
// get the image data
|
||||
s->img_x = header.dwWidth;
|
||||
s->img_y = header.dwHeight;
|
||||
s->img_n = 4;
|
||||
is_compressed = (header.sPixelFormat.dwFlags & DDPF_FOURCC) / DDPF_FOURCC;
|
||||
has_alpha = (header.sPixelFormat.dwFlags & DDPF_ALPHAPIXELS) / DDPF_ALPHAPIXELS;
|
||||
has_mipmap = (header.sCaps.dwCaps1 & DDSCAPS_MIPMAP) && (header.dwMipMapCount > 1);
|
||||
cubemap_faces = (header.sCaps.dwCaps2 & DDSCAPS2_CUBEMAP) / DDSCAPS2_CUBEMAP;
|
||||
/* I need cubemaps to have square faces */
|
||||
cubemap_faces &= (s->img_x == s->img_y);
|
||||
cubemap_faces *= 5;
|
||||
cubemap_faces += 1;
|
||||
block_pitch = (s->img_x+3) >> 2;
|
||||
num_blocks = block_pitch * ((s->img_y+3) >> 2);
|
||||
/* let the user know what's going on */
|
||||
*x = s->img_x;
|
||||
*y = s->img_y;
|
||||
*comp = s->img_n;
|
||||
/* is this uncompressed? */
|
||||
if( is_compressed )
|
||||
{
|
||||
/* compressed */
|
||||
// note: header.sPixelFormat.dwFourCC is something like (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24))
|
||||
DXT_family = 1 + (header.sPixelFormat.dwFourCC >> 24) - '1';
|
||||
if( (DXT_family < 1) || (DXT_family > 5) ) return NULL;
|
||||
/* check the expected size...oops, nevermind...
|
||||
those non-compliant writers leave
|
||||
dwPitchOrLinearSize == 0 */
|
||||
// passed all the tests, get the RAM for decoding
|
||||
sz = (s->img_x)*(s->img_y)*4*cubemap_faces;
|
||||
dds_data = (unsigned char*)malloc( sz );
|
||||
/* do this once for each face */
|
||||
for( cf = 0; cf < cubemap_faces; ++ cf )
|
||||
{
|
||||
// now read and decode all the blocks
|
||||
for( i = 0; i < num_blocks; ++i )
|
||||
{
|
||||
// where are we?
|
||||
int bx, by, bw=4, bh=4;
|
||||
int ref_x = 4 * (i % block_pitch);
|
||||
int ref_y = 4 * (i / block_pitch);
|
||||
// get the next block's worth of compressed data, and decompress it
|
||||
if( DXT_family == 1 )
|
||||
{
|
||||
// DXT1
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT1_block( block, compressed );
|
||||
} else if( DXT_family < 4 )
|
||||
{
|
||||
// DXT2/3
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT23_alpha_block ( block, compressed );
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT_color_block ( block, compressed );
|
||||
} else
|
||||
{
|
||||
// DXT4/5
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT45_alpha_block ( block, compressed );
|
||||
getn( s, compressed, 8 );
|
||||
stbi_decode_DXT_color_block ( block, compressed );
|
||||
}
|
||||
// is this a partial block?
|
||||
if( ref_x + 4 > s->img_x )
|
||||
{
|
||||
bw = s->img_x - ref_x;
|
||||
}
|
||||
if( ref_y + 4 > s->img_y )
|
||||
{
|
||||
bh = s->img_y - ref_y;
|
||||
}
|
||||
// now drop our decompressed data into the buffer
|
||||
for( by = 0; by < bh; ++by )
|
||||
{
|
||||
int idx = 4*((ref_y+by+cf*s->img_x)*s->img_x + ref_x);
|
||||
for( bx = 0; bx < bw*4; ++bx )
|
||||
{
|
||||
|
||||
dds_data[idx+bx] = block[by*16+bx];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* done reading and decoding the main image...
|
||||
skip MIPmaps if present */
|
||||
if( has_mipmap )
|
||||
{
|
||||
int block_size = 16;
|
||||
if( DXT_family == 1 )
|
||||
{
|
||||
block_size = 8;
|
||||
}
|
||||
for( i = 1; i < header.dwMipMapCount; ++i )
|
||||
{
|
||||
int mx = s->img_x >> (i + 2);
|
||||
int my = s->img_y >> (i + 2);
|
||||
if( mx < 1 )
|
||||
{
|
||||
mx = 1;
|
||||
}
|
||||
if( my < 1 )
|
||||
{
|
||||
my = 1;
|
||||
}
|
||||
skip( s, mx*my*block_size );
|
||||
}
|
||||
}
|
||||
}/* per cubemap face */
|
||||
} else
|
||||
{
|
||||
/* uncompressed */
|
||||
DXT_family = 0;
|
||||
s->img_n = 3;
|
||||
if( has_alpha )
|
||||
{
|
||||
s->img_n = 4;
|
||||
}
|
||||
*comp = s->img_n;
|
||||
sz = s->img_x*s->img_y*s->img_n*cubemap_faces;
|
||||
dds_data = (unsigned char*)malloc( sz );
|
||||
/* do this once for each face */
|
||||
for( cf = 0; cf < cubemap_faces; ++ cf )
|
||||
{
|
||||
/* read the main image for this face */
|
||||
getn( s, &dds_data[cf*s->img_x*s->img_y*s->img_n], s->img_x*s->img_y*s->img_n );
|
||||
/* done reading and decoding the main image...
|
||||
skip MIPmaps if present */
|
||||
if( has_mipmap )
|
||||
{
|
||||
for( i = 1; i < header.dwMipMapCount; ++i )
|
||||
{
|
||||
int mx = s->img_x >> i;
|
||||
int my = s->img_y >> i;
|
||||
if( mx < 1 )
|
||||
{
|
||||
mx = 1;
|
||||
}
|
||||
if( my < 1 )
|
||||
{
|
||||
my = 1;
|
||||
}
|
||||
skip( s, mx*my*s->img_n );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* data was BGR, I need it RGB */
|
||||
for( i = 0; i < sz; i += s->img_n )
|
||||
{
|
||||
unsigned char temp = dds_data[i];
|
||||
dds_data[i] = dds_data[i+2];
|
||||
dds_data[i+2] = temp;
|
||||
}
|
||||
}
|
||||
/* finished decompressing into RGBA,
|
||||
adjust the y size if we have a cubemap
|
||||
note: sz is already up to date */
|
||||
s->img_y *= cubemap_faces;
|
||||
*y = s->img_y;
|
||||
// did the user want something else, or
|
||||
// see if all the alpha values are 255 (i.e. no transparency)
|
||||
has_alpha = 0;
|
||||
if( s->img_n == 4)
|
||||
{
|
||||
for( i = 3; (i < sz) && (has_alpha == 0); i += 4 )
|
||||
{
|
||||
has_alpha |= (dds_data[i] < 255);
|
||||
}
|
||||
}
|
||||
if( (req_comp <= 4) && (req_comp >= 1) )
|
||||
{
|
||||
// user has some requirements, meet them
|
||||
if( req_comp != s->img_n )
|
||||
{
|
||||
dds_data = convert_format( dds_data, s->img_n, req_comp, s->img_x, s->img_y );
|
||||
*comp = s->img_n;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// user had no requirements, only drop to RGB is no alpha
|
||||
if( (has_alpha == 0) && (s->img_n == 4) )
|
||||
{
|
||||
dds_data = convert_format( dds_data, 4, 3, s->img_x, s->img_y );
|
||||
*comp = 3;
|
||||
}
|
||||
}
|
||||
// OK, done
|
||||
return dds_data;
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
stbi_uc *stbi_dds_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi s;
|
||||
start_file(&s,f);
|
||||
return dds_load(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
stbi_uc *stbi_dds_load (char *filename, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi_uc *data;
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f) return NULL;
|
||||
data = stbi_dds_load_from_file(f,x,y,comp,req_comp);
|
||||
fclose(f);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
stbi_uc *stbi_dds_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi s;
|
||||
start_mem(&s,buffer, len);
|
||||
return dds_load(&s,x,y,comp,req_comp);
|
||||
}
|
102
cw 5/src/Shader_Loader.cpp
Normal file
102
cw 5/src/Shader_Loader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "Shader_Loader.h"
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<vector>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Shader_Loader::Shader_Loader(void){}
|
||||
Shader_Loader::~Shader_Loader(void){}
|
||||
|
||||
std::string Shader_Loader::ReadShader(char *filename)
|
||||
{
|
||||
|
||||
std::string shaderCode;
|
||||
std::ifstream file(filename, std::ios::in);
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
std::cout << "Can't read file " << filename << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
shaderCode.resize((unsigned int)file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(&shaderCode[0], shaderCode.size());
|
||||
file.close();
|
||||
return shaderCode;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateShader(GLenum shaderType, std::string
|
||||
source, char* shaderName)
|
||||
{
|
||||
|
||||
int compile_result = 0;
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
const char *shader_code_ptr = source.c_str();
|
||||
const int shader_code_size = source.size();
|
||||
|
||||
glShaderSource(shader, 1, &shader_code_ptr, &shader_code_size);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_result);
|
||||
|
||||
//sprawdz bledy
|
||||
if (compile_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> shader_log(info_log_length);
|
||||
glGetShaderInfoLog(shader, info_log_length, NULL, &shader_log[0]);
|
||||
std::cout << "ERROR compiling shader: " << shaderName << std::endl << &shader_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint Shader_Loader::CreateProgram(char* vertexShaderFilename,
|
||||
char* fragmentShaderFilename)
|
||||
{
|
||||
|
||||
//wczytaj shadery
|
||||
std::string vertex_shader_code = ReadShader(vertexShaderFilename);
|
||||
std::string fragment_shader_code = ReadShader(fragmentShaderFilename);
|
||||
|
||||
GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_code, "vertex shader");
|
||||
GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_code, "fragment shader");
|
||||
|
||||
int link_result = 0;
|
||||
//stworz shader
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_result);
|
||||
//sprawdz bledy w linkerze
|
||||
if (link_result == GL_FALSE)
|
||||
{
|
||||
|
||||
int info_log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
std::vector<char> program_log(info_log_length);
|
||||
glGetProgramInfoLog(program, info_log_length, NULL, &program_log[0]);
|
||||
std::cout << "Shader Loader : LINK ERROR" << std::endl << &program_log[0] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
glDetachShader(program, vertex_shader);
|
||||
glDetachShader(program, fragment_shader);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void Shader_Loader::DeleteProgram( GLuint program )
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
}
|
29
cw 5/src/Shader_Loader.h
Normal file
29
cw 5/src/Shader_Loader.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
||||
class Shader_Loader
|
||||
{
|
||||
private:
|
||||
|
||||
std::string ReadShader(char *filename);
|
||||
GLuint CreateShader(GLenum shaderType,
|
||||
std::string source,
|
||||
char* shaderName);
|
||||
|
||||
public:
|
||||
|
||||
Shader_Loader(void);
|
||||
~Shader_Loader(void);
|
||||
GLuint CreateProgram(char* VertexShaderFilename,
|
||||
char* FragmentShaderFilename);
|
||||
|
||||
void DeleteProgram(GLuint program);
|
||||
|
||||
};
|
||||
}
|
230
cw 5/src/ex_5_1.hpp
Normal file
230
cw 5/src/ex_5_1.hpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
GLuint program;
|
||||
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
glm::vec3 lightDir = glm::normalize(glm::vec3(1.f, 1.f, 1.f));
|
||||
glm::vec3 lightColor = glm::vec3(1.f, 1.f, 1.f);
|
||||
|
||||
glm::vec3 spaceshipPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 spaceshipDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
GLuint VAO,VBO;
|
||||
|
||||
float aspectRatio = 1.f;
|
||||
|
||||
float lastTime = -1.f;
|
||||
float deltaTime = 0.f;
|
||||
|
||||
void updateDeltaTime(float time) {
|
||||
if (lastTime < 0) {
|
||||
lastTime = time;
|
||||
return;
|
||||
}
|
||||
|
||||
deltaTime = time - lastTime;
|
||||
if (deltaTime > 0.1) deltaTime = 0.1;
|
||||
lastTime = time;
|
||||
}
|
||||
|
||||
glm::mat4 createCameraMatrix()
|
||||
{
|
||||
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir,glm::vec3(0.f,1.f,0.f)));
|
||||
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide,cameraDir));
|
||||
glm::mat4 cameraRotrationMatrix = glm::mat4({
|
||||
cameraSide.x,cameraSide.y,cameraSide.z,0,
|
||||
cameraUp.x,cameraUp.y,cameraUp.z ,0,
|
||||
-cameraDir.x,-cameraDir.y,-cameraDir.z,0,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix);
|
||||
glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos);
|
||||
|
||||
return cameraMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 createPerspectiveMatrix()
|
||||
{
|
||||
|
||||
glm::mat4 perspectiveMatrix;
|
||||
float n = 0.05;
|
||||
float f = 20.;
|
||||
float a1 = glm::min(aspectRatio, 1.f);
|
||||
float a2 = glm::min(1 / aspectRatio, 1.f);
|
||||
perspectiveMatrix = glm::mat4({
|
||||
1,0.,0.,0.,
|
||||
0.,aspectRatio,0.,0.,
|
||||
0.,0.,(f+n) / (n - f),2*f * n / (n - f),
|
||||
0.,0.,-1.,0.,
|
||||
});
|
||||
|
||||
|
||||
perspectiveMatrix=glm::transpose(perspectiveMatrix);
|
||||
|
||||
return perspectiveMatrix;
|
||||
}
|
||||
|
||||
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
|
||||
glUseProgram(program);
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "modelMat"), 1, GL_FALSE, (float*)&modelMatrix);
|
||||
glUniform3f(glGetUniformLocation(program, "color"), color.x,color.y,color.z);
|
||||
glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z);
|
||||
glUniform3f(glGetUniformLocation(program, "lightColor"), lightColor.x, lightColor.y, lightColor.z);
|
||||
glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
//TEST
|
||||
glUniform1f(glGetUniformLocation(program, "time"), lastTime);
|
||||
|
||||
Core::DrawContext(context);
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
{
|
||||
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glm::mat4 transformation;
|
||||
float time = glfwGetTime();
|
||||
updateDeltaTime(time);
|
||||
|
||||
|
||||
|
||||
drawObjectColor(sphereContext,glm::mat4(),glm::vec3(1.0, 1.0, 0.3));
|
||||
|
||||
drawObjectColor(sphereContext, glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3));
|
||||
|
||||
drawObjectColor(sphereContext,
|
||||
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
||||
glm::vec3(0.5, 0.5, 0.5));
|
||||
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
|
||||
glm::mat4 specshipCameraRotrationMatrix = glm::mat4({
|
||||
spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0,
|
||||
spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0,
|
||||
-spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0,
|
||||
0.,0.,0.,1.,
|
||||
});
|
||||
|
||||
|
||||
//drawObjectColor(shipContext,
|
||||
// glm::translate(cameraPos + 1.5 * cameraDir + cameraUp * -0.5f) * inveseCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
|
||||
// glm::vec3(0.3, 0.3, 0.5)
|
||||
// );
|
||||
drawObjectColor(shipContext,
|
||||
glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()) * glm::scale(glm::vec3(0.2f)),
|
||||
glm::vec3(0.3, 0.3, 0.5)
|
||||
);
|
||||
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
aspectRatio = width / float(height);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
void loadModelToContext(std::string path, Core::RenderContext& context)
|
||||
{
|
||||
Assimp::Importer import;
|
||||
const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
context.initFromAssimpMesh(scene->mMeshes[0]);
|
||||
}
|
||||
|
||||
void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_5_1.vert", "shaders/shader_5_1.frag");
|
||||
|
||||
loadModelToContext("./models/sphere.obj", sphereContext);
|
||||
loadModelToContext("./models/spaceship.obj", shipContext);
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
{
|
||||
shaderLoader.DeleteProgram(program);
|
||||
}
|
||||
|
||||
//obsluga wejscia
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f);
|
||||
float angleSpeed = 0.05f * deltaTime * 60;
|
||||
float moveSpeed = 0.05f * deltaTime * 60;
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
|
||||
angleSpeed *= 3;
|
||||
moveSpeed *= 3;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipDir * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipSide * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
|
||||
spaceshipPos += spaceshipUp * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
|
||||
spaceshipPos -= spaceshipUp * moveSpeed;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0));
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0));
|
||||
|
||||
cameraPos = spaceshipPos - 0.3f * spaceshipDir + glm::vec3(0, 1, 0) * 0.1f;
|
||||
cameraDir = spaceshipDir;
|
||||
|
||||
//cameraDir = glm::normalize(-cameraPos);
|
||||
|
||||
}
|
||||
|
||||
// funkcja jest glowna petla
|
||||
void renderLoop(GLFWwindow* window) {
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
renderScene(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
//}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user