angle::Result ContextGL::drawRangeElements(const gl::Context *context, gl::PrimitiveMode mode, GLuint start, GLuint end, GLsizei count, gl::DrawElementsType type, const void *indices) { const gl::Program *program = context->getState().getProgram(); const bool usesMultiview = program->usesMultiview(); const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0; const void *drawIndexPointer = nullptr; ANGLE_TRY( setDrawElementsState(context, count, type, indices, instanceCount, &drawIndexPointer)); if (!usesMultiview) { getFunctions()->drawRangeElements(ToGLenum(mode), start, end, count, ToGLenum(type), drawIndexPointer); } else { getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, instanceCount); } return angle::Result::Continue; }
angle::Result ContextGL::drawElementsIndirect(const gl::Context *context, gl::PrimitiveMode mode, gl::DrawElementsType type, const void *indirect) { getFunctions()->drawElementsIndirect(ToGLenum(mode), ToGLenum(type), indirect); return angle::Result::Continue; }
ShaderImpl *ContextGL::createShader(const gl::ShaderState &data) { const FunctionsGL *functions = getFunctions(); GLuint shader = functions->createShader(ToGLenum(data.getShaderType())); return new ShaderGL(data, shader, mRenderer->getMultiviewImplementationType(), mRenderer); }
angle::Result ContextGL::drawArraysIndirect(const gl::Context *context, gl::PrimitiveMode mode, const void *indirect) { getFunctions()->drawArraysIndirect(ToGLenum(mode), indirect); return angle::Result::Continue; }
bool RenderTarget::UpdateSize(void) { unsigned int maxW = GetMaxAttachmentWidth(), maxH = GetMaxAttachmentHeight(); width = maxW; height = maxH; if (colorTexes.size() == 0) { width = (depthTex.MTex != 0 ? depthTex.MTex->GetWidth() : depthTex.MTexCube->GetWidth()); height = (depthTex.MTex != 0 ? depthTex.MTex->GetHeight() : depthTex.MTexCube->GetHeight()); } for (unsigned int i = 0; i < colorTexes.size(); ++i) { //Figure out the attachment's width/height. unsigned int tempWidth, tempHeight; if (colorTexes[i].MTex != 0) { tempWidth = colorTexes[i].MTex->GetWidth(); tempHeight = colorTexes[i].MTex->GetHeight(); } else { tempWidth = colorTexes[i].MTexCube->GetWidth(); tempHeight = colorTexes[i].MTexCube->GetHeight(); } //Make sure the size is valid. if (tempWidth > maxW || tempHeight > maxH) { return false; } //Update the size of this frame buffer. width = Mathf::Min(width, tempWidth); height = Mathf::Min(height, tempHeight); } //Update the depth buffer. if (depthTex.MTex != 0) { depthTex.MTex->ClearData(width, height); } else if (depthTex.MTexCube != 0) { depthTex.MTexCube->ClearData(width, height); } else { glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, ToGLenum(depthRenderBufferSize), width, height); } return true; }
angle::Result ContextGL::drawArrays(const gl::Context *context, gl::PrimitiveMode mode, GLint first, GLsizei count) { const gl::Program *program = context->getState().getProgram(); const bool usesMultiview = program->usesMultiview(); const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0; ANGLE_TRY(setDrawArraysState(context, first, count, instanceCount)); if (!usesMultiview) { getFunctions()->drawArrays(ToGLenum(mode), first, count); } else { getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count, instanceCount); } return angle::Result::Continue; }
angle::Result ContextGL::drawElementsInstanced(const gl::Context *context, gl::PrimitiveMode mode, GLsizei count, gl::DrawElementsType type, const void *indices, GLsizei instances) { GLsizei adjustedInstanceCount = instances; const gl::Program *program = context->getState().getProgram(); if (program->usesMultiview()) { adjustedInstanceCount *= program->getNumViews(); } const void *drawIndexPointer = nullptr; ANGLE_TRY(setDrawElementsState(context, count, type, indices, adjustedInstanceCount, &drawIndexPointer)); getFunctions()->drawElementsInstanced(ToGLenum(mode), count, ToGLenum(type), drawIndexPointer, adjustedInstanceCount); return angle::Result::Continue; }
bool RenderTarget::SetDepthAttachment(RenderTargetTex newDepthTex, bool changeSize) { depthTex = newDepthTex; if (width == 0 && height == 0) { width = (depthTex.MTex != 0 ? depthTex.MTex->GetWidth() : (depthTex.MTexCube != 0 ? depthTex.MTexCube->GetWidth() : 0)); height = (depthTex.MTex != 0 ? depthTex.MTex->GetHeight() : (depthTex.MTexCube != 0 ? depthTex.MTexCube->GetHeight() : 0)); } if (depthTex.MTex != 0) { if (changeSize) { depthTex.MTex->ClearData(width, height); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex.MTex->GetTextureHandle(), 0); } else if (depthTex.MTexCube != 0) { if (changeSize) { depthTex.MTexCube->ClearData(width, height); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, TextureTypeToGLEnum(depthTex.MTexCube_Face), depthTex.MTexCube->GetTextureHandle(), 0); } else { if (changeSize) { glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, ToGLenum(depthRenderBufferSize), width, height); } } return true; }
angle::Result ContextGL::drawArraysInstanced(const gl::Context *context, gl::PrimitiveMode mode, GLint first, GLsizei count, GLsizei instanceCount) { GLsizei adjustedInstanceCount = instanceCount; const gl::Program *program = context->getState().getProgram(); if (program->usesMultiview()) { adjustedInstanceCount *= program->getNumViews(); } ANGLE_TRY(setDrawArraysState(context, first, count, adjustedInstanceCount)); getFunctions()->drawArraysInstanced(ToGLenum(mode), first, count, adjustedInstanceCount); return angle::Result::Continue; }
angle::Result ImageEGL::setTexture2D(const gl::Context *context, gl::TextureType type, TextureGL *texture, GLenum *outInternalFormat) { const FunctionsGL *functionsGL = GetFunctionsGL(context); StateManagerGL *stateManager = GetStateManagerGL(context); // Make sure this texture is bound stateManager->bindTexture(type, texture->getTextureID()); // Bind the image to the texture functionsGL->eGLImageTargetTexture2DOES(ToGLenum(type), mImage); *outInternalFormat = mNativeInternalFormat; return angle::Result::Continue; }
RenderTarget::RenderTarget(PixelSizes rendBuffSize, std::string& outError) : depthTex(0), width(0), height(0), depthRenderBufferSize(rendBuffSize) { if (maxColorAttachments == 0) { maxColorAttachments = GetMaxNumbColorAttachments(); } ClearAllRenderingErrors(); //Create frame buffer object. glGenFramebuffers(1, &frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); //Create the depth renderbuffer to fall back on if not using a depth texture. glGenRenderbuffers(1, &depthRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); if (!IsPixelSizeDepth(rendBuffSize)) { outError = "Render buffer size specified in constructor is not a depth size type! " + std::string("It is ") + DebugAssist::ToString(rendBuffSize); return; } glRenderbufferStorage(GL_RENDERBUFFER, ToGLenum(rendBuffSize), 1, 1); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer); //Save the currently-bound framebuffer before binding this one to check it out. GLint currentBuffer; glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tBuffer); //Check framebuffer status. glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); std::string err = GetFramebufferStatusMessage(); if (!err.empty()) { outError = "Framebuffer is not ready! " + err; } //Re-bind the previously-bound framebuffer. glBindFramebuffer(GL_FRAMEBUFFER, currentBuffer); }
bool RenderTarget::SetColorAttachments(RenderTargetTex* newColTexes, unsigned int nTexes, bool updateDepthSize) { EnableDrawingInto(); //Make sure there aren't too many attachments. if (nTexes > GetMaxNumbColorAttachments()) { return false; } unsigned int newWidth = GetMaxAttachmentWidth(), newHeight = GetMaxAttachmentHeight(); //Set up each attachment. std::vector<GLenum> colAttachments; colAttachments.reserve(nTexes); for (unsigned int i = 0; i < maxColorAttachments; ++i) { if (i >= nTexes) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); } else { colAttachments.insert(colAttachments.end(), GL_COLOR_ATTACHMENT0 + i); const RenderTargetTex& tex = newColTexes[i]; if ((tex.MTex == 0 && tex.MTexCube == 0) || (tex.MTex != 0 && tex.MTexCube != 0)) { return false; } //Get texture information. RenderObjHandle texHandle; GLenum textureType; unsigned int colWidth; unsigned int colHeight; if (tex.MTex != 0) { texHandle = tex.MTex->GetTextureHandle(); textureType = GL_TEXTURE_2D; colWidth = tex.MTex->GetWidth(); colHeight = tex.MTex->GetHeight(); //TODO: Try removing the below line and making sure things still work. Do the same with the other clause's version of this. tex.MTex->Bind(); } else { texHandle = tex.MTexCube->GetTextureHandle(); textureType = TextureTypeToGLEnum(tex.MTexCube_Face); colWidth = tex.MTexCube->GetWidth(); colHeight = tex.MTexCube->GetHeight(); tex.MTexCube->Bind(); } //Make sure the texture will work and, if it will, attach it. if (colWidth > maxWidth || colHeight > maxHeight) { return false; } newWidth = Mathf::Min(newWidth, colWidth); newHeight = Mathf::Min(newHeight, colHeight); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textureType, texHandle, 0); } } width = newWidth; height = newHeight; if (colAttachments.size() == 0) { glDrawBuffer(GL_NONE); } else { glDrawBuffers(colAttachments.size(), colAttachments.data()); } colorTexes.resize(nTexes); memcpy(colorTexes.data(), newColTexes, sizeof(RenderTargetTex) * nTexes); if (updateDepthSize) { if (depthTex.MTex != 0) { depthTex.MTex->ClearData(width, height); } else if (depthTex.MTexCube != 0) { depthTex.MTexCube->ClearData(width, height); } else { glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, ToGLenum(depthRenderBufferSize), width, height); } } return true; }