Compare commits

...

9 commits

Author SHA1 Message Date
maelstrom cd906be4c9 sdfvsdvsdv 2024-11-21 18:49:39 +01:00
maelstrom a36407c75e Better Studs 2024-11-19 23:58:32 +01:00
maelstrom 9b06763cfb Studs 2024-11-19 12:46:43 +01:00
maelstrom d10606dca5 Adjustin' 2024-11-17 13:11:53 +01:00
maelstrom 9162b9327e le humble skybox 2024-10-15 19:02:55 +02:00
maelstrom fed15e4ff8 A skybox that actually renders! 2024-10-15 18:52:22 +02:00
maelstrom a9a7422a19 skybox loading code 2024-10-15 18:42:55 +02:00
maelstrom c0e6669045 taste the rainbow 2024-10-09 18:19:37 +02:00
maelstrom 2e47b379fc Somethin's cookin here! 2024-10-09 17:50:20 +02:00
29 changed files with 347 additions and 20 deletions

View file

@ -29,11 +29,19 @@ struct PointLight {
float quadratic;
};
const int FaceRight = 0;
const int FaceTop = 1;
const int FaceBack = 2;
const int FaceLeft = 3;
const int FaceBottom = 4;
const int FaceFront = 5;
// I/O
in vec3 vPos;
in vec3 vNormal;
in vec2 vTexCoords;
flat in int vSurfaceZ;
out vec4 FragColor;
@ -44,6 +52,7 @@ uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform int numPointLights;
uniform DirLight sunLight;
uniform Material material;
uniform sampler2DArray studs;
// Functions
@ -61,8 +70,9 @@ void main() {
for (int i = 0; i < numPointLights; i++) {
result += calculatePointLight(pointLights[i]);
}
FragColor = vec4(result, 1.0);
vec4 studPx = texture(studs, vec3(vTexCoords, vSurfaceZ));
FragColor = vec4(mix(result, vec3(studPx), studPx.w), 1);
}
vec3 calculateDirectionalLight(DirLight light) {

View file

@ -3,18 +3,60 @@ layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
const int FaceRight = 0;
const int FaceTop = 1;
const int FaceBack = 2;
const int FaceLeft = 3;
const int FaceBottom = 4;
const int FaceFront = 5;
const int SurfaceSmooth = 0;
const int SurfaceGlue = 1;
const int SurfaceWeld = 2;
const int SurfaceStuds = 3;
const int SurfaceInlets = 4;
const int SurfaceUniversal = 5;
out vec3 vPos;
out vec3 vNormal;
out vec2 vTexCoords;
flat out int vSurfaceZ;
uniform mat4 model;
uniform mat3 normalMatrix;
uniform mat4 view;
uniform mat4 projection;
uniform int surfaces[6];
uniform vec3 texScale;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
vPos = vec3(model * vec4(aPos, 1.0));
vNormal = normalMatrix * aNormal;
int vFace = aNormal == vec3(0,1,0) ? FaceTop :
aNormal == vec3(0, -1, 0) ? FaceBottom :
aNormal == vec3(1, 0, 0) ? FaceRight :
aNormal == vec3(-1, 0, 0) ? FaceLeft :
aNormal == vec3(0, 0, 1) ? FaceFront :
aNormal == vec3(0, 0, -1) ? FaceBack : -1;
vSurfaceZ = surfaces[vFace];
// if (surfaces[vFace] > SurfaceUniversal) vSurfaceZ = 0;
switch (vFace) {
case FaceTop:
case FaceBottom:
// vTexCoords = aTexCoords * vec2(texScale.x / 2, fract(surfaceOffset + texScale.z / 12));
vTexCoords = aTexCoords * vec2(texScale.x, texScale.z) / 2;
break;
case FaceLeft:
case FaceRight:
vTexCoords = aTexCoords * vec2(texScale.y, texScale.z) / 2;
break;
case FaceFront:
case FaceBack:
vTexCoords = aTexCoords * vec2(texScale.x, texScale.y) / 2;
break;
};
}

