nenuzhno-engine_iter1/demos/SSR/ssr.cpp

253 lines
5.8 KiB
C++

#include <gtc/type_ptr.hpp>
#include "log.h"
#include "graphics/platform_gl.h"
#include "graphics/gl_utils.h"
#include "graphics/glsl_prog.h"
#include "graphics/ArrayBuffer.h"
#include "graphics/vao.h"
#include "renderer/mesh.h"
#include "graphics/texture.h"
#include "graphics/fbo.h"
#include "renderer/camera.h"
#include "game/IGame.h"
class SSRGame : public IGame{
public:
void Created();
void Changed(int w, int h);
void Draw();
const char *GetGamedir(){
return "ssr";
}
};
IGame *CreateGame(){
return new SSRGame();
}
GLfloat vertices[] =
{
0.5f, 0.0f, 0.5f, 0,1,0, 1,1,
0.5f, 0.0f, -0.5f, 0,1,0, 1,0,
-0.5f, 0.0f, -0.5f, 0,1,0, 0,0,
-0.5f, 0.0f, 0.5f, 0,1,0, 0,1
};
int scrWidth = 0;
int scrHeight = 0;
glslProg simpleProg;
glslProg texProg;
glslProg ssrProg;
int u_eyePos=-1;
Mesh *plane;
Mesh *cube;
VertexBufferObject *vboQuad;
VertexArrayObject vaoQuad;
VertexArrayObject vaoSO;
FrameBufferObject fbo1;
FrameBufferObject fboBack;
Texture testTex;
Camera camera;
glm::mat4 mvpMtx(1);
void UnbindFBO()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, scrWidth, scrHeight);
}
class SceneObject
{
public:
Mesh *mesh;
glm::mat4 modelMtx;
SceneObject(){}
SceneObject(Mesh *msh, glm::mat4 mtx)
{
mesh = msh;
modelMtx = mtx;
}
void Draw(GLint u_mvpMtx)
{
mvpMtx = camera.projMtx * camera.viewMtx * modelMtx;
glUniformMatrix4fv(u_mvpMtx,1,GL_FALSE,glm::value_ptr(mvpMtx));
mesh->Bind();
mesh->Draw();
mesh->Unbind();
}
};
SceneObject planeSO;
SceneObject cubeSO;
void SSRGame::Created()
{
simpleProg.CreateFromFile("simple", "simple");
simpleProg.u_mvpMtx = simpleProg.GetUniformLoc("u_mvpMtx");
if(texProg.CreateFromFile("generic", "col_tex"))
{
texProg.u_mvpMtx = texProg.GetUniformLoc("u_mvpMtx");
texProg.u_color = texProg.GetUniformLoc("u_color");
texProg.Use();
glUniform4f(texProg.u_color, 1,1,1,1);
}
ssrProg.CreateFromFile("ssr", "ssr");
ssrProg.u_mvpMtx = ssrProg.GetUniformLoc("u_mvpMtx");
ssrProg.u_invModelMtx = ssrProg.GetUniformLoc("u_invMVPMtx");
u_eyePos = ssrProg.GetUniformLoc("u_eyePos");
GLint u_depthTex = ssrProg.GetUniformLoc("u_depthTex");
ssrProg.Use();
glUniform1i(u_depthTex, 1);
glUseProgram(0);
CheckGLError("Created shaders", __FILE__, __LINE__);
plane = new MeshFBO_N3_T2(vertices, 4, GL_TRIANGLE_FAN);
cube = LoadMeshFile("cube", true);
vaoSO.Create();
float quadVerts[] ={
1,-1,1,0,
1, 1,1,1,
-1, 1,0,1,
-1,-1,0,0
};
vboQuad = new VertexBufferObject();
vboQuad->Create();
vboQuad->Upload(4*4*4, quadVerts);
vaoQuad.Create();
vaoQuad.Bind();
vboQuad->Bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,16,0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,16,(void*)8);
vboQuad->Unbind();
vaoQuad.Unbind();
CheckGLError("Created meshes", __FILE__, __LINE__);
testTex.Create(4,4);
GLubyte testTexData[] =
{
0,0,0, 255,255,255, 0,0,0, 255,255,255,
255,255,255, 0,0,0, 255,255,255, 0,0,0,
0,0,0, 255,255,255, 0,0,0, 255,255,255,
255,255,255, 0,0,0, 255,255,255, 0,0,0
};
testTex.Upload(0, GL_RGB, testTexData);
planeSO = SceneObject(plane,glm::mat4(1.0));
cubeSO = SceneObject(cube,glm::scale(glm::translate(glm::mat4(1.0),glm::vec3(0,0.1,0)),glm::vec3(0.2)));
camera.pos = glm::vec3(0,0.6f,1);
camera.rot = glm::vec3(30,0,0);
camera.UpdateView();
fbo1.Create();
fbo1.CreateTexture(64, 64, GL_LINEAR);
fbo1.CreateDepthTexture();
fboBack.Create();
fboBack.CreateTexture(256,256);
CheckGLError("Created fbo", __FILE__, __LINE__);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_CULL_FACE);
CheckGLError("Created", __FILE__, __LINE__);
}
void SSRGame::Changed(int w, int h)
{
scrWidth = w;
scrHeight = h;
glViewport(0, 0, w, h);
float aspect = w/(float)h;
camera.UpdateProj(75.0f, aspect, 0.1f, 2.0f);
fbo1.Resize(w,h);
CheckGLError("Changed", __FILE__, __LINE__);
}
float a = 0;
void SSRGame::Draw()
{
a+=0.02;
camera.pos = glm::vec3(glm::sin(a),0.6f,glm::cos(a));
camera.rot = glm::vec3(30,glm::degrees(a),0);
camera.UpdateView();
fbo1.Bind();
CheckGLError("Bind fbo", __FILE__, __LINE__);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
CheckGLError("Clear", __FILE__, __LINE__);
vaoSO.Bind();
glEnableVertexAttribArray(0);
glEnable(GL_DEPTH_TEST);
glEnableVertexAttribArray(2);
texProg.Use();
testTex.Bind();
cubeSO.Draw(texProg.u_mvpMtx);
glDisableVertexAttribArray(2);
CheckGLError("Draw cube", __FILE__, __LINE__);
simpleProg.Use();
planeSO.Draw(simpleProg.u_mvpMtx);
CheckGLError("Draw plane", __FILE__, __LINE__);
vaoSO.Unbind();
#if 1
glDisable(GL_DEPTH_TEST);
//UnbindFBO();
fboBack.Bind();
glClear(GL_COLOR_BUFFER_BIT);
texProg.Use();
glUniformMatrix4fv(texProg.u_mvpMtx,1,GL_FALSE,glm::value_ptr(glm::mat4(1.0f)));
fbo1.BindTexture();
vaoQuad.Bind();
glDrawArrays(GL_TRIANGLE_FAN,0,4);
vaoQuad.Unbind();
ssrProg.Use();
glm::mat4 invMVPMtx = glm::inverse(camera.projMtx * camera.viewMtx);
glUniformMatrix4fv(ssrProg.u_invModelMtx,1,GL_FALSE,glm::value_ptr(invMVPMtx));
glUniform3fv(u_eyePos,1,&camera.pos.x);
glActiveTexture(GL_TEXTURE1);
fbo1.BindDepthTexture();
glActiveTexture(GL_TEXTURE0);
fbo1.BindTexture();
vaoSO.Bind();
glEnableVertexAttribArray(1);
planeSO.Draw(ssrProg.u_mvpMtx);
glDisableVertexAttribArray(1);
UnbindFBO();
glClear(GL_COLOR_BUFFER_BIT);
texProg.Use();
glUniformMatrix4fv(texProg.u_mvpMtx,1,GL_FALSE,glm::value_ptr(glm::mat4(1.0f)));
fboBack.BindTexture();
vboQuad->Bind();
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,16,0);
glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,16,(void*)8);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glDisableVertexAttribArray(2);
vboQuad->Unbind();
glBindTexture(GL_TEXTURE_2D, 0);
glDisableVertexAttribArray(0);
vaoSO.Unbind();
#endif
CheckGLError("Draw", __FILE__, __LINE__);
}