renderer: initial texture support via ArrayTextures
totally stolen textures from minecraftpull/1/head
parent
2b1991ff2b
commit
1a4412c5b1
|
@ -17,7 +17,7 @@ namespace chunkmesher{
|
||||||
void draw(Chunk::Chunk* chunk, glm::mat4 model);
|
void draw(Chunk::Chunk* chunk, glm::mat4 model);
|
||||||
|
|
||||||
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight,
|
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight,
|
||||||
glm::vec3 bottomRight, glm::vec3 normal, Block block, bool backFace);
|
glm::vec3 bottomRight, glm::vec3 normal, Block block, int dim, bool backFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
treemap[end] = end_prev_entry->second;
|
treemap[end] = end_prev_entry->second;
|
||||||
|
|
||||||
// A little optimization: delete next key if it is of the same value of the end key
|
// A little optimization: delete next key if it is of the same value of the end key
|
||||||
if(end_next_entry->second == treemap[end]) treemap.erase(end_next_entry);
|
//if(end_next_entry->second == treemap[end]) treemap.erase(end_next_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the start key. Replaces whatever value is already there. Do not place if the element before is of the same value
|
// insert the start key. Replaces whatever value is already there. Do not place if the element before is of the same value
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec3 vNormal;
|
||||||
|
in vec3 vTexCoord;
|
||||||
|
in vec3 FragPos;
|
||||||
|
|
||||||
|
vec3 lightColor = vec3(1.0);
|
||||||
|
vec3 lightDir = -normalize(vec3(0.0, 100.0, 0.0) - vec3(32.0));
|
||||||
|
|
||||||
|
float ambientStrength = 0.4;
|
||||||
|
float diffuseStrength = 0.45;
|
||||||
|
float specularStrength = 0.05;
|
||||||
|
|
||||||
|
uniform vec3 viewPos;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform sampler2DArray textureArray;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 vColor = vec3(texture(textureArray, vTexCoord));
|
||||||
|
|
||||||
|
// offset the normal a tiny bit, so that the color of faces opposing lightDir is not completely
|
||||||
|
// flat
|
||||||
|
vec3 normal = normalize(vNormal);
|
||||||
|
|
||||||
|
// Blinn-Phong lighting
|
||||||
|
// Ambient
|
||||||
|
vec3 ambient = lightColor*vColor;
|
||||||
|
|
||||||
|
// Diffuse
|
||||||
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
vec3 diffuse = vColor * diff;
|
||||||
|
|
||||||
|
// Blinn Specular
|
||||||
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||||
|
float spec = pow(max(dot(normal, halfwayDir), 0.0), 32.0);
|
||||||
|
vec3 specular = lightColor * vColor * spec;
|
||||||
|
|
||||||
|
// Final color
|
||||||
|
vec3 color = ambient * ambientStrength + diffuse * diffuseStrength + specular * specularStrength;
|
||||||
|
FragColor.rgb = color;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec3 aNormal;
|
||||||
|
layout (location = 2) in vec3 aTexCoord;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
out vec3 vNormal;
|
||||||
|
out vec3 vTexCoord;
|
||||||
|
out vec3 FragPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vTexCoord = aTexCoord;
|
||||||
|
vNormal = mat3(transpose(inverse(model))) * aNormal;
|
||||||
|
|
||||||
|
FragPos = vec3(model*vec4(aPos, 1.0));
|
||||||
|
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ void generateNoise3D(Chunk::Chunk *chunk);
|
||||||
|
|
||||||
void generateChunk(Chunk::Chunk *chunk)
|
void generateChunk(Chunk::Chunk *chunk)
|
||||||
{
|
{
|
||||||
generateNoise3D(chunk);
|
generateNoise(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
Block block;
|
Block block;
|
||||||
|
|
|
@ -152,7 +152,7 @@ void mesh(Chunk::Chunk* chunk)
|
||||||
x[2] + du[2] + dv[2]),
|
x[2] + du[2] + dv[2]),
|
||||||
glm::vec3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]),
|
glm::vec3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]),
|
||||||
glm::vec3(backFace ? q[0] : -q[0], backFace ? q[1] : -q[1], backFace ? q[2] : -q[2] ),
|
glm::vec3(backFace ? q[0] : -q[0], backFace ? q[1] : -q[1], backFace ? q[2] : -q[2] ),
|
||||||
mask[n], backFace);
|
mask[n], dim, backFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = 0; l < h; ++l)
|
for (l = 0; l < h; ++l)
|
||||||
|
@ -205,7 +205,7 @@ void sendtogpu(Chunk::Chunk* chunk)
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk->EBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk->EBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, chunk->indices.size() * sizeof(GLuint), &(chunk->indices[0]), GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, chunk->indices.size() * sizeof(GLuint), &(chunk->indices[0]), GL_STATIC_DRAW);
|
||||||
|
|
||||||
// color attribute
|
// texcoords attribute
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, chunk->colorBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, chunk->colorBuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, chunk->colors.size() * sizeof(GLfloat), &(chunk->colors[0]), GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, chunk->colors.size() * sizeof(GLfloat), &(chunk->colors[0]), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ void sendtogpu(Chunk::Chunk* chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight,
|
void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight,
|
||||||
glm::vec3 bottomRight, glm::vec3 normal, Block block, bool backFace)
|
glm::vec3 bottomRight, glm::vec3 normal, Block block, int dim, bool backFace)
|
||||||
{
|
{
|
||||||
|
|
||||||
chunk->vertices.push_back(bottomLeft.x);
|
chunk->vertices.push_back(bottomLeft.x);
|
||||||
|
@ -259,6 +259,56 @@ void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec
|
||||||
chunk->vertices.push_back(normal.y);
|
chunk->vertices.push_back(normal.y);
|
||||||
chunk->vertices.push_back(normal.z);
|
chunk->vertices.push_back(normal.z);
|
||||||
|
|
||||||
|
// texcoords
|
||||||
|
if(dim == 0){
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(bottomRight.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(bottomRight.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topLeft.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(topLeft.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topRight.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(topRight.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
}else if(dim == 1){
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(bottomRight.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(bottomRight.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topLeft.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(topLeft.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topRight.z - bottomLeft.z));
|
||||||
|
chunk->colors.push_back(abs(topRight.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
}else{
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(0);
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(bottomRight.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(abs(bottomRight.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topLeft.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(abs(topLeft.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
|
||||||
|
chunk->colors.push_back(abs(topRight.x - bottomLeft.x));
|
||||||
|
chunk->colors.push_back(abs(topRight.y - bottomLeft.y));
|
||||||
|
chunk->colors.push_back(((int)block) - 2);
|
||||||
|
}
|
||||||
|
|
||||||
if (backFace)
|
if (backFace)
|
||||||
{
|
{
|
||||||
|
@ -279,38 +329,5 @@ void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec
|
||||||
chunk->indices.push_back(chunk->vIndex + 2);
|
chunk->indices.push_back(chunk->vIndex + 2);
|
||||||
}
|
}
|
||||||
chunk->vIndex += 4;
|
chunk->vIndex += 4;
|
||||||
|
|
||||||
// ugly switch case for colors
|
|
||||||
GLfloat r, g, b;
|
|
||||||
switch (block)
|
|
||||||
{
|
|
||||||
case Block::STONE:
|
|
||||||
r = 0.588f;
|
|
||||||
g = 0.588f;
|
|
||||||
b = 0.588f;
|
|
||||||
break;
|
|
||||||
case Block::GRASS:
|
|
||||||
r = 0.05f;
|
|
||||||
g = 0.725f;
|
|
||||||
b = 0.0f;
|
|
||||||
break;
|
|
||||||
case Block::DIRT:
|
|
||||||
r = 0.152f;
|
|
||||||
g = 0.056f;
|
|
||||||
b = 0.056f;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
r = 0.0f;
|
|
||||||
g = 0.0f;
|
|
||||||
b = 0.0f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
chunk->colors.push_back(r);
|
|
||||||
chunk->colors.push_back(g);
|
|
||||||
chunk->colors.push_back(b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,7 +81,7 @@ int main()
|
||||||
lastFPSFrame = currentFrame;
|
lastFPSFrame = currentFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.431f, 0.694f, 1.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Input processing
|
// Input processing
|
||||||
|
|
|
@ -1,15 +1,39 @@
|
||||||
|
#include "renderer.hpp"
|
||||||
|
|
||||||
#include "chunkmanager.hpp"
|
#include "chunkmanager.hpp"
|
||||||
#include "chunkmesher.hpp"
|
#include "chunkmesher.hpp"
|
||||||
#include "renderer.hpp"
|
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
namespace renderer{
|
namespace renderer{
|
||||||
Shader* theShader;
|
Shader* theShader;
|
||||||
|
GLuint chunkTexture;
|
||||||
|
|
||||||
Shader* getRenderShader() { return theShader; }
|
Shader* getRenderShader() { return theShader; }
|
||||||
|
|
||||||
void init(){
|
void init(){
|
||||||
theShader = new Shader{"shaders/shader.vs", "shaders/shader.fs"};
|
// Create Shader
|
||||||
|
theShader = new Shader{"shaders/shader-texture.vs", "shaders/shader-texture.fs"};
|
||||||
|
|
||||||
|
// Create 3d array texture
|
||||||
|
constexpr int layerCount = 3;
|
||||||
|
glGenTextures(1, &chunkTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, chunkTexture);
|
||||||
|
|
||||||
|
int width, height, nrChannels;
|
||||||
|
unsigned char *texels = stbi_load("textures/cobblestone.png", &width, &height, &nrChannels, 0);
|
||||||
|
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, width, height, layerCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texels);
|
||||||
|
unsigned char *texels1 = stbi_load("textures/dirt.png", &width, &height, &nrChannels, 0);
|
||||||
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texels1);
|
||||||
|
unsigned char *texels2 = stbi_load("textures/grass_top.png", &width, &height, &nrChannels, 0);
|
||||||
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, texels2);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_REPEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(){
|
void render(){
|
||||||
|
@ -22,6 +46,8 @@ namespace renderer{
|
||||||
int chunkY=static_cast<int>(cameraPos.y) / CHUNK_SIZE;
|
int chunkY=static_cast<int>(cameraPos.y) / CHUNK_SIZE;
|
||||||
int chunkZ=static_cast<int>(cameraPos.z) / CHUNK_SIZE;
|
int chunkZ=static_cast<int>(cameraPos.z) / CHUNK_SIZE;
|
||||||
|
|
||||||
|
theShader->use();
|
||||||
|
theShader->setVec3("viewPos", cameraPos);
|
||||||
for(int i = 0; i < chunks_volume; i++) {
|
for(int i = 0; i < chunks_volume; i++) {
|
||||||
Chunk::Chunk* c = chunkmanager::getChunks().at(chunkmanager::calculateIndex(chunkmanager::getChunksIndices()[i][0] +
|
Chunk::Chunk* c = chunkmanager::getChunks().at(chunkmanager::calculateIndex(chunkmanager::getChunksIndices()[i][0] +
|
||||||
chunkX, chunkmanager::getChunksIndices()[i][1] + chunkY, chunkmanager::getChunksIndices()[i][2] + chunkZ));
|
chunkX, chunkmanager::getChunksIndices()[i][1] + chunkY, chunkmanager::getChunksIndices()[i][2] + chunkZ));
|
||||||
|
@ -55,7 +81,6 @@ namespace renderer{
|
||||||
if(c->getState(Chunk::CHUNK_STATE_MESH_LOADED) && c->vIndex > 0)
|
if(c->getState(Chunk::CHUNK_STATE_MESH_LOADED) && c->vIndex > 0)
|
||||||
{
|
{
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode
|
||||||
theShader->use();
|
|
||||||
theShader->setMat4("model", model);
|
theShader->setMat4("model", model);
|
||||||
theShader->setMat4("view", theCamera.getView());
|
theShader->setMat4("view", theCamera.getView());
|
||||||
theShader->setMat4("projection", theCamera.getProjection());
|
theShader->setMat4("projection", theCamera.getProjection());
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 265 B |
Binary file not shown.
After Width: | Height: | Size: 266 B |
Binary file not shown.
After Width: | Height: | Size: 633 B |
Loading…
Reference in New Issue