16
assets/shaders/skybox.fs Normal file
View file

@ -0,0 +1,16 @@
#version 330 core
uniform samplerCube skybox;
// in vec3 vPos;
// in vec3 vNormal;
in vec3 vTexCoords;
out vec4 fColor;
// Main
void main() {
// fColor = texture(uTexture, vTexCoords);
fColor = texture(skybox, vTexCoords);
}

17
assets/shaders/skybox.vs Normal file
View file

@ -0,0 +1,17 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
// out vec3 vPos;
// out vec3 vNormal;
out vec3 vTexCoords;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vTexCoords = aPos;
gl_Position = projection * view * vec4(aPos, 1.0);
}

View file

@ -0,0 +1 @@
null_plainsky is copyright of Jauhn Dabz, jauhn@yahoo.com, https://nullpoint.fragland.net

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
assets/textures/studs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/textures/studs.psd Normal file

Binary file not shown.

BIN
assets/textures/studs.xcf Normal file

Binary file not shown.

BIN
assets/textures/studs1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -18,7 +18,7 @@ public:
float pitch = 0., yaw = -90., roll = 0.;
float movementSpeed = 5.0f;
float movementSpeed = 10.0f;
float mouseSensitivity = 0.2f;
Camera(glm::vec3 initialPosition);

View file

