void DeferredRenderer::DrawAmbientLight(const glm::vec3 &color) { //화면 전체를 단색으로 그리기 Device *device = Device::GetInstance(); RenderState &render_state = device->render_state(); Shader &shader = ambient_shader(); render_state.UseShader(shader); mat4 mvp(1.0f); shader.SetUniformMatrix(kMVPHandleName, mvp); vec4 ambient_color(color, 1.0f); shader.SetUniformVector(kAmbientColorHandleName, ambient_color); Texture diffuse_tex = DiffuseTex(); render_state.UseTexture(diffuse_tex, 0); vector<Vertex2D> vert_list; vert_list.push_back(CreateVertex2D(-1, -1, 0, 0)); vert_list.push_back(CreateVertex2D(1, -1, 1, 0)); vert_list.push_back(CreateVertex2D(1, 1, 1, 1)); vert_list.push_back(CreateVertex2D(-1, 1, 0, 1)); shader.DrawArrays(kDrawTriangleFan, vert_list); }
void DeferredRenderer::SetCommonLightQuadDraw(Shader &shader) { Device *dev = Device::GetInstance(); RenderState &render_state = dev->render_state(); const mat4 &projection_mat = render_state.GetProjection3D(); const mat4 &view_mat = render_state.view_mat(); const mat4 &model_mat = render_state.model_mat(); mat4 modelview = view_mat * model_mat; //벡터방향만 잇으면 되니까 이동관련속성은 날리기 for(int i = 0 ; i < 3 ; ++i) { modelview[3][i] = 0; } vec4 viewport(0, 0, render_state.win_width(), render_state.win_height()); float pixels[4][2] = { { 0, 0 }, { viewport[2], 0 }, { viewport[2], viewport[3] }, { 0, viewport[3] }, }; vec3 view_vec_list[4]; for(int i = 0 ; i < 4 ; i++) { vec3 win_coord(pixels[i][0], pixels[i][1], 10); vec3 obj = glm::unProject(win_coord, modelview, projection_mat, viewport); vec3 &view_vec = view_vec_list[i]; view_vec = obj; vec3 cam_pos = MatrixHelper::ViewPos(view_mat); view_vec -= cam_pos; view_vec = glm::normalize(view_vec); mat3 modelview_mat3(modelview); view_vec = modelview_mat3 * view_vec; view_vec.z *= -1; //픽셀에서 cam_pos로 들어오는 방향으로 만들기 위해서 z뒤집음 } //fragment마다 view vector를 계산하기 위해서 계산에 필요한 정보까지 넣기 //4군데만 넣어주면 나머지는 알아서 적절히 보간될것이다 struct LightQuadVertex { LightQuadVertex(float x, float y, float s, float t, const vec3 &view_vec) : pos(x, y), texcoord(s, t), view_vec(view_vec) {} vec2 pos; vec2 texcoord; vec3 view_vec; }; vector<LightQuadVertex> vert_list; vert_list.push_back(LightQuadVertex(-1, -1, 0, 0, view_vec_list[0])); vert_list.push_back(LightQuadVertex(1, -1, 1, 0, view_vec_list[1])); vert_list.push_back(LightQuadVertex(1, 1, 1, 1, view_vec_list[2])); vert_list.push_back(LightQuadVertex(-1, 1, 0, 1, view_vec_list[3])); ShaderVariable pos_var = shader.attrib_var(kPositionHandleName); ShaderVariable texcoord_var = shader.attrib_var(kTexcoordHandleName); ShaderVariable view_vec_var = shader.attrib_var("a_viewVector"); { SR_ASSERT(pos_var.location != kInvalidShaderVarLocation); AttribBindParam param; param.dim = 2; param.normalize = false; param.offset = offsetof(LightQuadVertex, pos); param.var_type = GL_FLOAT; param.vert_size = sizeof(LightQuadVertex); void *ptr = &vert_list[0]; SetAttrib(pos_var, param, (char*)ptr); } { SR_ASSERT(texcoord_var.location != kInvalidShaderVarLocation); AttribBindParam param; param.dim = 2; param.normalize = false; param.offset = offsetof(LightQuadVertex, texcoord); param.var_type = GL_FLOAT; param.vert_size = sizeof(LightQuadVertex); void *ptr = &vert_list[0]; SetAttrib(texcoord_var, param, (char*)ptr); } if(view_vec_var.location != kInvalidShaderVarLocation) { AttribBindParam param; param.dim = 3; param.normalize = true; param.offset = offsetof(LightQuadVertex, view_vec); param.var_type = GL_FLOAT; param.vert_size = sizeof(LightQuadVertex); void *ptr = &vert_list[0]; SetAttrib(view_vec_var, param, (char*)ptr); } shader.DrawArrays(kDrawTriangleFan, vert_list.size()); /* vector<Vertex2D> vert_list; vert_list.push_back(CreateVertex2D(-1, -1, 0, 0)); vert_list.push_back(CreateVertex2D(1, -1, 1, 0)); vert_list.push_back(CreateVertex2D(1, 1, 1, 1)); vert_list.push_back(CreateVertex2D(-1, 1, 0, 1)); shader.DrawArrays(kDrawTriangleFan, vert_list); */ }
void draw_frame(Device *device) { SR_CHECK_ERROR("Begin RenderFrame"); RenderState &render_state = device->render_state(); vec4ub color(77, 77, 77, 255); render_state.ClearBuffer(true, true, false, color); //3d device->render_state().Set3D(); depth_fbo.Bind(); //fbo로 그리기. deferred같은거 구현하기 위해서 임시로 시도함 device->render_state().Set3D(); render_state.ClearBuffer(true, true, false, color); VertexList vert_list; vert_list.push_back(CreateVertex(vec3(-0.5, -0.5, 0), vec2(0, 0))); vert_list.push_back(CreateVertex(vec3(0.5, -0.5, 0), vec2(1, 0))); vert_list.push_back(CreateVertex(vec3(0, 0.5, 0), vec2(0.5, 1))); //vbo, ibo 적절히 만들기 if(vbo.Loaded() == false) { vbo.Init(vert_list); } if(wire_ibo.Loaded() == false) { IndexList index_list; index_list.push_back(0); index_list.push_back(1); index_list.push_back(1); index_list.push_back(2); index_list.push_back(2); index_list.push_back(0); wire_ibo.Init(index_list); } { //shader사용 선언이 가장 먼저 device->render_state().UseShader(color_shader); SR_CHECK_ERROR("UseShader"); mat4 mvp(1.0f); ShaderVariable mvp_var = color_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); vec4 color(1.0f); ShaderVariable const_color_var = color_shader.uniform_var(kConstColorHandleName); SetUniformVector(const_color_var, color); SR_CHECK_ERROR("SetVector"); color_shader.SetVertexList(vert_list); color_shader.DrawArrays(kDrawTriangles, vert_list.size()); color_shader.DrawArrays(kDrawTriangles, vbo); color_shader.DrawElements(kDrawLines, vbo, wire_ibo); } { //shader사용 선언이 가장 먼저 device->render_state().UseShader(simple_shader); TexturePtr tex = device->tex_mgr()->Get("sora"); device->render_state().UseTexture(*tex, 0); SR_CHECK_ERROR("UseShader"); mat4 mvp(1.0f); mvp = glm::rotate(mvp, 10.0f, vec3(0, 0, 1)); ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); SR_CHECK_ERROR("SetMatrix"); simple_shader.SetVertexList(vert_list); simple_shader.DrawArrays(kDrawTriangles, vert_list.size()); } //일반 3d객체 그리기+카메라 회전 장착 { //set camera + projection float win_width = (float)device->render_state().win_width(); float win_height = (float)device->render_state().win_height(); glm::mat4 projection = glm::perspective(45.0f, win_width / win_height, 0.1f, 100.0f); float radius = 4; float cam_x = radius * cos(SR_DEG_2_RAD(aptitude)) * sin(SR_DEG_2_RAD(latitude)); float cam_y = radius * sin(SR_DEG_2_RAD(aptitude)); float cam_z = radius * cos(SR_DEG_2_RAD(aptitude)) * cos(SR_DEG_2_RAD(latitude)); vec3 eye(cam_x, cam_y, cam_z); vec3 center(0); vec3 up(0, 1, 0); glm::mat4 view = glm::lookAt(eye, center, up); glm::mat4 mvp(1.0f); mvp = projection * view; ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); SR_CHECK_ERROR("SetMatrix"); GeometricObject<Vertex> mesh; //mesh.PointTeapot(0.05f); //mesh.WireTeapot(0.05f); //mesh.SolidTeapot(0.05f); //mesh.WireShpere(1, 16, 16); //mesh.PointShpere(1, 16, 16); //mesh.SolidSphere(1, 16, 16); //mesh.SolidCube(1, 1, 1); //mesh.WireCube(1, 1, 1); mesh.PointCube(1, 1, 1); //mesh.PointCylinder(1, 1, 2, 8, 8); //mesh.WireCylinder(1, 1, 2, 8, 8); mesh.SolidCylinder(1, 1, 2, 8, 8); //mesh.WireAxis(5); //mesh.SolidPlane(3); //mesh.WirePlane(3, 0.1f); //mesh.SolidTorus(1, 0.1); //mesh.SolidCone(2, 2); auto it = mesh.Begin(); auto endit = mesh.End(); for( ; it != endit ; ++it) { const DrawCmdData<Vertex> &cmd = *it; //앞면 뒷면 그리기를 허용/불가능 정보까지 내장해야 //뚜껑없는 원통 그리기가 편하다 if(cmd.disable_cull_face == true) { glDisable(GL_CULL_FACE); } simple_shader.SetVertexList(cmd.vertex_list); if(cmd.index_list.empty()) { simple_shader.DrawArrays(cmd.draw_mode, cmd.vertex_list.size()); } else { simple_shader.DrawElements(cmd.draw_mode, cmd.index_list); } if(cmd.disable_cull_face == true) { glEnable(GL_CULL_FACE); } } } depth_fbo.Unbind(); /* //fbo에 있는 내용을 적절히 그리기 { device->render_state().Set2D(); device->render_state().UseShader(simple_shader); ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); mat4 world_mat(1.0f); SetUniformMatrix(mvp_var, world_mat); //device->render_state().UseTexture(depth_fbo.color_tex()); device->render_state().UseTexture(depth_fbo.depth_tex()); Vertex2DList vert_list; vert_list.push_back(CreateVertex2D(-1, -1, 0, 0)); vert_list.push_back(CreateVertex2D(1, -1, 1, 0)); vert_list.push_back(CreateVertex2D(1, 1, 1, 1)); vert_list.push_back(CreateVertex2D(-1, 1, 0, 1)); simple_shader.SetVertexList(vert_list); simple_shader.DrawArrays(kDrawTriangleFan, vert_list.size()); } */ null_post_effect.DrawScissor(depth_fbo.color_tex(), 0, 0, 320, 480); grayscale_post_effect.DrawScissor(depth_fbo.color_tex(), 320, 0, 320, 480); grayscale_post_effect.Draw(depth_fbo.color_tex(), 100, 100, 100, 100); SR_CHECK_ERROR("End RenderFrame"); }