renderer: initial texture support via ArrayTextures

totally stolen textures from minecraft
pull/1/head
EmaMaker 2023-04-10 00:21:49 +02:00
parent 2b1991ff2b
commit 1a4412c5b1
11 changed files with 151 additions and 43 deletions

View File

@ -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);
} }

View File

@ -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

44
shaders/shader-texture.fs Normal file
View File

@ -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;
}

22
shaders/shader-texture.vs Normal file
View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
} }
}; };

View File

@ -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

View File

@ -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());

BIN
textures/cobblestone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

BIN
textures/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

BIN
textures/grass_top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B