// A replacement for the ARB_shader_include extension, which is not widely supported // This loads a "header" file (uniformsFile) and a "source" file (srcFile). It scans // the source file for "#UNIFORMS" and replaces this tag with the contents of the // uniforms file. Limited, but functional for the cases used here std::string loadShaderSourceWithUniformTag(const char* uniformsFile, const char* srcFile) { int32_t len; char *uniformsStr = NvAssetLoaderRead(uniformsFile, len); if (!uniformsStr) return ""; char *srcStr = NvAssetLoaderRead(srcFile, len); if (!srcStr) return ""; std::string dest = ""; const char* uniformTag = "#UNIFORMS"; char* uniformTagStart = strstr(srcStr, uniformTag); if (uniformTagStart) { // NULL the start of the tag *uniformTagStart = 0; dest += srcStr; // source up to tag dest += "\n"; dest += uniformsStr; dest += "\n"; char* uniformTagEnd = uniformTagStart + strlen(uniformTag); dest += uniformTagEnd; } else { dest += srcStr; } NvAssetLoaderFree(uniformsStr); NvAssetLoaderFree(srcStr); return dest; }
void ComputeBasicGLSL::initRendering(void) { NV_APP_BASE_SHARED_INIT(); NvAssetLoaderAddSearchPath("es3aep-kepler/ComputeBasicGLSL"); if (!requireMinAPIVersion(NvGLAPIVersionES3_1())) return; { NvScopedShaderPrefix switched( (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL) ? "#version 430\n" : "#version 310 es\n"); //init shaders m_blitProg = NvGLSLProgram::createFromFiles("shaders/plain.vert", "shaders/plain.frag"); m_computeProg = new NvGLSLProgram; int32_t len; NvGLSLProgram::ShaderSourceItem sources[1]; sources[0].type = GL_COMPUTE_SHADER; sources[0].src = NvAssetLoaderRead("shaders/invert.glsl", len); m_computeProg->setSourceFromStrings(sources, 1); NvAssetLoaderFree((char*)sources[0].src); } //load input texture - this is a normal, "mutable" texture m_sourceImage = NvImage::CreateFromDDSFile("textures/flower1024.dds"); GLint w = m_sourceImage->getWidth(); GLint h = m_sourceImage->getHeight(); GLint intFormat = m_sourceImage->getInternalFormat(); GLint format = m_sourceImage->getFormat(); GLint type = m_sourceImage->getType(); // Image must be immutable in order to be used with glBindImageTexture // So we copy the mutable texture to an immutable texture glGenTextures(1, &m_sourceTexture ); glBindTexture(GL_TEXTURE_2D, m_sourceTexture); glTexStorage2D(GL_TEXTURE_2D, 1, intFormat, w, h ); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, m_sourceImage->getLevel(0)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); //create output texture with same size and format as input // Image must be immutable in order to be used with glBindImageTexture glGenTextures(1, &m_resultTexture ); glBindTexture(GL_TEXTURE_2D, m_resultTexture); glTexStorage2D(GL_TEXTURE_2D, 1, intFormat, w, h ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); CHECK_GL_ERROR(); glBindTexture(GL_TEXTURE_2D, 0); }
static std::string createStringFromAsset(const char* filename) { int32_t len; char *asset = NvAssetLoaderRead(filename, len); std::string str = asset; NvAssetLoaderFree(asset); return str; }
void SceneRenderer::loadModel() { // load model int32_t length; char *modelData = NvAssetLoaderRead("models/cow.obj", length); loadModelFromData(modelData); NvAssetLoaderFree(modelData); }
void InstancingApp::loadModelFromFile(const char *pFileName, int32_t modelNum ) { int32_t length; char *modelData = NvAssetLoaderRead(pFileName, length); m_pModel[modelNum] = NvModelGL::CreateFromObj((uint8_t*)modelData, 10.0f, true); NvAssetLoaderFree(modelData); initSceneInstancingData( modelNum ); }
//-------------------------------------------------------------------------- NvModelGL* DeferredShadingMSAA::LoadModel(const char *model_filename) { // Load model data for scene geometry int32_t length; char *modelData = NvAssetLoaderRead(model_filename, length); NvModelGL* model = NvModelGL::CreateFromObj( (uint8_t *)modelData, 40.0f, true, false); NvAssetLoaderFree(modelData); return model; }
int LoadMdlDataFromFile(const char* name, void** buffer) { int32_t len; char* data = NvAssetLoaderRead(name, len); if (!data) return 0; *buffer = malloc(len+1); memcpy(*buffer, data, len); NvAssetLoaderFree(data); return len; }
uint32_t NvImage::UploadTextureFromDDSFile(const char* filename) { int32_t len; char* ddsData = NvAssetLoaderRead(filename, len); if (!ddsData) return 0; GLuint result = NvImage::UploadTextureFromDDSData(ddsData, len); NvAssetLoaderFree(ddsData); return result; }
NvGLModel* NormalBlendedDecal::loadModel(const char *model_filename) { // Load model data for scene geometry int32_t length; char *modelData = NvAssetLoaderRead(model_filename, length); NvGLModel* model = new NvGLModel(); model->loadModelFromObjData(modelData); model->rescaleModel(1.0f); model->initBuffers(true, true); NvAssetLoaderFree(modelData); CHECK_GL_ERROR(); return model; }
NvGLModel* loadModelFromFile(const char *pFileName, float rescale ) { int32_t length; char *modelData = NvAssetLoaderRead(pFileName, length); NvGLModel* pModel = new NvGLModel; pModel->loadModelFromObjData(modelData); pModel->rescaleModel(rescale); pModel->initBuffers(); NvAssetLoaderFree(modelData); return pModel; }
void ComputeBasicGLSL::initRendering(void) { NvAssetLoaderAddSearchPath("ComputeBasicGLSL"); if (!requireMinAPIVersion(NvGfxAPIVersionGL4())) return; //init shaders m_blitProg = NvGLSLProgram::createFromFiles("shaders/plain.vert", "shaders/plain.frag"); m_computeProg = new NvGLSLProgram; int32_t len; NvGLSLProgram::ShaderSourceItem sources[1]; sources[0].type = GL_COMPUTE_SHADER; sources[0].src = NvAssetLoaderRead("shaders/invert.glsl", len); m_computeProg->setSourceFromStrings(sources, 1); NvAssetLoaderFree((char*)sources[0].src); //load input texture m_sourceImage = NvImage::CreateFromDDSFile("textures/flower1024.dds"); m_sourceTexture = NvImage::UploadTexture(m_sourceImage); glBindTexture(GL_TEXTURE_2D, m_sourceTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); //create output texture with same size and format as input GLint w = m_sourceImage->getWidth(); GLint h = m_sourceImage->getHeight(); GLint intFormat = m_sourceImage->getInternalFormat(); GLint format = m_sourceImage->getFormat(); GLint type = m_sourceImage->getType(); glGenTextures(1, &m_resultTexture ); glBindTexture(GL_TEXTURE_2D, m_resultTexture); glTexImage2D(GL_TEXTURE_2D, 0, intFormat, w, h, 0, format, type, 0 ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); CHECK_GL_ERROR(); glBindTexture(GL_TEXTURE_2D, 0); }
NvImage* NvImage::CreateFromDDSFile(const char* filename) { int32_t len; char* ddsData = NvAssetLoaderRead(filename, len); if (!ddsData) return NULL; NvImage* image = new NvImage; bool result = image->loadImageFromFileData((const uint8_t*)ddsData, len, "dds"); NvAssetLoaderFree(ddsData); if (!result) { delete image; image = NULL; } return image; }
void TopazSample::loadModel(std::string filename, GLuint program, bool calculateCornerPoints) { int32_t length; char* data = NvAssetLoaderRead(filename.c_str(), length); std::unique_ptr<TopazGLModel> model(new TopazGLModel()); model->loadModelFromObjData(data); if (calculateCornerPoints) { model->calculateCornerPoints(1.0f); } model->rescaleModel(1.0f); model->setProgram(program); models.push_back(std::move(model)); NvAssetLoaderFree(data); CHECK_GL_ERROR(); }
void NvFClose(NvFile* file) { NvAssetLoaderFree(file->mData); delete file; }
void MotionBlur::initRendering(void) { // This sample requires at least OpenGL ES 2.0 if (!requireMinAPIVersion(NvGfxAPIVersionES2())) return; cleanRendering(); NvAssetLoaderAddSearchPath("es2-aurora/MotionBlur"); mSceneColorShader = new SceneColorShader; mSkyboxColorShader = new SkyboxColorShader; mMotionBlurShader = new MotionBlurShader; // Load model data for scene geometry int32_t length; char *modelData = NvAssetLoaderRead("models/house.obj", length); mHouseModel = new NvGLModel(); mHouseModel->loadModelFromObjData(modelData); mHouseModel->initBuffers(); NvAssetLoaderFree(modelData); modelData = NvAssetLoaderRead("models/fan.obj", length); mSailsModel = new NvGLModel(); mSailsModel->loadModelFromObjData(modelData); mSailsModel->initBuffers(); NvAssetLoaderFree(modelData); // Load some scene textures mHouseTexID = NvImage::UploadTextureFromDDSFile("textures/windmill_diffuse.dds"); glBindTexture(GL_TEXTURE_2D, mHouseTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); CHECK_GL_ERROR(); mSkyBoxTexID = NvImage::UploadTextureFromDDSFile("textures/sky_cube.dds"); glBindTexture(GL_TEXTURE_CUBE_MAP, mSkyBoxTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECK_GL_ERROR(); // Assign some uniform values that never change. nv::vec4f lightPositionEye(1.0f, 1.0f, 1.0f, 0.0f); mSceneColorShader->enable(); glUniform4fv(mSceneColorShader->lightPositionUHandle, 1, lightPositionEye._array); glUniform1f(mSceneColorShader->lightAmbientUHandle, 0.1f); glUniform1f(mSceneColorShader->lightDiffuseUHandle, 0.7f); glUniform1f(mSceneColorShader->lightSpecularUHandle, 1.0f); glUniform1f(mSceneColorShader->lightShininessUHandle, 64.0f); CHECK_GL_ERROR(); mSceneColorShader->disable(); // Set some pipeline state settings that do not change glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); CHECK_GL_ERROR(); }
virtual void ReleaseData(char* pData) { NvAssetLoaderFree(pData); }
void MultiDrawIndirect::Startup() { std::vector<NvGLModel*>::iterator ii; int32_t length; char* modelData; m_SceneShader = new SceneShader("shaders/scenecolor.vert", "shaders/scenecolorvanilla.frag"); m_SceneShaderMDI = new SceneShader("shaders/scenecolormdi.vert", "shaders/scenecolorvanilla.frag"); m_SkyboxShader = new SkyboxShader; // Set the initial view m_transformer->setRotationVec(nv::vec3f(0.0f, 2.35f, 0.0f)); m_transformer->setTranslationVec(nv::vec3f(0.0f, -50.0f, 0.0f)); modelData = NvAssetLoaderRead(MODEL_TO_LOAD_1, length); m_Model = new NvGLModel(); m_Model->loadModelFromObjData(modelData); m_Model->initBuffers(); NvAssetLoaderFree(modelData); m_WindmillTextureID = NvImage::UploadTextureFromDDSFile("textures/windmill_diffuse1.dds"); glBindTexture(GL_TEXTURE_2D, m_WindmillTextureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); m_SkyBoxTextureID = NvImage::UploadTextureFromDDSFile("textures/sky_cube.dds"); glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyBoxTextureID); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); nv::vec4f lightPositionEye(1.0f, 1.0f, 1.0f, 0.0f); glGenBuffers(1, &m_IndirectDrawBuffer); glGenVertexArrays(1, &m_VertexArrayObject); CreateMultiDrawParameters(); SetupMultiDrawParameters(); m_SceneShader->enable(); glUniform4fv(m_SceneShader->m_LightPositionUHandle, 1, lightPositionEye._array); glUniform1f(m_SceneShader->m_LightAmbientUHandle, 0.1f); glUniform1f(m_SceneShader->m_LightDiffuseUHandle, 0.7f); glUniform1f(m_SceneShader->m_LightSpecularUHandle, 1.0f); glUniform1f(m_SceneShader->m_LightShininessUHandle, 64.0f); m_SceneShader->disable(); m_SceneShaderMDI->enable(); glUniform4fv(m_SceneShaderMDI->m_LightPositionUHandle, 1, lightPositionEye._array); glUniform1f(m_SceneShaderMDI->m_LightAmbientUHandle, 0.1f); glUniform1f(m_SceneShaderMDI->m_LightDiffuseUHandle, 0.7f); glUniform1f(m_SceneShaderMDI->m_LightSpecularUHandle, 1.0f); glUniform1f(m_SceneShaderMDI->m_LightShininessUHandle, 64.0f); SetupMultiDrawIndirectData( m_SceneShaderMDI->m_PositionAHandle, m_SceneShaderMDI->m_NormalAHandle, m_SceneShaderMDI->m_TexcoordAHandle, m_SceneShaderMDI->m_InstanceAHandle); m_SceneShaderMDI->disable(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); }
void Mercury::initRendering(void) { // OpenGL 4.3 is the minimum for compute shaders if (!requireMinAPIVersion(NvGLAPIVersionES3_1())) return; // Set Clear Color glClearColor(0.25f, 0.25f, 0.25f, 1.0f); CHECK_GL_ERROR(); NvAssetLoaderAddSearchPath("es3aep-kepler/Mercury"); const char* shaderPrefix = (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL) ? "#version 430\n" : "#version 310 es\n"; CHECK_GL_ERROR(); { int32_t len; // Initialize Particles Render Program NvScopedShaderPrefix switched(shaderPrefix); std::string renderPartVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartVS.glsl"); std::string renderPartGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartGS.glsl"); mParticlesRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesP[2]; sourcesP[0].type = GL_VERTEX_SHADER; sourcesP[0].src = renderPartVS.c_str(); sourcesP[1].type = GL_FRAGMENT_SHADER; sourcesP[1].src = NvAssetLoaderRead("shaders/renderPartFS.glsl", len); mParticlesRenderProg->setSourceFromStrings(sourcesP, 2); NvAssetLoaderFree((char*)sourcesP[1].src); // Initialize Surface Render Program std::string renderSurfVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfVS.glsl"); std::string renderSurfGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfGS.glsl"); std::string renderSurfFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfFS.glsl"); mSurfaceRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesS[3]; sourcesS[0].type = GL_VERTEX_SHADER; sourcesS[0].src = renderSurfVS.c_str(); sourcesS[1].type = GL_GEOMETRY_SHADER_EXT; sourcesS[1].src = renderSurfGS.c_str(); sourcesS[2].type = GL_FRAGMENT_SHADER; sourcesS[2].src = renderSurfFS.c_str(); mSurfaceRenderProg->setSourceFromStrings(sourcesS, 3); std::string quadVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadVS.glsl"); std::string quadFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadFS.glsl"); mQuadProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesQ[2]; sourcesQ[0].type = GL_VERTEX_SHADER; sourcesQ[0].src = quadVS.c_str(); sourcesQ[1].type = GL_FRAGMENT_SHADER; sourcesQ[1].src = quadFS.c_str(); mQuadProg->setSourceFromStrings(sourcesQ, 2); std::string blurVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurVS.glsl"); std::string blurFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurFS.glsl"); mBlurProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesB[2]; sourcesB[0].type = GL_VERTEX_SHADER; sourcesB[0].src = blurVS.c_str(); sourcesB[1].type = GL_FRAGMENT_SHADER; sourcesB[1].src = blurFS.c_str(); mBlurProg->setSourceFromStrings(sourcesB, 2); } CHECK_GL_ERROR(); // Set up cubemap for skybox mSkyBoxTexID = NvImageGL::UploadTextureFromDDSFile("textures/sky_cube.dds"); glBindTexture(GL_TEXTURE_CUBE_MAP, mSkyBoxTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECK_GL_ERROR(); // Initialize skybox for screen quad mScreenQuadPos = new ShaderBuffer<nv::vec4f>(4); vec4f* pos = mScreenQuadPos->map(); pos[0] = vec4f(-1.0f, -1.0f, -1.0f, 1.0f); pos[1] = vec4f( 1.0f, -1.0f, -1.0f, 1.0f); pos[2] = vec4f(-1.0f, 1.0f, -1.0f, 1.0f); pos[3] = vec4f( 1.0f, 1.0f, -1.0f, 1.0f); mScreenQuadPos->unmap(); //create ubo and initialize it with the structure data glGenBuffers( 1, &mUBO); glBindBuffer( GL_UNIFORM_BUFFER, mUBO); glBufferData( GL_UNIFORM_BUFFER, sizeof(ShaderParams), &mShaderParams, GL_STREAM_DRAW); CHECK_GL_ERROR(); //create simple single-vertex VBO float vtx_data[] = { 0.0f, 0.0f, 0.0f, 1.0f}; glGenBuffers( 1, &mVBO); glBindBuffer( GL_ARRAY_BUFFER, mVBO); glBufferData( GL_ARRAY_BUFFER, sizeof(vtx_data), vtx_data, GL_STATIC_DRAW); CHECK_GL_ERROR(); // For now, scale back the particle count on mobile. //int32_t particleCount = isMobilePlatform() ? (mNumParticles >> 2) : mNumParticles; int32_t particleCount = mNumParticles; mParticles = new ParticleSystem(particleCount, shaderPrefix); CHECK_GL_ERROR(); int cx, cy, cz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &cx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &cy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &cz ); LOGI("Max compute work group count = %d, %d, %d\n", cx, cy, cz ); int sx, sy, sz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &sx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &sy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &sz ); LOGI("Max compute work group size = %d, %d, %d\n", sx, sy, sz ); CHECK_GL_ERROR(); //Set clockwise winding glFrontFace(GL_CW); // Texture const int screen_width = getAppContext()->width(); const int screen_height = getAppContext()->height(); // Frame buffer for final scene glGenTextures(gbuffer_size, gbuffer_tex); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (int i = 0; i < gbuffer_size; i++) { glActiveTexture(GL_TEXTURE0 + 3 + i); glBindTexture(GL_TEXTURE_2D, gbuffer_tex[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, screen_width, screen_height, 0, GL_RGBA, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, gbuffer_tex[i], 0); } // Depth buffer glGenRenderbuffers(1, &rbo_depth); glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth); GLuint attachments[gbuffer_size]; for (int i = 0; i < gbuffer_size; i++) { attachments[i] = GL_COLOR_ATTACHMENT0 + i; } glDrawBuffers(gbuffer_size, attachments); GLenum status; if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { LOGE("glCheckFramebufferStatus: error %p", status); exit(0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); }