velage/engine/rendering.cpp
miri 3ea07456e2 stuff added,
YEES OHMYGOD FINALLY SHIT'S WORKING
2023-12-15 19:00:02 +01:00

396 lines
No EOL
12 KiB
C++

#include "rendering.hpp"
#include "camera.hpp"
#include "light.hpp"
#include "multipass.hpp"
#include "shader.hpp"
#include <glm/ext/matrix_float4x4.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <iostream>
#include <vector>
bool rendering::SDLinit() {
// init
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
return true;
}
bool rendering::GLinit(SDL_Window *window) {
this->context = SDL_GL_CreateContext(window);
glewExperimental = GL_TRUE;
glewInit();
return true;
}
bool rendering::Shaderinit() {
// read manifest
std::ifstream shader_manifest("shaders.json", std::ifstream::binary);
Json::Value manifest;
shader_manifest >> manifest;
// ====get vertex====
if (!manifest["vertex"].isArray()) {
std::cerr << "Malformed shader.json (vertex)";
return false;
}
std::vector<std::string> shaderpaths_vertex;
// --get paths--
for (int i = 0; i < manifest["vertex"].size(); i++) {
shaderpaths_vertex.push_back(manifest["vertex"][i]["path"].asString());
}
std::vector<std::string> shadercode_vertex;
// --read paths--
for (int i = 0; i < shaderpaths_vertex.size(); i++) {
std::ifstream vert(shaderpaths_vertex.at(i));
if (vert.is_open()) {
std::ostringstream ss;
ss << vert.rdbuf();
shadercode_vertex.push_back(ss.str());
} else {
std::cerr << "vertex shader: " << shaderpaths_vertex.at(i)
<< " is missing.\n";
return false;
}
}
// --compile vertex--
for (int i = 0; i < shadercode_vertex.size(); i++) {
this->vertex_shaders.push_back(glCreateShader(GL_VERTEX_SHADER));
const char *code = shadercode_vertex.at(i).c_str();
glShaderSource(this->vertex_shaders.back(), 1, &code, NULL);
glCompileShader(this->vertex_shaders.back());
GLint status;
glGetShaderiv(this->vertex_shaders.back(), GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char buffer[512];
glGetShaderInfoLog(this->vertex_shaders.back(), 512, NULL, buffer);
std::cerr << "shader compilation error on shader: "
<< shaderpaths_vertex.at(i) << "\n"
<< buffer << "\n";
}
}
// ====get geometry====
if (!manifest["geometry"].isArray()) {
std::cerr << "Malformed shader.json (geometry)";
return false;
}
std::vector<std::string> shaderpaths_geometry;
// --get paths--
for (int i = 0; i < manifest["geometry"].size(); i++) {
shaderpaths_geometry.push_back(manifest["geometry"][i]["path"].asString());
}
std::vector<std::string> shadercode_geometry;
// --read paths--
for (int i = 0; i < shaderpaths_geometry.size(); i++) {
std::ifstream vert(shaderpaths_geometry.at(i));
if (vert.is_open()) {
std::ostringstream ss;
ss << vert.rdbuf();
shadercode_geometry.push_back(ss.str());
} else {
std::cerr << "geometry shader: " << shaderpaths_geometry.at(i)
<< " is missing.\n";
return false;
}
}
// --compile geometry--
for (int i = 0; i < shadercode_geometry.size(); i++) {
this->geometry_shaders.push_back(glCreateShader(GL_GEOMETRY_SHADER));
const char *code = shadercode_geometry.at(i).c_str();
glShaderSource(this->geometry_shaders.back(), 1, &code, NULL);
glCompileShader(this->geometry_shaders.back());
GLint status;
glGetShaderiv(this->geometry_shaders.back(), GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char buffer[512];
glGetShaderInfoLog(this->geometry_shaders.back(), 512, NULL, buffer);
std::cerr << "shader compilation error on shader: "
<< shaderpaths_geometry.at(i) << "\n"
<< buffer << "\n";
}
}
// ====get fragment====
if (!manifest["fragment"].isArray()) {
std::cerr << "Malformed shader.json (fragment)";
return false;
}
std::vector<std::string> shaderpaths_fragment;
// --get paths--
for (int i = 0; i < manifest["fragment"].size(); i++) {
shaderpaths_fragment.push_back(manifest["fragment"][i]["path"].asString());
}
std::vector<std::string> shadercode_fragment;
// --read paths--
for (int i = 0; i < shaderpaths_fragment.size(); i++) {
std::ifstream vert(shaderpaths_fragment.at(i));
if (vert.is_open()) {
std::ostringstream ss;
ss << vert.rdbuf();
shadercode_fragment.push_back(ss.str());
} else {
std::cerr << "fragment shader: " << shaderpaths_fragment.at(i)
<< " is missing.\n";
return false;
}
}
// --compile fragment--
for (int i = 0; i < shadercode_fragment.size(); i++) {
this->fragment_shaders.push_back(glCreateShader(GL_FRAGMENT_SHADER));
const char *code = shadercode_fragment.at(i).c_str();
glShaderSource(this->fragment_shaders.back(), 1, &code, NULL);
glCompileShader(this->fragment_shaders.back());
GLint status;
glGetShaderiv(this->fragment_shaders.back(), GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char buffer[512];
glGetShaderInfoLog(this->fragment_shaders.back(), 512, NULL, buffer);
std::cerr << "shader compilation error on shader: "
<< shaderpaths_fragment.at(i) << "\n"
<< buffer << "\n";
}
}
// linking it all together
if (!manifest["combos"].isArray()) {
std::cerr << "Malformed shader.json (combos)";
}
for (int i = 0; i < manifest["combos"].size(); i++) {
shader shader;
// vertex
if (manifest["combos"][i]["vertex"].isInt()) {
shader.vertexShader =
vertex_shaders.at(manifest["combos"][i]["vertex"].asInt());
} else {
std::cerr << "required argument \"vetex\" is nonexistant or not an int";
return false;
}
// fragment
if (manifest["combos"][i]["fragment"].isInt()) {
shader.fragmentShader =
fragment_shaders.at(manifest["combos"][i]["fragment"].asInt());
} else {
std::cerr
<< "required argument \"fragment\" is nonexistant or not an int\n";
return false;
}
if (manifest["combos"][i]["geometry"].isInt()) {
shader.geometryShader =
geometry_shaders.at(manifest["combos"][i]["geometry"].asInt());
shader.geoshd=true;
}
if (!manifest["fragment"][manifest["combos"][i]["fragment"].asInt()]
["framebuff_output"]
.isArray()) {
std::cerr << "vertex[" << i << "].framebuff_output is not an array.\n";
return false;
}
shader.attatchshader();
for (int j = 0;
j < manifest["fragment"][manifest["combos"][i]["fragment"].asInt()]
["framebuff_output"]
.size();
j++) {
glBindFragDataLocation(
shader.shaderProgram, j,
manifest["fragment"][manifest["combos"][i]["fragment"].asInt()]
["framebuff_output"][j]
.asCString());
}
shader.linkshader();
GLint success;
__glewGetProgramiv(shader.shaderProgram,GL_LINK_STATUS,&success);
std::cout<<"\n"<<i<<" status "<<success<<"\n",
this->shaders.push_back(shader);
}
return true;
}
void rendering::render(camera cam, shader *depthshd, shader *shadowcalc, Gbuffer *gbuf) {
//shadow Pass
for (int i=0; i<lights.size(); i++) {
light *clight=&lights.at(i);
//// DEPTH PASS ////
depthshd->use();
glCullFace(GL_FRONT);
for (int j=0; j<objects.size(); j++) {
objects.at(j).get().renderShadows(*clight, SHADOW_WIDTH, SHADOW_HEIGHT, depthCubemap, depthshd, depthFBO, farClipPlane, cam, (j==0));
}
glCullFace(GL_BACK);
//// SHADOW PASS ////
shadowcalc->use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);
glUniform1i(shadowcalc->getUniformId("depthMap"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gbuf->textus[gbuf->GBUFER_TEXTURE_SHADOW]);
glUniform1i(shadowcalc->getUniformId("GbufPrevShadow"), 1);
glUniform3f(shadowcalc->getUniformId("lights[0].Position"), clight->position.x, clight->position.y, clight->position.z);
glUniform3f(shadowcalc->getUniformId("lights[0].Color"), 1.f,1.f,1.f);
glUniform1f(shadowcalc->getUniformId("far_plane"), farClipPlane);
gbuf->bindW();
gbuf->clearw();
for (int j=0; j<objects.size(); j++) {
objects.at(j).get().renderShadowCalc(cam, shadowcalc);
}
}
glClear(GL_DEPTH_BUFFER_BIT);
glClearDepth(1.0);
// gbuf->bindW();
// gbuf->clear();
for (int i = 0; i < objects.size(); i++) {
objects.at(i).get().rend_shader->use();
objects.at(i).get().render(cam);
}
shaders.at(2).use();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
gbuf->bindR();
// tex 0 position
// tex 1 normals
// tex 2 diffuse (albedo)
// tex 3 texcoord
// tex 4 shadow
setupTextureDS(*gbuf);
glUniform1i(shaders.at(2).getUniformId("gPosition"),0);
glUniform1i(shaders.at(2).getUniformId("gNormal"),1);
glUniform1i(shaders.at(2).getUniformId("gAlbedoSpec"),2);
glUniform1i(shaders.at(2).getUniformId("gShadow"),4);
// for (int i =0; i<lights.size(); i++) {
// }
glUniform3f(shaders.at(2).getUniformId("lights[0].Position"), 0.f,0.f,0.f);
glUniform3f(shaders.at(2).getUniformId("lights[0].Color"), 1.f,1.f,1.f);
renderlighting(shaders.at(2).getInputId("position"),shaders.at(2).getInputId("TexCoord"));
}
void rendering::renderlighting(GLuint pos, GLuint txc) {
// shamelessly stolen from
// https://learnopengl.com/code_viewer_gh.php?code=src/5.advanced_lighting/8.1.deferred_shading/deferred_shading.cpp
// bc i'm lazy
if (quadVAO == 0) {
float quadVertices[] = {
// positions // texture Coords
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
};
// setup plane VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(pos);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
(void *)0);
glEnableVertexAttribArray(txc);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
(void *)(3 * sizeof(float)));
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
}
void rendering::setupTextureDS(Gbuffer gbuf){
for (int i = 0; i<12&&i<gbuf.GBUFER_NUM_TEXTURES; i++) {
glActiveTexture(GL_TEXTURE0+i);
glBindTexture(GL_TEXTURE_2D, gbuf.textus[i]);
}
}
void rendering::cpyDepthBuffer(GLuint buffer){
__glewBindFramebuffer(GL_READ_FRAMEBUFFER, buffer);
__glewBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void rendering::mkDepthBuffer(){
glGenRenderbuffers(1, &rboDepth);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
}
void rendering::mkShadowCubemap(){
glGenFramebuffers(1,&depthFBO);
glGenTextures(1, &depthCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);
for (unsigned int i = 0; i < 6; ++i)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT,
SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
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);
glBindFramebuffer(GL_FRAMEBUFFER, depthFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}