/** Invalidates all meshes so the next time they are rendered new VBO handles are generated. * @param app */ void Mesh::invalidateAllMeshes() { std::list<Mesh*>::iterator current = m_meshes.begin(); while (current != m_meshes.end()) { VertexBufferObject* vbo = dynamic_cast<VertexBufferObject*>((*current)->m_vertices); if(vbo) vbo->invalidate(); (*current)->m_indices->invalidate(); current++; } }
void VertexArrayObject::mount(const VertexBufferObject& inVBO, GLuint inIndex) { inVBO.bind(); glEnableVertexAttribArray(inIndex); glVertexAttribPointer(inIndex, inVBO.mValuesPerUnit, inVBO.mType, GL_FALSE, 0, 0); }
void ReleaseScene(LPVOID lpParam) { // delete shader program object spShader.DeleteShaderProgram(); // delete VBOs and VAOs here VBOScene.ReleaseVBO(); glDeleteVertexArrays(1, &uVAO); //delete shader objects vShader.DeleteShader(); fShader.DeleteShader(); }
void VertexArrayObject::attribute_pointer( AttributeIndex index, VertexBufferObject& vbo, ComponentCount component_count, DataType data_type, bool normalise, size_t stride ) { assert(vbo.target() == BufferTarget::ARRAY_BUFFER); bind(); vbo.bind(); glVertexAttribPointer( index.idx(), get_gl_int(component_count), get_gl_enum(data_type), normalise, stride, nullptr ); }
GLint Program::bindVertexAttribArray( const std::string &name, VertexBufferObject& VBO) const { GLint id = attrib(name); if (id < 0) return id; if (VBO.id == 0) { glDisableVertexAttribArray(id); return id; } VBO.bind(); glEnableVertexAttribArray(id); glVertexAttribPointer(id, VBO.rows, GL_FLOAT, GL_FALSE, 0, 0); check_gl_error(); return id; }
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { // Update the position of the first vertex if the keys 1,2, or 3 are pressed switch (key) { case GLFW_KEY_1: V.col(0) << -0.5, 0.5; break; case GLFW_KEY_2: V.col(0) << 0, 0.5; break; case GLFW_KEY_3: V.col(0) << 0.5, 0.5; break; default: break; } // Upload the change to the GPU VBO.update(V); }
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { // Get the position of the mouse in the window double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); // Get the size of the window int width, height; glfwGetWindowSize(window, &width, &height); // Convert screen position to world coordinates double xworld = ((xpos/double(width))*2)-1; double yworld = (((height-1-ypos)/double(height))*2)-1; // NOTE: y axis is flipped in glfw // Update the position of the first vertex if the left button is pressed if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) V.col(0) << xworld, yworld; // Upload the change to the GPU VBO.update(V); }
Node* RealisticEngine::Scene::CreateCube(float w, float h, float l, GPURenderer* renderer) { GLfloat positionbuffer[] = { // front -w/2,-h/2,l/2, w/2,-h/2,l/2, w/2,h/2,l/2, -w/2,h/2,l/2, // back -w/2,-h/2,-l/2, w/2,-h/2,-l/2, w/2,h/2,-l/2, -w/2,h/2,-l/2, // left -w/2,-h/2,l/2, -w/2,-h/2,-l/2, -w/2,h/2,-l/2, -w/2,h/2,l/2, // right w/2,-h/2,l/2, w/2,-h/2,-l/2, w/2,h/2,-l/2, w/2,h/2,l/2, // top -w/2,h/2,l/2, -w/2,h/2,-l/2, w/2,h/2,-l/2, w/2,h/2,l/2, // bottom -w/2,-h/2,l/2, -w/2,-h/2,-l/2, w/2,-h/2,-l/2, w/2,-h/2,l/2, }; GLfloat normalbuffer[] = { // front 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, // back 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, 0.0,0.0,-1.0, // left -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, -1.0,0.0,0.0, // right 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,0.0, // top 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, // bottom 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, 0.0,-1.0,0.0, }; GLuint indices[] = { // front 0,1,2, 0,2,3, // back 4,5,6, 4,6,7, // left 8,9,10, 8,10,11, // right 12,13,14, 12,14,15, // top 16,17,18, 16,18,19, // bottom 20,21,22, 20,22,23, }; VertexBufferObject* vbo = new VertexBufferObject(); AttributeArrayBuffer* positionbufferobject = new AttributeArrayBuffer(); positionbufferobject->Setup(renderer, "position", positionbuffer, GL_FLOAT, sizeof(GLfloat) * 3, 24, 3); positionbufferobject->Load(); AttributeArrayBuffer* normalbufferobject = new AttributeArrayBuffer(); normalbufferobject->Setup(renderer, "normal", normalbuffer, GL_FLOAT, sizeof(GLfloat) * 3, 24, 3); normalbufferobject->Load(); ElementArrayBuffer* indexbuffer = new ElementArrayBuffer(); indexbuffer->Setup(renderer, indices, 36); indexbuffer->Load(); vbo->AddAtributeArray(positionbufferobject); vbo->AddAtributeArray(normalbufferobject); vbo->SetIndices(indexbuffer); DrawVertexBufferObject* drawvbo = new DrawVertexBufferObject(); drawvbo->SetVBO(vbo); Node* objectNode = new Node(); objectNode->AddDrawInterface(drawvbo); UpdateModelMatrix* updater = new UpdateModelMatrix(); updater->Setup(objectNode, renderer, "modelMat", "normalMat"); objectNode->AddAsset(updater); Geometry geo; for(int i = 0; i < 24; i++) { glm::vec3 pos; pos.x = positionbuffer[i*3 + 0]; pos.y = positionbuffer[i*3 + 1]; pos.z = positionbuffer[i*3 + 2]; geo.mVertices.push_back(pos); } for(int i = 0; i < 72; i++) { geo.mIndices.push_back(indices[i]); } objectNode->SetGeometry(geo); return objectNode; }
Node* RealisticEngine::Scene::CreateSphere(float r, int hsects, int vsects, GPURenderer* renderer) { float thetastep = PI / (hsects+1); float theta = 0; float phistep = 2*PI/vsects; float phi = 0; std::vector<glm::vec3> positions; std::vector<glm::vec3> normals; std::vector<GLushort> indices; glm::vec3 topposition = glm::vec3(0,0,r); glm::vec3 topnormal = glm::normalize(glm::vec3(0,0,r)); positions.push_back(topposition); normals.push_back(topnormal); for(int i = 0; i < hsects; i++) { theta += thetastep; for(int j = 0; j < vsects; j++) { float x = cos(phi) * sin(theta) * r; float y = sin(phi) * sin(theta) * r; float z = cos(theta) * r; glm::vec3 pos = glm::vec3(x,y,z); glm::vec3 norm = glm::normalize(glm::vec3(x,y,z)); positions.push_back(pos); normals.push_back(norm); phi += phistep; } } glm::vec3 bottomposition = glm::vec3(0,0,-r); glm::vec3 bottomnormal = glm::normalize(glm::vec3(0,0,-r)); positions.push_back(bottomposition); normals.push_back(bottomnormal); //add top indices for(int i = 2; i < vsects+1; i++) { indices.push_back(0); indices.push_back(i-1); indices.push_back(i); } indices.push_back(0); indices.push_back(1); indices.push_back(vsects); for(int i = 0; i < hsects-1; i++) { for(int j = 0; j < vsects+1; j++) { indices.push_back(vsects*i+j); indices.push_back(vsects*i+j+1); indices.push_back(vsects*(i+1)+j); } for(int j = 0; j < vsects+1; j++) { indices.push_back(vsects*i+j+1); indices.push_back(vsects*(i+1)+j+1); indices.push_back(vsects*(i+1)+j); } } //add bottom indices for(int i = 1; i < vsects; i++) { indices.push_back(positions.size() - 1); indices.push_back(positions.size() - 1 - i); indices.push_back(positions.size() - 2 - i); } indices.push_back(positions.size() - 1); indices.push_back(positions.size() - 2); indices.push_back(positions.size() - vsects-1); GLfloat* positionbuffer = new GLfloat[positions.size()*3]; GLfloat* normalbuffer = new GLfloat[normals.size()*3]; for(int i = 0; i < positions.size(); i++) { for(int j = 0; j < 3; j++) { positionbuffer[i*3 + j] = positions[i][j]; normalbuffer[i*3 + j] = normals[i][j]; } } std::cout << "positions " << positions.size() << "\n"; std::cout.flush(); VertexBufferObject* vbo = new VertexBufferObject(); AttributeArrayBuffer* positionbufferobject = new AttributeArrayBuffer(); positionbufferobject->Setup(renderer, "position", positionbuffer, GL_FLOAT, sizeof(GLfloat) * 3, positions.size(), 3); positionbufferobject->Load(); AttributeArrayBuffer* normalbufferobject = new AttributeArrayBuffer(); normalbufferobject->Setup(renderer, "normal", normalbuffer, GL_FLOAT, sizeof(GLfloat) * 3, normals.size(), 3); normalbufferobject->Load(); ElementArrayBuffer* indexbuffer = new ElementArrayBuffer(); indexbuffer->Setup(renderer, indices.data(), indices.size()); indexbuffer->Load(); vbo->AddAtributeArray(positionbufferobject); vbo->AddAtributeArray(normalbufferobject); vbo->SetIndices(indexbuffer); DrawVertexBufferObject* drawvbo = new DrawVertexBufferObject(); drawvbo->SetVBO(vbo); Node* objectNode = new Node(); objectNode->AddDrawInterface(drawvbo); UpdateModelMatrix* updater = new UpdateModelMatrix(); updater->Setup(objectNode, renderer, "modelMat", "normalMat"); objectNode->AddAsset(updater); return objectNode; }
void InitScene(LPVOID lpParam) { // clear rendering window glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /////Load assets bind shaders here///// VBOScene.CreateVBO(); glGenVertexArrays(1, &uVAO); // Create one VAO glBindVertexArray(uVAO); VBOScene.BindVBO(); // Add cube to VBO for (int i = 0; i < 36; i++) { VBOScene.AddData(&vCubeVertices[i], sizeof(glm::vec3)); VBOScene.AddData(&vCubeTexCoords[i % 6], sizeof(glm::vec2)); } // Add pyramid to VBO for (int i = 0; i < 12; i++) { VBOScene.AddData(&vPyramidVertices[i], sizeof(glm::vec3)); VBOScene.AddData(&vPyramidTexCoords[i % 3], sizeof(glm::vec2)); } // Add ground to VBO for (int i = 0; i < 6; i++) { VBOScene.AddData(&vGround[i], sizeof(glm::vec3)); vCubeTexCoords[i] *= 5.0f; VBOScene.AddData(&vCubeTexCoords[i % 6], sizeof(glm::vec2)); } VBOScene.LoadDataToGPU(GL_STATIC_DRAW); // Vertex positions start on zero index, and distance between two consecutive is sizeof whole // vertex data (position and tex. coord) glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) + sizeof(glm::vec2), 0); // Texture coordinates start right after positon, thus on (sizeof(glm::vec3)) index, // and distance between two consecutive is sizeof whole vertex data (position and tex. coord) glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) + sizeof(glm::vec2), (void*)sizeof(glm::vec3)); // Load shaders and create shader program vShader.LoadShader("data\\Shaders\\scene.vert", GL_VERTEX_SHADER); fShader.LoadShader("data\\Shaders\\scene.frag", GL_FRAGMENT_SHADER); spShader.CreateShaderProgram(); spShader.AddShaderToProgram(&vShader); spShader.AddShaderToProgram(&fShader); spShader.LinkShader(); spShader.UseShaderProgram(); glEnable(GL_DEPTH_TEST); glClearDepth(1.0); // load texture tGold.LoadTexture2D("data\\Textures\\gold.jpg", true); tGold.SetFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP); tSnow.LoadTexture2D("data\\Textures\\snow.jpg", true); tSnow.SetFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR_MIPMAP); glEnable(GL_TEXTURE_2D); }
namespace posteffect { Shader simple_shader; Shader color_shader; PostEffect null_post_effect; PostEffect grayscale_post_effect; VertexBufferObject vbo; IndexBufferObject wire_ibo; FrameBuffer depth_fbo; void setup_graphics(Device *device, int w, int h) { device->render_state().SetWinSize(w, h); depth_fbo.Init(w, h); LOGI("Version : %s", RendererEnv::Version().c_str()); LOGI("Vendor : %s", RendererEnv::Vender().c_str()); LOGI("Renderer : %s", RendererEnv::Renderer().c_str()); LOGI("Extensions List"); auto ext_list = RendererEnv::ExtensionList(); auto ext_it = ext_list.begin(); auto ext_endit = ext_list.end(); for( ; ext_it != ext_endit ; ++ext_it) { LOGI("%s", ext_it->c_str()); } { //create shader string simple_vs_path = Filesystem::GetAppPath("shader/simple.vs"); string simple_fs_path = Filesystem::GetAppPath("shader/simple.fs"); simple_shader.LoadFromFile(simple_vs_path, simple_fs_path); string color_vs_path = Filesystem::GetAppPath("shader/const_color.vs"); string color_fs_path = Filesystem::GetAppPath("shader/const_color.fs"); color_shader.LoadFromFile(color_vs_path, color_fs_path); } { //post effect string vs_path = Filesystem::GetAppPath("posteffect/shared.vs"); string to_grayscale_fs_path = Filesystem::GetAppPath("posteffect/to_grayscale.fs"); string null_fs_path = Filesystem::GetAppPath("posteffect/null.fs"); grayscale_post_effect.InitFromFile(vs_path, to_grayscale_fs_path); null_post_effect.InitFromFile(vs_path, null_fs_path); } //lodepng const char *texture_table[][2] = { { "sora", "texture/sora.png" }, { "sora2", "texture/sora2.png" }, }; int tex_count = sizeof(texture_table) / sizeof(texture_table[0]); for(int i = 0 ; i < tex_count ; i++) { std::string tex_path = sora::Filesystem::GetAppPath(texture_table[i][1]); sora::MemoryFile tex_file(tex_path); tex_file.Open(); Texture tex(texture_table[i][0]); tex.Init(); Image img; img.LoadPNG(tex_file.start, tex_file.end - tex_file.start); tex.LoadTexture(img); device->tex_mgr()->Add(tex); } } float aptitude = 10; //위도. -90~90. 세로 위치 표현 float latitude = 10; //경도 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"); } void update_frame(sora::Device *def, float dt) { } } //namespace posteffect
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"); }
void VertexArrayObject::mount(const VertexBufferObject& inVBO) { inVBO.bind(); }
int main(void) { GLFWwindow* window; // Initialize the library if (!glfwInit()) return -1; // Activate supersampling glfwWindowHint(GLFW_SAMPLES, 8); // Ensure that we get at least a 3.2 context glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); // On apple we have to load a core profile with forward compatibility #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif // Create a windowed mode window and its OpenGL context window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } // Make the window's context current glfwMakeContextCurrent(window); #ifndef __APPLE__ glewExperimental = true; GLenum err = glewInit(); if(GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } glGetError(); // pull and savely ignonre unhandled errors like GL_INVALID_ENUM fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); #endif int major, minor, rev; major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); printf("OpenGL version recieved: %d.%d.%d\n", major, minor, rev); printf("Supported OpenGL is %s\n", (const char*)glGetString(GL_VERSION)); printf("Supported GLSL is %s\n", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)); // Initialize the VAO // A Vertex Array Object (or VAO) is an object that describes how the vertex // attributes are stored in a Vertex Buffer Object (or VBO). This means that // the VAO is not the actual object storing the vertex data, // but the descriptor of the vertex data. VertexArrayObject VAO; VAO.init(); VAO.bind(); // Initialize the VBO with the vertices data // A VBO is a data container that lives in the GPU memory VBO.init(); V.resize(2,6); V << 0, 0.5, -0.5, 0.1, 0.6, -0.4, 0.5, -0.5, -0.5, 0.6, -0.4, -0.4; VBO.update(V); // Initialize the OpenGL Program // A program controls the OpenGL pipeline and it must contains // at least a vertex shader and a fragment shader to be valid Program program; const GLchar* vertex_shader = "#version 150 core\n" "in vec2 position;" "void main()" "{" " gl_Position = vec4(position, 0.0, 1.0);" "}"; const GLchar* fragment_shader = "#version 150 core\n" "out vec4 outColor;" "uniform vec4 triangleColor;" "void main()" "{" " outColor = vec4(triangleColor);" "}"; // Compile the two shaders and upload the binary to the GPU // Note that we have to explicitly specify that the output "slot" called outColor // is the one that we want in the fragment buffer (and thus on screen) program.init(vertex_shader,fragment_shader,"outColor"); program.bind(); // The vertex shader wants the position of the vertices as an input. // The following line connects the VBO we defined above with the position "slot" // in the vertex shader program.bindVertexAttribArray("position",VBO); // Register the keyboard callback glfwSetKeyCallback(window, key_callback); // Register the mouse callback glfwSetMouseButtonCallback(window, mouse_button_callback); // Update viewport glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // Loop until the user closes the window while (!glfwWindowShouldClose(window)) { // Bind your VAO (not necessary if you have only one) VAO.bind(); // Bind your program program.bind(); // Clear the framebuffer glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enable blending test glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Draw a triangle (red) glUniform4f(program.uniform("triangleColor"), 1.0f, 0.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLES, 0, 3); // Draw a triangle (green) glUniform4f(program.uniform("triangleColor"), 0.0f, 1.0f, 0.0f, 0.5f); glDrawArrays(GL_TRIANGLES, 3, 3); // Swap front and back buffers glfwSwapBuffers(window); // Poll for and process events glfwPollEvents(); } // Deallocate opengl memory program.free(); VAO.free(); VBO.free(); // Deallocate glfw internals glfwTerminate(); return 0; }