@ -45,9 +45,9 @@ int main() {
parts.push_back(Part {
.position = glm::vec3(0, -5, 0),
.rotation = glm::vec3(0),
.scale = glm::vec3(5, 1, 5),
.scale = glm::vec3(512, 1.2, 512),
.material = Material {
.diffuse = glm::vec3(1.0f, 0.5f, 0.31f),
.diffuse = glm::vec3(0.388235, 0.372549, 0.384314),
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 32.0f,
},
@ -58,9 +58,9 @@ int main() {
parts.push_back(Part {
.position = glm::vec3(0),
.rotation = glm::vec3(0),
.scale = glm::vec3(1, 1, 1),
.scale = glm::vec3(4, 1.2, 2),
.material = Material {
.diffuse = glm::vec3(1.0f, 0.5f, 0.31f),
.diffuse = glm::vec3(0.639216f, 0.635294f, 0.647059f),
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 32.0f,
}

View file

@ -30,6 +30,7 @@ void simulationInit() {
rp::Quaternion orientation = rp::Quaternion::identity();
rp::Transform transform(position, orientation);
rp::RigidBody* body = world->createRigidBody(transform);
world->setGravity(rp::Vector3(0, -196.2, 0));
}
void syncPartPhysics(Part& part) {
@ -48,13 +49,14 @@ void syncPartPhysics(Part& part) {
part.rigidBody->removeCollider(part.rigidBody->getCollider(0));
}
if (part.rigidBody->getNbColliders() == 0)
part.rigidBody->addCollider(shape, rp::Transform());
part.rigidBody->setType(part.anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC);
}
void physicsStep(float deltaTime) {
// Step the simulation a few steps
world->update(deltaTime);
world->update(deltaTime / 2);
for (Part& part : parts) {
const rp::Transform& transform = part.rigidBody->getTransform();

View file

@ -5,7 +5,7 @@ Mesh* CUBE_MESH;
void initMeshes() {
static float vertices[] = {
// positions // normals // texture coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,

View file

@ -3,6 +3,7 @@
#include <GL/gl.h>
#include <cstdio>
#include <glm/ext.hpp>
#include <glm/ext/matrix_float4x4.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/glm.hpp>
#include <glm/trigonometric.hpp>
@ -13,12 +14,18 @@
#include "defaultmeshes.h"
#include "../camera.h"
#include "../part.h"
#include "skybox.h"
#include "surface.h"
#include "texture3d.h"
#include "renderer.h"
Shader *shader = NULL;
Shader *skyboxShader = NULL;
extern Camera camera;
extern std::vector<Part> parts;
Skybox* skyboxTexture = NULL;
Texture3D* studsTexture = NULL;
void renderInit(GLFWwindow* window) {
glViewport(0, 0, 1200, 900);
@ -26,31 +33,46 @@ void renderInit(GLFWwindow* window) {
initMeshes();
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
skyboxTexture = new Skybox({
"assets/textures/skybox/null_plainsky512_lf.jpg",
"assets/textures/skybox/null_plainsky512_rt.jpg",
"assets/textures/skybox/null_plainsky512_up.jpg",
"assets/textures/skybox/null_plainsky512_dn.jpg",
"assets/textures/skybox/null_plainsky512_ft.jpg",
"assets/textures/skybox/null_plainsky512_bk.jpg",
}, GL_RGB);
studsTexture = new Texture3D("assets/textures/studs.png", 128, 128, 6, GL_RGBA);
// Compile shader
shader = new Shader("assets/shaders/phong.vs", "assets/shaders/phong.fs");
skyboxShader = new Shader("assets/shaders/skybox.vs", "assets/shaders/skybox.fs");
}
void render(GLFWwindow* window) {
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
void renderParts() {
glDepthMask(GL_TRUE);
// Use shader
shader->use();
shader->set("objectColor", glm::vec3(1.0f, 0.5f, 0.31f));
shader->set("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
// shader->set("objectColor", glm::vec3(1.0f, 0.5f, 0.31f));
// shader->set("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
// view/projection transformations
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)1200 / (float)900, 0.1f, 100.0f);
glm::mat4 view = camera.getLookAt();
shader->set("projection", projection);
shader->set("view", view);
shader->set("material", Material {
// .ambient = glm::vec3(1.0f, 0.5f, 0.31f),
.diffuse = glm::vec3(1.0f, 0.5f, 0.31f),
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 32.0f,
});
// shader->set("material", Material {
// // .ambient = glm::vec3(1.0f, 0.5f, 0.31f),
// .diffuse = glm::vec3(0.639216f, 0.635294f, 0.647059f),
// .specular = glm::vec3(0.5f, 0.5f, 0.5f),
// .shininess = 16.0f,
// });
shader->set("sunLight", DirLight {
.direction = glm::vec3(-0.2f, -1.0f, -0.3f),
.ambient = glm::vec3(0.2f, 0.2f, 0.2f),
@ -67,6 +89,11 @@ void render(GLFWwindow* window) {
// .linear = 0.9,
// .quadratic = 0.32,
// });
studsTexture->activate(0);
shader->set("studs", 0);
// shader->set("surfaces[1]", SurfaceStuds);
shader->set("surfaces[1]", SurfaceStuds);
shader->set("surfaces[4]", SurfaceInlets);
// Pre-calculate the normal matrix for the shader
@ -79,10 +106,38 @@ void render(GLFWwindow* window) {
model = model * glm::mat4_cast(part.rotation);
model = glm::scale(model, part.scale);
shader->set("model", model);
shader->set("material", part.material);
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
shader->set("normalMatrix", normalMatrix);
shader->set("texScale", part.scale);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
void renderSkyBox() {
glDepthMask(GL_FALSE);
skyboxShader->use();
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)1200 / (float)900, 0.1f, 100.0f);
// Remove translation component of view, making us always at (0, 0, 0)
glm::mat4 view = glm::mat4(glm::mat3(camera.getLookAt()));
skyboxShader->set("projection", projection);
skyboxShader->set("view", view);
skyboxShader->set("uTexture", 0);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, 36);
}
void render(GLFWwindow* window) {
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderSkyBox();
renderParts();
}

44
src/rendering/skybox.cpp Normal file
View file

@ -0,0 +1,44 @@
#include <GL/glew.h>
#include <GL/gl.h>
#include <stb/stb_image.h>
#include "skybox.h"
Skybox::Skybox(std::array<std::string, 6> faces, unsigned int format) {
glGenTextures(1, &this->ID);
glBindTexture(GL_TEXTURE_CUBE_MAP, this->ID);
// stbi_set_flip_vertically_on_load(true);
for (unsigned int i = 0; i< faces.size(); i++) {
int width, height, nrChannels;
unsigned char *data = stbi_load(faces[i].c_str(), &width, &height,
&nrChannels, 0);
if (!data) {
printf("Failed to load texture '%s'\n", faces[i].c_str());
abort();
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, width, height, 0, format,
GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
// Wrapping
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// Interpolation
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
Skybox::~Skybox() {
glDeleteTextures(1, &this->ID);
}
void Skybox::activate(unsigned int textureIdx) {
glActiveTexture(GL_TEXTURE0 + textureIdx);
glBindTexture(GL_TEXTURE_2D, this->ID);
}

16
src/rendering/skybox.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <array>
#include <string>
#include <vector>
#define GL_RGB 0x1907
class Skybox {
private:
unsigned int ID;
public:
Skybox(std::array<std::string, 6>, unsigned format = GL_RGB);
~Skybox();
void activate(unsigned int textureIdx);
};

10
src/rendering/surface.h Normal file
View file

@ -0,0 +1,10 @@
#pragma once
enum SurfaceType {
SurfaceSmooth = 0,
SurfaceGlue = 1,
SurfaceWeld = 2,
SurfaceStuds = 3,
SurfaceInlets = 4,
SurfaceUniversal = 5,
};

43
src/rendering/texture.cpp Normal file
View file

@ -0,0 +1,43 @@
#include "texture.h"
#include <GL/glew.h>
#include <GL/gl.h>
#include <stb/stb_image.h>
Texture::Texture(const char* texturePath, unsigned int format, bool noMipMaps) {
glGenTextures(1, &this->ID);
glBindTexture(GL_TEXTURE_2D, this->ID);
// Wrapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Interpolation
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// stbi_set_flip_vertically_on_load(true);
int width, height, nrChannels;
unsigned char *data = stbi_load(texturePath, &width, &height,
&nrChannels, 0);
if (!data) {
printf("Failed to load texture '%s'\n", texturePath);
abort();
}
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
GL_UNSIGNED_BYTE, data);
if (!noMipMaps) glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);
}
Texture::~Texture() {
glDeleteTextures(1, &this->ID);
}
void Texture::activate(unsigned int textureIdx) {
glActiveTexture(GL_TEXTURE0 + textureIdx);
glBindTexture(GL_TEXTURE_2D, this->ID);
}

13
src/rendering/texture.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#define GL_RGB 0x1907
class Texture {
private:
unsigned int ID;
public:
Texture(const char* texturePath, unsigned format = GL_RGB, bool noMipMaps = false);
~Texture();
void activate(unsigned int textureIdx);
};

View file

@ -0,0 +1,43 @@
#include "texture3d.h"
#include <GL/glew.h>
#include <GL/gl.h>
#include <stb/stb_image.h>
Texture3D::Texture3D(const char* texturePath, unsigned int tileWidth, unsigned int tileHeight, unsigned int tileCount, unsigned int format) {
glGenTextures(1, &this->ID);
glBindTexture(GL_TEXTURE_2D_ARRAY, this->ID);
// Wrapping
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_REPEAT);
// Interpolation
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// stbi_set_flip_vertically_on_load(true);
int width, height, nrChannels;
unsigned char *data = stbi_load(texturePath, &width, &height,
&nrChannels, 0);
if (!data) {
printf("Failed to load texture '%s'\n", texturePath);
abort();
}
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, tileWidth, tileHeight, /* no of layers= */ tileCount, 0, format,
GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
Texture3D::~Texture3D() {
glDeleteTextures(1, &this->ID);
}
void Texture3D::activate(unsigned int textureIdx) {
glActiveTexture(GL_TEXTURE0 + textureIdx);
glBindTexture(GL_TEXTURE_2D, this->ID);
}

13
src/rendering/texture3d.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#define GL_RGB 0x1907
class Texture3D {
private:
unsigned int ID;
public:
Texture3D(const char* texturePath, unsigned int tileWidth, unsigned int tileHeight, unsigned int tileCount, unsigned format = GL_RGB);
~Texture3D();
void activate(unsigned int textureIdx);
};

2
src/stb.cpp Normal file
View file

@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>