bool CRenderTarget::Clear() const { OPENGL_CHECK_FOR_ERRORS(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); OPENGL_CHECK_FOR_ERRORS(); return false; }
bool CRenderTarget::BindColorTexture(axelynx::Texture* tex, int layer) { OPENGL_CHECK_FOR_ERRORS(); // указываем для текущего FBO текстуру, куда следует производить рендер глубины glBindFramebuffer(GL_FRAMEBUFFER, fbo_); if(tex) { CTexture *ctex = dynamic_cast<CTexture*>(tex); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + layer, ctex->GetHandle(), 0); used_layer_[layer] = true; } else { glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + layer, 0, 0); used_layer_[layer] = false; } if(current_) current_->Bind(); else glBindFramebuffer(GL_FRAMEBUFFER, 0); OPENGL_CHECK_FOR_ERRORS(); return true; }
bool CRenderTarget::Bind3DTexture(axelynx::Texture* tex, int texlayer, int rendertargetlayer) { OPENGL_CHECK_FOR_ERRORS(); glBindFramebuffer(GL_FRAMEBUFFER, fbo_); OPENGL_CHECK_FOR_ERRORS(); if(tex) { CTexture *ctex = dynamic_cast<CTexture*>(tex); glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + rendertargetlayer, GL_TEXTURE_3D, ctex->GetHandle(), 0, texlayer); used_layer_[rendertargetlayer] = true; } else { glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + rendertargetlayer, GL_TEXTURE_3D, 0, 0, texlayer); used_layer_[rendertargetlayer] = false; } OPENGL_CHECK_FOR_ERRORS(); if(current_) current_->Bind(); else glBindFramebuffer(GL_FRAMEBUFFER, 0); OPENGL_CHECK_FOR_ERRORS(); return true; }
bool CRenderTarget::UnBind(bool restore) const { OPENGL_CHECK_FOR_ERRORS(); CCanvas::ResizeCanvas(old_width_,old_height_); if(restore) if(restored_) restored_->Bind(); if(current_) glBindFramebuffer(GL_FRAMEBUFFER, 0); current_ = 0; OPENGL_CHECK_FOR_ERRORS(); return true; }
vec2 Terrain::LoadVertices( const QuadTree<TerrainNode>::Iterator& node, const Image& hmap ) { //Setup vertex data vec2 res = vec2(1.0f, 0.0f); int verticesCount = (lodResolution + 1) * (lodResolution + 1); vector<vec3> vertices(verticesCount), colors(verticesCount); float deltaX = 1.0f / node.LayerSize() / lodResolution; float deltaY = 1.0f / node.LayerSize() / lodResolution; float x = node.OffsetFloat().x; for (int i = 0; i <= lodResolution; i++, x += deltaX) { float y = node.OffsetFloat().y; for (int j = 0; j <= lodResolution; j++, y += deltaY) { float h = hmap[vec2(x, y)].x; res = UniteSegments(res, vec2(h)); vertices[i*lodResolution + i + j] = vec3(x, h, y); colors[i*lodResolution + i + j] = vec3(0.2f, 0.2f + h, 0.4f - h); } } // VAO allocation glGenVertexArrays(1, &node->vaoID); // VAO setup glBindVertexArray(node->vaoID); // VBOs allocation glGenBuffers(2, node->vboID); // VBOs setup // vertices buffer glBindBuffer(GL_ARRAY_BUFFER, node->vboID[0]); glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); glEnableVertexAttribArray(0); // colors buffer glBindBuffer(GL_ARRAY_BUFFER, node->vboID[1]); glBufferData(GL_ARRAY_BUFFER, colors.size() * 3 * sizeof(GLfloat), colors.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); glEnableVertexAttribArray(1); // indices buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GetIndicesBufferID()); OPENGL_CHECK_FOR_ERRORS(); // release vertex data vertices.clear(); colors.clear(); if (node.Level() < maxLOD) { for (int i : {0, 1, 2, 3}) res = UniteSegments(res, LoadVertices(node.Add(i), hmap)); } node->heights = res; return res; }
void Mesh::Create(){ glGenBuffers(1,&this->VertexBuffer); glBindBuffer(GL_ARRAY_BUFFER,this->VertexBuffer); glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(math::Vector3), &vertices[0], GL_STATIC_DRAW); OPENGL_CHECK_FOR_ERRORS(); }
axelynx::Texture* CRenderTarget::CreateDepthTexture() { OPENGL_CHECK_FOR_ERRORS(); axelynx::Texture::Desc desc; desc.TT = axelynx::Texture::TT_DEPTH; desc.width = width_; desc.height = height_; desc.cpp = 1; desc.bpc = 4; desc.use_mipmaps = false; CTexture *tex = new CTexture(desc); //tex->Bind(); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); //tex->UnBind(); tex->Build(0,GL_DEPTH_COMPONENT,GL_DEPTH_COMPONENT32F); OPENGL_CHECK_FOR_ERRORS(); BindDepthTexture(tex); OPENGL_CHECK_FOR_ERRORS(); return tex; }
axelynx::Texture* CRenderTarget::CreateColorTexture(int channels, int channel_size, int layer,bool use_mipmaps) { OPENGL_CHECK_FOR_ERRORS(); axelynx::Texture::Desc desc; desc.TT = axelynx::Texture::TT_2D; desc.width = width_; desc.height = height_; desc.cpp = channels; desc.bpc = channel_size; desc.use_mipmaps = use_mipmaps; CTexture *tex = new CTexture(desc); GLenum format; GLenum internalformat; GetGLTextures(format,internalformat,channels,channel_size); tex->Build(0,format,internalformat); OPENGL_CHECK_FOR_ERRORS(); BindColorTexture(tex,layer); OPENGL_CHECK_FOR_ERRORS(); return tex; }
bool CRenderTarget::Bind() const { OPENGL_CHECK_FOR_ERRORS(); old_width_ = CCanvas::Instance()->GetWidth(); old_height_ = CCanvas::Instance()->GetHeight(); CCanvas::ResizeCanvas(width_,height_); // проверим текущий FBO на корректность GLenum fboStatus; // создаем FBO для рендера глубины в текстуру if ((fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { LOG_ERROR(L"glCheckFramebufferStatus error"); } // возвращаем FBO по-умолчанию glBindFramebuffer(GL_FRAMEBUFFER, 0); if(current_ != this) { restored_ = current_; glBindFramebuffer(GL_FRAMEBUFFER, fbo_); } unsigned int buffers[16]; int c=0; for(int i=0;i<16;++i) { if(used_layer_[i]) { buffers[c] = GL_COLOR_ATTACHMENT0 + i; c++; } } glDrawBuffers(c,buffers); current_ = this; OPENGL_CHECK_FOR_ERRORS(); return true; }
bool Shader::loadFromFile(const char* fileName, GLuint type) { GET_CONTEXT(); GLuint program; std::string shaderName; if ((program = glCreateProgram()) == 0){ LOG_ERROR(boost::str(boost::format("Creating shader program fail (%d)\n") % glGetError())); return false; } // если необходимо создать вершинный шейдер if (type & Vertex){ // им¤ вершинного шейдера shaderName = boost::str(boost::format("%s.vs") % fileName); if (!loadShader(shaderName, GL_VERTEX_SHADER, program)){ glDeleteProgram(program); return false; } } // если необходимо создать фрагментный шейдер if (type & Fragment) { shaderName = boost::str(boost::format("%s.fs") % fileName); if (!loadShader(shaderName, GL_FRAGMENT_SHADER, program)){ glDeleteProgram(program); return false; } } if (type & Geometry) { shaderName = boost::str(boost::format("%s.gs") % fileName); if (!loadShader(shaderName, GL_GEOMETRY_SHADER, program)){ glDeleteProgram(program); return false; } } OPENGL_CHECK_FOR_ERRORS(); m_program = program; return true; }
void UMesh::Initialize() { ComputeBoundSphere(); InitializeBuffers(); auto renderer = URenderer::GetInstance(); renderer->BindVBO(&vb); renderer->BindVBO(&ib); InitializeMaterial(URenderPass::Normal); InitializeMaterial(URenderPass::Depth); InitializeMaterial(URenderPass::Forward); InitializeMaterial(URenderPass::Deffered); OPENGL_CHECK_FOR_ERRORS(); }
GLint Shader::shaderProgramStatus(GLuint program, GLenum param) { GET_CONTEXT(); GLint status = 0, length = 0; GLchar buffer[1024]; glGetProgramiv(program, param, &status); if (status != GL_TRUE) { glGetProgramInfoLog(program, 1024, &length, buffer); buffer[length] = '\0'; LOG_ERROR(boost::str(boost::format("Shader: %s\n") % (const char*)buffer)); } OPENGL_CHECK_FOR_ERRORS(); return status; }
GLint Shader::getShaderStatus(GLuint shader, GLenum param) { GET_CONTEXT(); GLint status = 0, length = 0; GLchar buffer[4096 * 4]; glGetShaderiv(shader, param, &status); if (status != GL_TRUE) { glGetShaderInfoLog(shader, 4096 * 4, &length, buffer); buffer[length] = '\0'; LOG_ERROR(boost::str(boost::format("Shader: %s\n") % (const char*)buffer)); } OPENGL_CHECK_FOR_ERRORS(); return status; }
void GLContext::initContext(){ if(!_glfwInit()){ LOG_ERROR("Failed to setup GLFW\n" ); } if(!_glInit()){ LOG_ERROR("Failed to initialize OpenGL\n" ); } core::World::I().cam.setPerspective( GLContext::I().SceneParam.FOV, GLContext::I().SceneParam.AspectRatio, GLContext::I().SceneParam.zNear, GLContext::I().SceneParam.zFar); //TODO: Remove it to coll source load procedure Program = RenderProgram("Lesson"); Program.createShader(GL_VERTEX_SHADER ,"data/lesson.vs"); Program.createShader(GL_FRAGMENT_SHADER ,"data/lesson.fs"); Program.compile(); OPENGL_CHECK_FOR_ERRORS(); }
// инициализаця OpenGL bool GLWindowInit(const GLWindow *window) { ASSERT(window); // устанавливаем вьюпорт на все окно glViewport(0, 0, window->width, window->height); // параметры OpenGL glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); // создадим и загрузим шейдерную программу if ((shaderProgram = ShaderProgramCreateFromMemory(vertexShader, fragmentShader)) == 0) return false; // собираем созданную и загруженную шейдерную программу if (!ShaderProgramLink(shaderProgram)) return false; // сделаем шейдерную программу активной ShaderProgramBind(shaderProgram); // проверка шейдерной программы на корректность if (!ShaderProgramValidate(shaderProgram)) return false; // создадим примитив для сферы MeshCreateSphere(mesh, vec3(0.0f, 0.0f, 0.0f), 1.0f); // создадим и настроим камеру CameraCreate(mainCamera, -1.0f, -1.0f, -1.0f); CameraOrthographic(mainCamera, -0.5f, 0.5f, -0.5f, 0.5f, -10.0f, 10.0f); CameraRotate(mainCamera, (float)(-math_degrees * asin((double)1/sqrt(3.0))), 135.0f, 0.0f); // проверим не было ли ошибок OPENGL_CHECK_FOR_ERRORS(); return true; }
bool CScene::ZPassRender() { std::list<axelynx::Camera *>::const_iterator ci = camlist.begin(); std::list<axelynx::Camera *>::const_iterator ei = camlist.end(); CEarlyZ::StartEarlyZPass(); for(;ci!=ei;++ci) { if((*ci)->isEnabled()) { frame_++; (*ci)->Bind(); CMaterial::Free(); //материал зависит от камеры OPENGL_CHECK_FOR_ERRORS(); for(int i=0;i<256;++i) { if(visible_groups_[i]) scenegraph_[i]->Render(*ci); } (*ci)->UnBind(); CMaterial::Free(); //материал зависит от камеры } } CShader *cs = CShader::Current(); if(cs) cs->UnBind(); for(int i=0;i<16;++i) { CTexture *ct = CTexture::Current(i); if(ct) ct->UnBind(); } CEarlyZ::EndEarlyZPass(); zpassed = true; return true; }
bool CScene::Render() { std::list<axelynx::Camera *>::const_iterator ci = camlist.begin(); std::list<axelynx::Camera *>::const_iterator ei = camlist.end(); OPENGL_CHECK_FOR_ERRORS(); for(;ci!=ei;++ci) { if((*ci)->isEnabled()) { frame_++; (*ci)->Bind(zpassed?-1:0); OPENGL_CHECK_FOR_ERRORS(); CMaterial::Free(); //материал зависит от камеры OPENGL_CHECK_FOR_ERRORS(); if(zpassed) { CEarlyZ::StartRenderPass(); } else { glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); } OPENGL_CHECK_FOR_ERRORS(); for(int i=0;i<256;++i) { if(visible_groups_[i]) scenegraph_[i]->Render(*ci); } (*ci)->UnBind(); CMaterial::Free(); //материал зависит от камеры } } OPENGL_CHECK_FOR_ERRORS(); CShader *cs = CShader::Current(); if(cs) cs->UnBind(); for(int i=0;i<16;++i) { CTexture *ct = CTexture::Current(i); if(ct) ct->UnBind(); } OPENGL_CHECK_FOR_ERRORS(); if(zpassed) CEarlyZ::EndRenderPass(); OPENGL_CHECK_FOR_ERRORS(); zpassed = false; glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glDepthMask(GL_TRUE); OPENGL_CHECK_FOR_ERRORS(); return true; }
void Terrain::GenerateIndices() { const int VBOSize = lodResolution * lodResolution * 6 * 16; vector<GLuint> indices(VBOSize); vector<GLuint>::iterator ptr; int i, u, v, count; for(i = 0; i < 16; i++) { ptr = indices.begin() + lodResolution * lodResolution * 6 * i; count = 0; // //UPPER SIDE // if(i & TERRAIN_GRID_SPARSE_UPPER) { v = 0; ptr[count++] = v; ptr[count++] = v + lodResolution + 2; ptr[count++] = v + 2; ptr[count++] = v + 2; ptr[count++] = v + lodResolution + 2; ptr[count++] = v + lodResolution + 3; for (v = 2; v < lodResolution-2 ; v+=2) { ptr[count++] = v; ptr[count++] = v + lodResolution + 1; ptr[count++] = v + lodResolution + 2; ptr[count++] = v; ptr[count++] = v + lodResolution + 2; ptr[count++] = v + 2; ptr[count++] = v + 2; ptr[count++] = v + lodResolution + 2; ptr[count++] = v + lodResolution + 3; } ptr[count++] = v; ptr[count++] = v + lodResolution + 1; ptr[count++] = v + lodResolution + 2; ptr[count++] = v; ptr[count++] = v + lodResolution + 2; ptr[count++] = v + 2; } else { v = 0; ptr[count++] = v; ptr[count++] = v + 2 + lodResolution; ptr[count++] = v + 1; for (v = 1; v < lodResolution-1 ; v++) { ptr[count++] = v; ptr[count++] = v + 2 + lodResolution; ptr[count++] = v + 1; ptr[count++] = v; ptr[count++] = v + lodResolution + 1; ptr[count++] = v + lodResolution + 2; } ptr[count++] = v; ptr[count++] = v + 1 + lodResolution; ptr[count++] = v + 1; } // //RIGHT SIDE // if(i & TERRAIN_GRID_SPARSE_RIGHT) { u = 0; unsigned int aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux + lodResolution; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + lodResolution; ptr[count++] = aux + 2*lodResolution + 1; ptr[count++] = aux + 2*lodResolution + 2; for (u = 2; u < lodResolution-2 ; u+=2) { aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux - 1; ptr[count++] = aux + lodResolution; ptr[count++] = aux; ptr[count++] = aux + lodResolution; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + lodResolution; ptr[count++] = aux + 2*lodResolution + 1; ptr[count++] = aux + 2*lodResolution + 2; } aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux - 1; ptr[count++] = aux + lodResolution; ptr[count++] = aux; ptr[count++] = aux + lodResolution; ptr[count++] = aux + 2*lodResolution + 2; } else { u = 0; unsigned int aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux + lodResolution; ptr[count++] = aux + lodResolution + 1; for (u = 1; u < lodResolution-1 ; u++) { aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux - 1; ptr[count++] = aux + lodResolution; ptr[count++] = aux; ptr[count++] = aux + lodResolution; ptr[count++] = aux + lodResolution + 1; } aux = u*(lodResolution+1) + lodResolution; ptr[count++] = aux; ptr[count++] = aux - 1; ptr[count++] = aux + lodResolution + 1; } // //LOWER SIDE // if(i & TERRAIN_GRID_SPARSE_LOWER) { v = 0; unsigned int aux = (lodResolution-1)*(lodResolution+1) + v; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 3; ptr[count++] = aux + 2; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 3; for (v = 2; v < lodResolution-2 ; v+=2) { aux = (lodResolution-1)*(lodResolution+1) + v; ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 3; ptr[count++] = aux + 2; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 3; } aux = (lodResolution-1)*(lodResolution+1) + v; ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 3; } else { v = 0; unsigned int aux = (lodResolution-1)*(lodResolution+1) + v; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; for (v = 1; v < lodResolution-1 ; v++) { aux = (lodResolution-1)*(lodResolution+1) + v; ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + 1; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; } aux = (lodResolution - 1)*(lodResolution + 1) + v; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; } // //LEFT SIDE // if(i & TERRAIN_GRID_SPARSE_LEFT) { u = 0; unsigned int aux = u*(lodResolution+1); ptr[count++] = aux; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + 2*lodResolution + 3; for (u = 2; u < lodResolution-2 ; u+=2) { aux = u*(lodResolution+1); ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + 2*lodResolution + 3; } aux = u*(lodResolution+1); ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux; ptr[count++] = aux + 2*lodResolution + 2; ptr[count++] = aux + lodResolution + 2; } else { u = 0; unsigned int aux = u*(lodResolution+1); ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; for (u = 1; u < lodResolution-1 ; u++) { aux = u*(lodResolution+1); ptr[count++] = aux; ptr[count++] = aux + lodResolution + 2; ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; } aux = u*(lodResolution+1); ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + 1; } // //CENTRAL PART // for (u = 1; u < lodResolution-1; u++) { for (v = 1; v < lodResolution-1 ; v++) { const unsigned int aux = u*(lodResolution+1) + v; ptr[count++] = aux; ptr[count++] = aux + 2 + lodResolution; ptr[count++] = aux + 1; ptr[count++] = aux; ptr[count++] = aux + lodResolution + 1; ptr[count++] = aux + lodResolution + 2; } } indicesBufferSize[i] = count; } glGenBuffers(1, &indicesBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBufferID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, VBOSize * sizeof(uint32), indices.data(), GL_STATIC_DRAW); OPENGL_CHECK_FOR_ERRORS(); }