void Scene::splatRecords() { /*irradianceRecord rec1, rec2, rec3; rec1.pos[0] = 2.1766; rec1.pos[1] = 1.8176; rec1.pos[2] = 5.1762; rec1.norm[0] = -.573576; rec1.norm[1] = 0; rec1.norm[2] = -.819152; rec1.irradiance[0] = 1; rec1.irradiance[1] = 0; rec1.irradiance[2] = 0; rec1.hmd = 1.0; records.clear(); records.push_back(rec1); */ float eye[3]; float eyedir[3]; float up[3] = {0.0, 1.0, 0.0}; view->getEye(eye); view->getCenter(eyedir); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, splatBufFBOID); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, splatTex, 0); glViewport(0, 0, windWidth, windHeight); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE);//add all the contributions together glUseProgram(splatProgram); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); viewProjSetup(eye, eyedir, up, 45.0, 1.0, defaultFront, defaultBack); float color[4] = {1, 0, 1, 1}; glPointSize(5); glColor4fv(color); //set up samplers glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, coordTexBase[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, coordTexBase[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, coordTexBase[2]); float ws[2] = {windWidth, windHeight}; std::cout << splatWindSizeUniform << std::endl; glUniform2fv(splatWindSizeUniform, 1, ws); glUniform1f(splatAUniform, a); glUniform1i(splatWorldPosUniform, 0); glUniform1i(splatWorldNormUniform, 1); glUniform1i(splatDiffuseUniform, 2); for(size_t i = 0; i < records.size(); ++i) { glUniform1f(splatUniform,records[i].hmd*a); glUniform1f(splatHmdUniform, records[i].hmd); glBegin(GL_QUADS); for(int j = 0; j < 4; ++j) { glVertexAttrib1f(splatAttribute, 3 - j); glNormal3fv(records[i].norm); glColor3fv(records[i].irradiance); glVertex3fv(records[i].pos); } glEnd(); } glFlush(); //glutSwapBuffers(); std::cout << records.size() << "records splatted" << std::endl; Helpers::getGLErrors("end of splat"); glIsShader(999); glIsTexture(222); std::cout << "after first records splatted " << timer.split() << std::endl; //now do another frag shader pass //now read the buffer back and to the CPU traversal glBindTexture(GL_TEXTURE_2D, splatTex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, splatBuffer); int startNewRecords = records.size(); float * newpos; float * newnorm; double modelviewmat[16]; double projectionmat[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelviewmat); matrix4x4 modmat(modelviewmat); glGetDoublev(GL_PROJECTION_MATRIX, projectionmat); matrix4x4 projmat(projectionmat); double identity[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; vector3d xyz, norm, eyeCoord, perpLeft, perpDown; float upv[3] = {0, 1, 0}, right[3] = {1, 0, 0}; vector3d upvec(upv); vector3d rightvec(right); vector3d botleft, topright; vector3d projbotLeft, projtopRight; float hmd; double x1, y1, z1, x2, y2, z2;//for gluproject GLint vp[4] = {0, 0, windWidth, windHeight}; int xmin, xmax, ymin, ymax; for(size_t y = 0; y < windHeight; ++y) { for(size_t x = 0; x < windWidth; ++x) { if(splatBuffer[(y*windWidth +x)*4 + 3] < a) { newpos = &objectCoords[(y*windWidth +x)*3]; newnorm = &objectNormals[(y*windWidth +x)*3]; generateRecord(newpos, newnorm); hmd = records.back().hmd; //do a simple cpusplat to update nearby weights //mimic the v and f shaders almost exactly xyz = vector3d(newpos); norm = vector3d(newnorm); eyeCoord = modmat.mult(xyz); perpLeft = (((eyeCoord.normalize()).cross(upvec)).normalize()).scale(a*hmd); perpDown = (((eyeCoord.normalize()).cross(rightvec)).normalize()).scale(a*hmd); botleft = eyeCoord + perpLeft + perpDown; topright = eyeCoord - perpLeft - perpDown; gluProject(botleft.xyz[0], botleft.xyz[1], botleft.xyz[2], identity, projectionmat, vp, &x1, &y1, &z1); gluProject(topright.xyz[0], topright.xyz[1], topright.xyz[2], identity, projectionmat, vp, &x2, &y2, &z2); //bottom left is actually bottom right // top right is actually top left //WTF!! xmin = std::max(0, int(x2)); xmax = std::min(int(windWidth), int(ceil(x1))); ymin = std::max(0, int(y1)); ymax = std::min(int(windHeight), int(ceil(y2))); //std::cout << "updating range: x1 x2, y1 y2: " << xmin << //' ' << xmax << ' ' << ymin << ' ' << ymax << std::endl; //splat the w coord int offset; float w, dist, sqrtnrm, dot; for(int fragy = ymin; fragy < ymax; ++fragy) { for(int fragx = xmin; fragx < xmax; ++fragx) { //compute distance: offset = (fragy*windWidth + fragx)*3; dist = sqrt(pow(newpos[0] - objectCoords[offset], 2) + pow(newpos[1] - objectCoords[offset+1],2)+ pow(newpos[2] - objectCoords[offset+2],2)); if(dist >= a*hmd) continue; dot = newnorm[0]*objectNormals[offset] + newnorm[1]*objectNormals[offset +1] + newnorm[2]*objectNormals[offset +2]; dot = std::min(1.0f, dot); sqrtnrm = sqrt(1.0 - dot); w = 1.0/((dist/hmd) + sqrtnrm); if (w >= 1.0/a) { splatBuffer[(fragy*windWidth +fragx)*4 + 3] += w; } } } } } } std::cout << "cpu traversal" << timer.split() << std::endl; std::cout << "about to splat new records" << std::endl; glUseProgram(splatProgram); //splat the newly added records for(size_t i = startNewRecords; i < records.size(); ++i) { glUniform1f(splatUniform,records[i].hmd*a); glUniform1f(splatHmdUniform, records[i].hmd); glBegin(GL_QUADS); for(int j = 0; j < 4; ++j) { glVertexAttrib1f(splatAttribute, 3 - j); glNormal3fv(records[i].norm); glColor3fv(records[i].irradiance); glVertex3fv(records[i].pos); } glEnd(); } std::cout << records.size() - startNewRecords << " new records created" << std::endl; glFlush(); }
/* used for both 3d view and image window */ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); PaletteColor *color; Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; const unsigned char *cp; CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); if (use_palette) { if (!palette) { palette = BKE_palette_add(CTX_data_main(C), "Palette"); BKE_paint_palette_set(paint, palette); } color = BKE_palette_color_add(palette); } if (CTX_wm_view3d(C) && texpaint_proj) { /* first try getting a colour directly from the mesh faces if possible */ Object *ob = OBACT; bool sample_success = false; ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL); if (ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); ViewContext vc; const int mval[2] = {x, y}; unsigned int faceindex; unsigned int totface = dm->getNumTessFaces(dm); MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); DM_update_materials(dm, ob); if (dm_mtface) { view3d_set_viewcontext(C, &vc); view3d_operator_needs_opengl(C); if (imapaint_pick_face(&vc, mval, &faceindex, totface)) { Image *image; if (use_material) image = imapaint_face_image(dm, faceindex); else image = imapaint->canvas; if (image) { ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf && ibuf->rect) { float uv[2]; float u, v; imapaint_pick_uv(scene, ob, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); v = fmodf(uv[1], 1.0f); if (u < 0.0f) u += 1.0f; if (v < 0.0f) v += 1.0f; u = u * ibuf->x - 0.5f; v = v * ibuf->y - 0.5f; if (ibuf->rect_float) { float rgba_f[4]; bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); } else { linearrgb_to_srgb_v3_v3(rgba_f, rgba_f); BKE_brush_color_set(scene, br, rgba_f); } } else { unsigned char rgba[4]; bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, rgba); BKE_brush_color_set(scene, br, rgba_f); } } } BKE_image_release_ibuf(image, ibuf, NULL); } } } dm->release(dm); } if (!sample_success) { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } else return; } else { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } cp = (unsigned char *)&col; if (use_palette) { rgb_uchar_to_float(color->rgb, cp); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, cp); BKE_brush_color_set(scene, br, rgba_f); } }
int surface_create(int width, int height) { if (!GLEW_EXT_framebuffer_object) { return -1; } GLuint tex, fbo; int prevFbo; size_t id, w = (int)width, h = (int)height; //get the integer width and height, and prepare to search for an id if (enigma::surface_max==0) { enigma::surface_array=new enigma::surface*[1]; enigma::surface_max=1; } for (id=0; enigma::surface_array[id]!=NULL; id++) { if (id+1 >= enigma::surface_max) { enigma::surface **oldarray=enigma::surface_array; enigma::surface_array=new enigma::surface*[enigma::surface_max+1]; for (size_t i=0; i<enigma::surface_max; i++) enigma::surface_array[i]=oldarray[i]; enigma::surface_array[enigma::surface_max]=NULL; enigma::surface_max++; delete[] oldarray; } } enigma::surface_array[id] = new enigma::surface; enigma::surface_array[id]->width = w; enigma::surface_array[id]->height = h; glGenTextures(1, &tex); glGenFramebuffers(1, &fbo); glPushAttrib(GL_TEXTURE_BIT); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prevFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glClearColor(1,1,1,0); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); glPopAttrib(); enigma::surface_array[id]->tex = tex; enigma::surface_array[id]->fbo = fbo; return id; }
static enum piglit_result test(void) { static const GLfloat dest_color[4] = { 0.75, 0.25, 0.25, 0.5 }; static const GLfloat test_color[4] = { 1.0, 0.25, 0.75, 0.25 }; static const GLfloat test_color1[4] = { 0.5, 0.5, 0.5, 0.5 }; GLfloat expected[4]; GLuint prog; GLuint vs; GLuint fs; int i, j, k, o; if (max_ds_buffers > 1) { printf("Test only supports 1 dual source blending color buffer\n"); max_ds_buffers = 1; } prog = glCreateProgram(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text); glAttachShader(prog, vs); glAttachShader(prog, fs); piglit_check_gl_error(GL_NO_ERROR); glBindFragDataLocationIndexed(prog, 0, 0, "col0"); glBindFragDataLocationIndexed(prog, 0, 1, "col1"); create_fbo(); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glLinkProgram(prog); glUseProgram(prog); uniform_src0 = glGetUniformLocation(prog, "src0"); uniform_src1 = glGetUniformLocation(prog, "src1"); /* Setup blend modes and compute expected result color. * We only test two simple blending modes. A more elaborate * test would exercise a much wider variety of modes. */ for (o = 0; o < ARRAY_SIZE(operators); o++) { for (i = 0; i < ARRAY_SIZE(srcFactors); i++) { for (j = 0; j < ARRAY_SIZE(dstFactors); j++) { blend_expected(expected, test_color, test_color1, dest_color, srcFactors[i], dstFactors[j], operators[o]); blend(test_color, test_color1, dest_color, srcFactors[i], dstFactors[j], operators[o]); for (k = 0; k < max_ds_buffers; k++) { glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + k); check_error(__LINE__); if (!piglit_probe_pixel_rgba(5, 5, expected)) { printf("For src/dst %d %d %d\n", i, j, o); return PIGLIT_FAIL; } } } } } return PIGLIT_PASS; }
void GL3PlusFrameBufferObject::initialise() { // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attachment 0 must have surface attached", "GL3PlusFrameBufferObject::initialise"); } // If we're doing multisampling, then we need another FBO which contains a // renderbuffer which is set up to multisample, and we'll blit it to the final // FBO afterwards to perform the multisample resolve. In that case, the // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); uint32 height = mColour[0].buffer->getHeight(); GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); // Bind simple buffer to add colour attachments mManager->getStateCacheManager()->bindGLFrameBuffer( GL_FRAMEBUFFER, mFB ); // Bind all attachment points to frame buffer for(unsigned int x = 0; x < maxSupportedMRTs; ++x) { if(mColour[x].buffer) { if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height) { StringStream ss; ss << "Attachment " << x << " has incompatible size "; ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight(); ss << ". It must be of the same as the size of surface 0, "; ss << width << "x" << height; ss << "."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GL3PlusFrameBufferObject::initialise"); } if(mColour[x].buffer->getGLFormat() != format) { StringStream ss; ss << "Attachment " << x << " has incompatible format."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GL3PlusFrameBufferObject::initialise"); } if(getFormat() == PF_DEPTH) mColour[x].buffer->bindToFramebuffer(GL_DEPTH_ATTACHMENT, mColour[x].zoffset); else mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0+x, mColour[x].zoffset); } else { // Detach OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+x, GL_RENDERBUFFER, 0)); } } // Now deal with depth / stencil if (mMultisampleFB) { // Bind multisample buffer mManager->getStateCacheManager()->bindGLFrameBuffer( GL_FRAMEBUFFER, mMultisampleFB ); // Create AA render buffer (colour) // note, this can be shared too because we blit it to the final FBO // right after the render is finished mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); // Attach it, because we won't be attaching below and non-multisample has // actually been attached to other FBO mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, mMultisampleColourBuffer.zoffset); // depth & stencil will be dealt with below } // Depth buffer is not handled here anymore. // See GL3PlusFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() // Do glDrawBuffer calls GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; GLsizei n=0; for(unsigned int x=0; x<maxSupportedMRTs; ++x) { // Fill attached colour buffers if(mColour[x].buffer) { if(getFormat() == PF_DEPTH) bufs[x] = GL_DEPTH_ATTACHMENT; else bufs[x] = GL_COLOR_ATTACHMENT0 + x; // Keep highest used buffer + 1 n = x+1; } else { bufs[x] = GL_NONE; } } // Drawbuffer extension supported, use it if(getFormat() != PF_DEPTH) OGRE_CHECK_GL_ERROR(glDrawBuffers(n, bufs)); if (mMultisampleFB) { // we need a read buffer because we'll be blitting to mFB OGRE_CHECK_GL_ERROR(glReadBuffer(bufs[0])); } else { // No read buffer, by default, if we want to read anyway we must not forget to set this. OGRE_CHECK_GL_ERROR(glReadBuffer(GL_NONE)); } // Check status GLuint status; OGRE_CHECK_GL_ERROR(status = glCheckFramebufferStatus(GL_FRAMEBUFFER)); // Bind main buffer mManager->getStateCacheManager()->bindGLFrameBuffer( GL_FRAMEBUFFER, 0 ); switch(status) { case GL_FRAMEBUFFER_COMPLETE: // All is good break; case GL_FRAMEBUFFER_UNSUPPORTED: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "All framebuffer formats with this texture internal format unsupported", "GL3PlusFrameBufferObject::initialise"); default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Framebuffer incomplete or other FBO status error", "GL3PlusFrameBufferObject::initialise"); } }
void glInternalFlush(u32 target) { u32 i; u32 param_base = REGS32(0x8020) & 0x007FFFFF; u32 background = (REGS32(0x808C) & 0x00FFFFF8) >> 1; u32 address = (param_base + background) & 0x007FFFFF; flushPrim(); NewStripList(); BACKGROUND((u32*)&VRAM[address]); flushPrim(); NewStripList(); glClearColor((float)REGS[0x8042] / 255.0f, (float)REGS[0x8041] / 255.0f, (float)REGS[0x8040] / 255.0f, (float)REGS[0x8043] / 255.0f); glDepthMask(GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (cfg.ListSorting) { qsort((void*)objList, objCount, sizeof(OBJECT), comp_func); // qsort((void*)objList,objCount,sizeof(OBJECT),listtypesort_func); // qsort((void*)objList,objCount,sizeof(OBJECT),transsort_func); // qsort((void*)objList,objCount,sizeof(OBJECT),punchsort_func); } glPushMatrix(); switch (target) { case RENDER_TARGET_FRAMEBUFFER: glViewport(0, 0, 640, 480); glTranslatef(0.0f, 0.0f, -(float)RENDER_VIEW_DISTANCE); break; case RENDER_TARGET_TEXTURE: { glViewport(0, 0, 640, (REGS16(0x806E) - REGS16(0x806c) + 1)); glScalef(1.0f, -1.0f, 1.0f); glTranslatef(0.0f, -480.0f, -(float)RENDER_VIEW_DISTANCE); break; } } // DEMUL_printf(">render scene (objCount=%d)\n",objCount); for (i = 0; i < objCount; i++) { OBJECT *obj = &objList[i]; vCount = obj->vCount; if (vCount) { polygon = obj->polygon; // DEMUL_printf(">object %3d, dist = %6f, listtype = %d, pcw = %08X, isp = %08X, tsp = %08X, tcw = %08X\n",i,obj->midZ, obj->polygon.pcw.listtype, obj->polygon.pcw.all, obj->polygon.isp.all, obj->polygon.tsp.all, obj->polygon.tcw.all); if (polygon.tsp.usealpha && cfg.AlphaZWriteDisable) polygon.isp.zwritedis = 1; SetupShadeMode(); SetupCullMode(); SetupZBuffer(); if (cfg.Wireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { SetupAlphaTest(); SetupAlphaBlend(); SetupTexture(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } glDrawElements(GL_TRIANGLES, vCount, GL_UNSIGNED_INT, &pIndex[obj->vIndex]); } } glPopMatrix(); // ProfileFinish(0); IRQ(0x0002); switch (target) { case RENDER_TARGET_FRAMEBUFFER: SwapBuffers(hdc); break; case RENDER_TARGET_TEXTURE: { u32 tw = REGS32(0x804C) << 2; u32 th = 512; glReadBuffer(GL_BACK); glBindTexture(GL_TEXTURE_2D, backbufname); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, tw, th, 0); isFramebufferRendered = 1; TextureAddress = REGS32(0x8060) & 0x007FFFFF; break; } } // DEMUL_printf(">render end\n"); // DEMUL_printf(">frame summary (maxz=%f,minz=%f)\n",maxz,minz); maxz = -10000000.0f; minz = 10000000.0f; objCount = 0; vIndex = 0; vCount = 0; vVertex = 0; }
void FramebufferImplementation_Legacy::setReadBuffer(const Framebuffer * fbo, GLenum mode) const { fbo->bind(GL_READ_FRAMEBUFFER); glReadBuffer(mode); }
void OpenGLWindowProvider::flip(int interval) { OpenGL::set_active(get_gc()); glFlush(); if (shadow_window) { int width = get_viewport().get_width(); int height = get_viewport().get_height(); if (using_gl3) { if (double_buffered) { glDrawBuffer(GL_BACK); glReadBuffer(GL_FRONT); } PixelBuffer pixelbuffer(width, height, tf_bgra8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); } else { GLint old_viewport[4], old_matrix_mode; GLfloat old_matrix_projection[16], old_matrix_modelview[16]; glGetIntegerv(GL_VIEWPORT, old_viewport); glGetIntegerv(GL_MATRIX_MODE, &old_matrix_mode); glGetFloatv(GL_PROJECTION_MATRIX, old_matrix_projection); glGetFloatv(GL_MODELVIEW_MATRIX, old_matrix_modelview); GLboolean blending = glIsEnabled(GL_BLEND); glDisable(GL_BLEND); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMultMatrixf(Mat4f::ortho_2d(0.0f, (float)width, 0.0f, (float)height, handed_right, clip_negative_positive_w)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (double_buffered) { glReadBuffer(GL_BACK); } glRasterPos2i(0, 0); glPixelZoom(1.0f, 1.0f); PixelBuffer pixelbuffer(width, height, tf_rgba8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); if (blending) glEnable(GL_BLEND); glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]); glMatrixMode(GL_PROJECTION); glLoadMatrixf(old_matrix_projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(old_matrix_modelview); glMatrixMode(old_matrix_mode); } } else { if (interval != -1 && interval != swap_interval) { swap_interval = interval; if (wglSwapIntervalEXT) wglSwapIntervalEXT(swap_interval); } BOOL retval = SwapBuffers(get_device_context()); if (dwm_layered) { int width = get_viewport().get_width(); int height = get_viewport().get_height(); glReadBuffer(GL_FRONT); PixelBuffer pixelbuffer(width, height, tf_r8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_ALPHA, GL_BYTE, // use GL_BITMAP here for even less transfer? pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); } } OpenGL::check_error(); }
enum piglit_result piglit_display(void) { GLubyte *win_image, *fbo_image; GLuint fbo, rb; bool pass = true; win_image = (GLubyte *) malloc(piglit_width * piglit_height * 3); fbo_image = (GLubyte *) malloc(piglit_width * piglit_height * 3); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, piglit_width, piglit_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); assert(glGetError() == 0); assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); /* draw reference image in the window */ glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo); draw_test_image(); glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, win_image); /* draw test image in fbo */ glBindFramebuffer(GL_FRAMEBUFFER, fbo); glReadBuffer(GL_COLOR_ATTACHMENT0); draw_test_image(); glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, fbo_image); /* compare images */ if (memcmp(win_image, fbo_image, piglit_width * piglit_height * 3)) { #if 0 /* helpful debug code */ int i, k; for (i = k = 0; i < piglit_width * piglit_height * 3; i++) { if (win_image[i] != fbo_image[i] && k++ < 40) printf("%d: %d vs. %d\n", i, win_image[i], fbo_image[i]); } #endif printf("Image comparison failed!\n"); pass = false; } else if (!piglit_automatic) { printf("Image comparison passed.\n"); } glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo); #if 0 /* for debug/compare (alternate diplaying Window vs. FBO image) */ { int i; glWindowPos2i(0,0); for (i = 0; i < 10; i++) { GLubyte *image = (i & 1) ? fbo_image : win_image; printf("Showing %s image\n", (i & 1) ? "FBO" : "window"); glDrawPixels(piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, image); piglit_present_results(); sleep(1); } } #endif piglit_present_results(); glDeleteRenderbuffers(1, &rb); glDeleteFramebuffers(1, &fbo); free(win_image); free(fbo_image); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
image::Image * getDrawBufferImage() { GLenum format = GL_RGB; GLint channels = _gl_format_channels(format); if (channels > 4) { return NULL; } Context context; GLenum framebuffer_binding; GLenum framebuffer_target; if (context.ES) { framebuffer_binding = GL_FRAMEBUFFER_BINDING; framebuffer_target = GL_FRAMEBUFFER; } else { framebuffer_binding = GL_DRAW_FRAMEBUFFER_BINDING; framebuffer_target = GL_DRAW_FRAMEBUFFER; } GLint draw_framebuffer = 0; glGetIntegerv(framebuffer_binding, &draw_framebuffer); GLint draw_buffer = GL_NONE; ImageDesc desc; if (draw_framebuffer) { if (context.ARB_draw_buffers) { glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer); if (draw_buffer == GL_NONE) { return NULL; } } if (!getFramebufferAttachmentDesc(context, framebuffer_target, draw_buffer, desc)) { return NULL; } } else { if (!context.ES) { glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); if (draw_buffer == GL_NONE) { return NULL; } } if (!getDrawableBounds(&desc.width, &desc.height)) { return NULL; } desc.depth = 1; } GLenum type = GL_UNSIGNED_BYTE; #if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { type = GL_UNSIGNED_INT; channels = 4; } #endif image::Image *image = new image::Image(desc.width, desc.height, channels, true); if (!image) { return NULL; } while (glGetError() != GL_NO_ERROR) {} GLint read_framebuffer = 0; GLint read_buffer = GL_NONE; if (!context.ES) { glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, draw_framebuffer); glGetIntegerv(GL_READ_BUFFER, &read_buffer); glReadBuffer(draw_buffer); } // TODO: reset imaging state too context.resetPixelPackState(); glReadPixels(0, 0, desc.width, desc.height, format, type, image->pixels); context.restorePixelPackState(); if (!context.ES) { glReadBuffer(read_buffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer); } GLenum error = glGetError(); if (error != GL_NO_ERROR) { do { std::cerr << "warning: " << enumToString(error) << " while getting snapshot\n"; error = glGetError(); } while(error != GL_NO_ERROR); delete image; return NULL; } return image; }
static inline GLuint downsampledFramebuffer(Context &context, GLuint oldFbo, GLint drawbuffer, GLint colorRb, GLint depthRb, GLint stencilRb, GLuint *rbs, GLint *numRbs) { GLuint fbo; *numRbs = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); { // color buffer ImageDesc desc; glBindRenderbuffer(GL_RENDERBUFFER, colorRb); getBoundRenderbufferDesc(context, desc); glGenRenderbuffers(1, &rbs[*numRbs]); glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]); glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer, GL_RENDERBUFFER, rbs[*numRbs]); glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glDrawBuffer(drawbuffer); glReadBuffer(drawbuffer); glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, fbo); ++*numRbs; } if (stencilRb == depthRb && stencilRb) { //combined depth and stencil buffer ImageDesc desc; glBindRenderbuffer(GL_RENDERBUFFER, depthRb); getBoundRenderbufferDesc(context, desc); glGenRenderbuffers(1, &rbs[*numRbs]); glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]); glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbs[*numRbs]); glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, fbo); ++*numRbs; } else { if (depthRb) { ImageDesc desc; glBindRenderbuffer(GL_RENDERBUFFER, depthRb); getBoundRenderbufferDesc(context, desc); glGenRenderbuffers(1, &rbs[*numRbs]); glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]); glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbs[*numRbs]); glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glDrawBuffer(GL_DEPTH_ATTACHMENT); glReadBuffer(GL_DEPTH_ATTACHMENT); glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); ++*numRbs; } if (stencilRb) { ImageDesc desc; glBindRenderbuffer(GL_RENDERBUFFER, stencilRb); getBoundRenderbufferDesc(context, desc); glGenRenderbuffers(1, &rbs[*numRbs]); glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]); glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbs[*numRbs]); glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glDrawBuffer(GL_STENCIL_ATTACHMENT); glReadBuffer(GL_STENCIL_ATTACHMENT); glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height, GL_STENCIL_BUFFER_BIT, GL_NEAREST); ++*numRbs; } } return fbo; }
void menu(int value) { switch (value) { case 0: showSphereMap = 0; break; case 1: showSphereMap = 1; break; case 4: object = (object + 1) % 3; break; case 5: smapSetSphereMapTexDim(smap, 64); smapSetViewTexDim(smap, 64); break; case 6: smapSetSphereMapTexDim(smap, 128); smapSetViewTexDim(smap, 128); break; case 7: smapSetSphereMapTexDim(smap, 256); smapSetViewTexDim(smap, 256); break; case 8: glDrawBuffer(GL_FRONT); glReadBuffer(GL_FRONT); doubleBuffer = 0; break; case 9: glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); doubleBuffer = 1; break; case 10: dynamicSmap = 1; break; case 11: dynamicSmap = 0; break; case 12: cullBackFaces = 1; break; case 13: cullBackFaces = 0; break; case 14: doSphereMap = 1; multipass = 0; break; case 15: doSphereMap = 0; multipass = 0; break; case 16: multipass = 1; break; case 666: exit(0); break; } glutPostRedisplay(); }
//*********************************** // pixel manipulations //*********************************** void performPixelManipulation() { int i; GLbyte *pbits = NULL; //signed 8 bit integer GLbyte ptemp; // GLint viewport[4]; GLenum lastBuffer; unsigned long imageSize; unsigned int x = 64; unsigned int y = 64; unsigned int width = 220; // width of the window unsigned int height =180; // get the viewport dimensions glGetIntegerv(GL_VIEWPORT, viewport); // calculate image size (3 components per pixel) imageSize = viewport[2] * viewport[3] * 3; // allocate memory pbits = (GLbyte *) malloc(imageSize); if(pbits == NULL) { printf("Error: couldn't allocate memory in %s!", __func__); exit(-1); } // read the pixels from the buffer glPixelStorei(GL_PACK_ALIGNMENT, 1); //1 byte glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); // save the buffer setting (used for restoration later) glGetIntegerv(GL_READ_BUFFER, &lastBuffer); // switch to front buffer and read pixels glReadBuffer(GL_FRONT); glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pbits); // restore buffer glReadBuffer(lastBuffer); // run through the pixels for modification for(i = 0; i < imageSize; i = i+3) { //ptemp = 0.333*(pbits[i] + pbits[i+1] + pbits[i+2]); //rgb to grey scale //if (ptemp < 0) ptemp = abs(ptemp); //has to check this out //pbits[i+2] = 0; //b pbits[i+1] = 0; //g //pbits[i] = ptemp; //r //pbits[i+1] = ptemp; //g //pbits[i+2] = ptemp; //b } // save buffer setting glGetIntegerv(GL_READ_BUFFER, &lastBuffer); // write pixels glReadBuffer(GL_FRONT); glRasterPos3i(x, 0, y); // offset glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pbits); // restore buffer glReadBuffer(lastBuffer); }
void Scene::generateRecord(float *pos, float* normal) { float eps = .00001; float up[3]; if((fabs(normal[0]) <= eps) && ((fabs(normal[1] -1) <= eps) || (fabs(normal[1] +1) <= eps)) && (fabs(normal[2]) <= eps)) { up[0] = 1; up[1] = 0; up[2] = 0; } else { up[0] = 0; up[1] = 1; up[2] = 0; } float lookat[3]; lookat[0] = pos[0] + normal[0]; lookat[1] = pos[1] + normal[1]; lookat[2] = pos[2] + normal[2]; //bind my fbo glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, recordFBOID); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, recordTexBase[0], 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, recordTexBase[1], 0); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); drawAtPoint(pos, lookat, up, recordFBOID, recordWidth, recordHeight, recordFOV, recordFront, recordBack); glBindTexture(GL_TEXTURE_2D, recordTexBase[0]); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, IMap); float r = 0.0; float g = 0.0; float b = 0.0; float planeDim = 2*closePlane/cos(recordFOV*M_PI/360.0);//width/height of //the plane float dA = planeDim*planeDim/(recordWidth*recordHeight); float xoffset = recordWidth/2.0; float yoffset = recordWidth/2.0; float f_h; //eqn 2 from LC04 irradianceRecord rec; float hmdsum = 0.0; float dist; for(size_t y = 0; y < recordHeight; ++y) { for(size_t x = 0; x < recordWidth; ++x) { f_h = dA/(M_PI*pow(pow(x - xoffset, 2) + pow(y - yoffset, 2) +1,2)); r += f_h*IMap[(4*(y*recordWidth + x))]; g += f_h*IMap[(4*(y*recordWidth + x)) + 1]; b += f_h*IMap[(4*(y*recordWidth + x)) + 2]; dist = IMap[(4*(y*recordWidth + x)) + 3]; if(fabs(dist) < .0001) {} else hmdsum += 1.0/dist; } } float hmd = (recordWidth*recordWidth)/hmdsum; //std::cout << "sum: " << r << ' ' << g << ' ' << b << std::endl; //std::cout << "hmd: " << hmd << std::endl; if (hmdsum < .0001 || (r < .0001 && g < .0001 && b < .0001)) { glIsTexture(999); return; } rec.pos[0] = pos[0]; rec.pos[1] = pos[1]; rec.pos[2] = pos[2]; rec.norm[0] = normal[0]; rec.norm[1] = normal[1]; rec.norm[2] = normal[2]; rec.transGrad[0] = 0; rec.transGrad[1] = 0; rec.transGrad[2] = 0; rec.rotGrad[0] = 0; rec.rotGrad[1] = 0; rec.rotGrad[2] = 0; rec.irradiance[0] = r; rec.irradiance[1] = g; rec.irradiance[2] = b; rec.hmd = hmd; records.push_back(rec); glIsShader(999); }
void FrameBufferObject::Init( GraphicsState & glstate, const std::vector <FrameBufferTexture*> & newtextures, std::ostream & error_output, bool force_multisample_off) { CheckForOpenGLErrors("FBO init start", error_output); const bool verbose = false; if (inited) { if (verbose) error_output << "INFO: deinitializing existing FBO" << std::endl; DeInit(); CheckForOpenGLErrors("FBO deinit", error_output); } inited = true; // need at least some textures assert(!newtextures.empty()); textures = newtextures; width = -1; height = -1; std::vector <FrameBufferTexture*> color_textures; FrameBufferTexture * depth_texture = 0; for (std::vector <FrameBufferTexture*>::const_iterator i = textures.begin(); i != textures.end(); i++) { // ensure consistent sizes if (width == -1) width = (*i)->GetW(); if (height == -1) height = (*i)->GetH(); assert(width == int((*i)->GetW())); assert(height == int((*i)->GetH())); // separate textures by type if ((*i)->GetFormat() == FrameBufferTexture::DEPTH24) { // can't have more than one depth attachment assert(!depth_texture); depth_texture = *i; } else { color_textures.push_back(*i); } } if (verbose) error_output << "INFO: width " << width << ", height " << height << std::endl; if (verbose) error_output << "INFO: color textures: " << color_textures.size() << std::endl; if (verbose && depth_texture) error_output << "INFO: depth texture: 1" << std::endl; // can't have more than 4 color attachments assert(color_textures.size() < 5); // check for cubemaps for (std::vector <FrameBufferTexture*>::const_iterator i = color_textures.begin(); i != color_textures.end(); i++) { if ((*i)->GetTarget() == FrameBufferTexture::CUBEMAP) { if (verbose) error_output << "INFO: found cubemap" << std::endl; // can't have MRT with cubemaps assert(color_textures.size() == 1); // can't have multisample with cubemaps assert((*i)->GetMultiSample() == 0); // can't have depth texture with cubemaps assert(!depth_texture); } } // find what multisample value to use int multisample = 0; if (!color_textures.empty()) { multisample = -1; for (std::vector <FrameBufferTexture*>::const_iterator i = textures.begin(); i != textures.end(); i++) { if (multisample == -1) multisample = (*i)->GetMultiSample(); // all must have the same multisample assert(multisample == (*i)->GetMultiSample()); } } if (verbose) error_output << "INFO: multisample " << multisample << " found, " << force_multisample_off << std::endl; if (force_multisample_off) multisample = 0; // either we have no multisample or multisample and no depth texture assert((multisample == 0) || ((multisample > 0) && depth_texture)); // initialize framebuffer object glGenFramebuffers(1, &framebuffer_object); if (verbose) error_output << "INFO: generated FBO " << framebuffer_object << std::endl; CheckForOpenGLErrors("FBO generation", error_output); // bind framebuffer glstate.BindFramebuffer(GL_FRAMEBUFFER, framebuffer_object); CheckForOpenGLErrors("FBO binding", error_output); if (!depth_texture) { // create depth render buffer if we're not using a depth texture glGenRenderbuffers(1, &depth_renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer); if (verbose) error_output << "INFO: generating depth renderbuffer" << std::endl; CheckForOpenGLErrors("FBO renderbuffer generation", error_output); if (multisample > 0) { glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisample, GL_DEPTH_COMPONENT, width, height); if (verbose) error_output << "INFO: using multisampling for depth renderbuffer" << std::endl; } else { glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); } CheckForOpenGLErrors("FBO renderbuffer initialization", error_output); // attach depth render buffer to the FBO glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_renderbuffer); if (verbose) error_output << "INFO: depth renderbuffer attached to FBO" << std::endl; CheckForOpenGLErrors("FBO renderbuffer attachment", error_output); } if (multisample > 0) { // create/attach separate multisample color buffers for each color texture multisample_renderbuffers.resize(color_textures.size(), 0); for (size_t i = 0; i < color_textures.size(); i++) { glGenRenderbuffers(1, &multisample_renderbuffers[i]); glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffers[i]); glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisample, color_textures[i]->GetFormat(), width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, multisample_renderbuffers[i]); if (verbose) error_output << "INFO: generating separate multisample color buffer " << i << std::endl; CheckForOpenGLErrors("FBO multisample color renderbuffer", error_output); } } else { // attach color textures to frame buffer object int count = 0; for (std::vector <FrameBufferTexture*>::iterator i = color_textures.begin(); i != color_textures.end(); i++, count++) { int attachment = GL_COLOR_ATTACHMENT0 + count; if ((*i)->GetTarget() == FrameBufferTexture::CUBEMAP) { // if we're using a cubemap, arbitrarily pick one of the faces to activate so we can check that the FBO is complete glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X, (*i)->GetId(), 0); if (verbose) error_output << "INFO: attaching arbitrary cubemap face to color attachment " << count << std::endl; } else { glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, (*i)->GetTarget(), (*i)->GetId(), 0); if (verbose) error_output << "INFO: attaching texture to color attachment " << count << std::endl; } (*i)->SetAttachment(attachment); CheckForOpenGLErrors("FBO attachment", error_output); } if (depth_texture) { // attach depth texture to frame buffer object glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture->GetTarget(), depth_texture->GetId(), 0); depth_texture->SetAttachment(GL_DEPTH_ATTACHMENT); if (verbose) error_output << "INFO: attaching depth texture" << std::endl; CheckForOpenGLErrors("FBO attachment", error_output); } } GLenum buffers[4] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE}; { int count = 0; for (std::vector <FrameBufferTexture*>::const_iterator i = color_textures.begin(); i != color_textures.end(); i++, count++) { buffers[count] = GL_COLOR_ATTACHMENT0 + count; } glDrawBuffers(count, buffers); glReadBuffer(buffers[0]); CheckForOpenGLErrors("FBO buffer mask set", error_output); } if (verbose) error_output << "INFO: set draw buffers: " << buffers[0] << ", " << buffers[1] << ", " << buffers[2] << ", " << buffers[3] << std::endl; if (verbose) error_output << "INFO: set read buffer: " << buffers[0] << std::endl; if (!CheckStatus(error_output)) { error_output << "Error initializing FBO:" << std::endl; int count = 0; for (std::vector <FrameBufferTexture*>::const_iterator i = textures.begin(); i != textures.end(); i++) { error_output << "\t" << count << ". " << TargetToString(FrameBufferTexture::Target((*i)->GetTarget())); error_output << ": " << FormatToString((*i)->GetFormat()) << std::endl; count++; } assert(0); } // explicitely unbind framebuffer object glstate.BindFramebuffer(GL_FRAMEBUFFER, 0); CheckForOpenGLErrors("FBO unbinding", error_output); // if multisampling is on, create another framebuffer object for the single sample version of these textures if (multisample > 0) { if (verbose) error_output << "INFO: creating secondary single sample framebuffer object" << std::endl; assert(!singlesample_framebuffer_object); singlesample_framebuffer_object = new FrameBufferObject(); singlesample_framebuffer_object->Init(glstate, newtextures, error_output, true); } }
void EDA_3D_CANVAS::create_and_render_shadow_buffer( GLuint *aDst_gl_texture, GLuint aTexture_size, bool aDraw_body, int aBlurPasses ) { glDisable( GL_TEXTURE_2D ); glViewport( 0, 0, aTexture_size, aTexture_size); glClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Render body and shapes if( aDraw_body && m_glLists[GL_ID_BODY] ) glCallList( m_glLists[GL_ID_BODY] ); if( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] ) glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] ); // Create and Initialize the float depth buffer float *depthbufferFloat = (float*) malloc( aTexture_size * aTexture_size * sizeof(float) ); for( unsigned int i = 0; i < (aTexture_size * aTexture_size); i++ ) depthbufferFloat[i] = 1.0f; glPixelStorei( GL_PACK_ALIGNMENT, 4 ); glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); glReadBuffer( GL_BACK_LEFT ); glReadPixels( 0, 0, aTexture_size, aTexture_size, GL_DEPTH_COMPONENT, GL_FLOAT, depthbufferFloat ); CheckGLError( __FILE__, __LINE__ ); glEnable( GL_TEXTURE_2D ); glGenTextures( 1, aDst_gl_texture ); glBindTexture( GL_TEXTURE_2D, *aDst_gl_texture ); CIMAGE imgDepthBuffer( aTexture_size, aTexture_size ); CIMAGE imgDepthBufferAux( aTexture_size, aTexture_size ); imgDepthBuffer.SetPixelsFromNormalizedFloat( depthbufferFloat ); free( depthbufferFloat ); // Debug texture image //wxString filename; //filename.Printf( "imgDepthBuffer_%04d", *aDst_gl_texture ); //imgDepthBuffer.SaveAsPNG( filename ); while( aBlurPasses > 0 ) { aBlurPasses--; imgDepthBufferAux.EfxFilter( &imgDepthBuffer, FILTER_GAUSSIAN_BLUR ); imgDepthBuffer.EfxFilter( &imgDepthBufferAux, FILTER_GAUSSIAN_BLUR ); } // Debug texture image //filename.Printf( "imgDepthBuffer_blur%04d", *aDst_gl_texture ); //imgDepthBuffer.SaveAsPNG( filename ); unsigned char *depthbufferRGBA = (unsigned char*) malloc( aTexture_size * aTexture_size * 4 ); unsigned char *pPixels = imgDepthBuffer.GetBuffer(); // Convert it to a RGBA buffer for( unsigned int i = 0; i < (aTexture_size * aTexture_size); i++ ) { depthbufferRGBA[i * 4 + 0] = 0; depthbufferRGBA[i * 4 + 1] = 0; depthbufferRGBA[i * 4 + 2] = 0; depthbufferRGBA[i * 4 + 3] = 255 - pPixels[i]; // Store in alpha channel the inversion of the image } glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aTexture_size, aTexture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, depthbufferRGBA ); free( depthbufferRGBA ); CheckGLError( __FILE__, __LINE__ ); }
bool RenderToFrameBuffer::Init(const structRenderTargetInfo & rttInfo) { // Setup our FBO glGenFramebuffersEXT(1, &m_fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); if ((rttInfo.fSuperSample > 0 || rttInfo.bPhysicalScreen) && rttInfo.iWidthSS > 0 && rttInfo.iHeightSS > 0) { m_iWidth = (int)((float)rttInfo.iWidthSS * rttInfo.fSuperSample + 0.5f); m_iHeight = (int)((float)rttInfo.iHeightSS * rttInfo.fSuperSample + 0.5f); } else { m_iWidth = rttInfo.iWidth; m_iHeight = rttInfo.iHeight; } bool bCoverage = false; if ((rttInfo.iMultiSample > 0) && RenderToFrameBuffer::IsAvailable()/*[2]*/) { m_iMultiSample = rttInfo.iMultiSample; if (m_iMultiSample > MAX_AAModes) m_iMultiSample = MAX_AAModes; // coverage supported ? // if (glRenderbufferStorageMultisampleCoverageNV) // bCoverage = true; // else bCoverage = false; } else m_iMultiSample = 0; int ds = 0; int cs = 0; if (m_iMultiSample > 0) { ds = g_AAModes[m_iMultiSample-1].ds; cs = bCoverage ? g_AAModes[m_iMultiSample-1].cs : 0; } if (rttInfo.eFormat != GL_DEPTH_COMPONENT) { // Create the render buffer for depth glGenRenderbuffersEXT(1, &m_depthBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); GLenum internalFormat = rttInfo.bStencil ? GL_DEPTH24_STENCIL8_EXT : GL_DEPTH_COMPONENT; if (m_iMultiSample > 0) { glGenFramebuffersEXT(1, &m_fboMS); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboMS); if (cs==0) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, ds, internalFormat, m_iWidth, m_iHeight); // check the number of samples GLint qds = 0; glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &qds); if (qds < ds) { Clean(); return false; } } else { // glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, cs, ds, internalFormat, m_iWidth, m_iHeight); // check the number of samples GLint qds = 0; GLint qcs = 0; glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &qcs); glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &qds); if ((qcs < cs) || (qds < ds)) { Clean(); return false; } } } else glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, m_iWidth, m_iHeight); // Attach the depth render buffer to the FBO as it's depth attachment glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); if (rttInfo.bStencil) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); if (m_iMultiSample > 0) { glGenRenderbuffersEXT(1, &m_colorMS); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_colorMS); if (cs==0) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, ds, GL_RGBA8, m_iWidth, m_iHeight); // check the number of samples GLint qds = 0; glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &qds); if (qds < ds) { Clean(); return false; } } else { // glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, cs, ds, GL_RGBA8, m_iWidth, m_iHeight); // check the number of samples GLint qds = 0; GLint qcs = 0; glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &qcs); glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &qds); if ((qcs < cs) || (qds < ds)) { Clean(); return false; } } // attach the multisampled color buffer glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_colorMS); } } else { // The following is REQUIRED or the FBO will not be resolved (since we have no color buffer here) // Also note that these states are only valid for the FBO state, so can be done once during init glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } m_eFormat = rttInfo.eFormat; m_eType = rttInfo.eType; m_iFiltering = rttInfo.iFiltering; m_bMipMap = RenderToFrameBuffer::IsAvailable()/*[1]*/ && rttInfo.bMipMap; m_bBindDepth = rttInfo.m_bBindDepth; m_bInitialized = true; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind the FBO for now return true; }
////////////////////////////////////////////////////////////////////// // readback // // Code to handle reading back of the FBO data (but with a specified FBO pointer) // ////////////////////////////////////////////////////////////////////// bool CheckBackBuffer::readback( GLuint width, GLuint height, GLuint bufObject ) { bool ret = false; if (m_bUseFBO) { if (m_bUsePBO) { shrLog("CheckBackBuffer::readback() FBO->PBO->m_pImageData\n"); // binds the PBO for readback bindReadback(); // bind FBO buffer (we want to transfer FBO -> PBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufObject ); // Now initiate the readback to PBO glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)); ret = checkStatus(__FILE__, __LINE__, true); if (!ret) shrLog("CheckBackBuffer::readback() FBO->PBO checkStatus = %d\n", ret); // map - unmap simulates readback without the copy void *ioMem = glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); memcpy(m_pImageData, ioMem, width*height*m_Bpp); glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release the FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // release the PBO unbindReadback(); } else { shrLog("CheckBackBuffer::readback() FBO->m_pImageData\n"); // Reading direct to FBO using glReadPixels glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, bufObject ); ret = checkStatus(__FILE__, __LINE__, true); if (!ret) shrLog("CheckBackBuffer::readback::glBindFramebufferEXT() fbo=%d checkStatus = %d\n", bufObject, ret); glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT)); ret &= checkStatus(__FILE__, __LINE__, true); if (!ret) shrLog("CheckBackBuffer::readback::glReadBuffer() fbo=%d checkStatus = %d\n", bufObject, ret); glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } } else { shrLog("CheckBackBuffer::readback() PBO->m_pImageData\n"); // read from bufObject (PBO) to system memorys image glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, bufObject); // Bind the PBO // map - unmap simulates readback without the copy void *ioMem = glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); // allocate a buffer so we can flip the image unsigned char * temp_buf = (unsigned char *)malloc(width*height*m_Bpp); memcpy( temp_buf, ioMem, width*height*m_Bpp ); // let's flip the image as we copy for (unsigned int y = 0; y < height; y++) { memcpy( (void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(temp_buf[y*width*m_Bpp]), width*m_Bpp); } free(temp_buf); glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // read from bufObject (PBO) to system memory image glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); // unBind the PBO } return CHECK_FBO; }
GLenum getSnapshot(u8 *buf) { glReadBuffer(GL_FRONT); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buf); return glGetError(); }
int _tmain(int argc, _TCHAR* argv[]) { GLFWwindow* window = 0; glfwSetErrorCallback(glfw_error_callback_func); // Initialise GLFW if (!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); getchar(); return -1; } //----------------------------------------------------------------------------- glfwWindowHint(GLFW_SAMPLES, 4); // GL3.3 Core profile glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_VISIBLE, 0); //オフスクリーン // Open a window and create its OpenGL context window = glfwCreateWindow(1, 1, "GPGPU Test", NULL, NULL); if (window == NULL){ fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); getchar(); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); #if defined _WIN32 // Initialize GLEW glewExperimental = GL_TRUE; ///!!!! important for core profile // コアプロファイルで必要となります if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); getchar(); glfwTerminate(); return -1; } #endif { cout << "GL_VENDOR:" << glGetString(GL_VENDOR) << endl; cout << "GL_RENDERER:" << glGetString(GL_RENDERER) << endl; cout << "GL_VERSION:" << glGetString(GL_VERSION) << endl; cout << "GL_SHADING_LANGUAGE_VERSION:" << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; } #ifdef _DEBUG Mat imgSrc = Mat(Size(8, 4), CV_32FC1); #else Mat imgSrc = Mat(Size(1024, 1024), CV_32FC1); #endif Mat imgDst = Mat::zeros(imgSrc.size(), imgSrc.type()); Mat imgRef = Mat::zeros(imgSrc.size(), imgSrc.type()); //世代 #ifdef _DEBUG const int generations = 1; // const int generations = 3; #else const int generations = 1000; #endif { cout << "Cell Size:" << imgSrc.size() << endl; cout << "generations:" << generations << endl; } //--------------------------------- //init Src image initCellLife(imgSrc); //--------------------------------- //Execute GPGPU { cout << "Execute GPGPU" << endl; const int width = imgSrc.cols; const int height = imgSrc.rows; // Create and compile our GLSL program from the shaders GLuint programID = LoadShaders("LifeGame.vertexshader", "LifeGameUpdate.fragmentshader"); // texture enum E_TextureID{ SRC, DST, SIZEOF, }; unsigned int textureID[E_TextureID::SIZEOF]; //src dst //--------------------------------- // CreateTexture { GLenum format = GL_RED; //single channel GLenum type = GL_FLOAT; //float GLenum internalFormat = GL_R32F; //single channel float glGenTextures(sizeof(textureID) / sizeof(textureID[0]), textureID); // create (reference to) a new texture for (int i = 0; i < sizeof(textureID) / sizeof(textureID[0]); i++){ glBindTexture(GL_TEXTURE_2D, textureID[i]); // (set texture parameters here) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #ifdef LIFE_BOUND_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); #else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); #endif //create the texture glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, 0); glBindTexture(GL_TEXTURE_2D, 0); } } //upload imgSrc to texture { //Timer tmr("upload:"); GLenum format = GL_RED; //single channel GLenum type = GL_FLOAT; //float void* data = imgSrc.data; glBindTexture(GL_TEXTURE_2D, textureID[E_TextureID::SRC]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data); glBindTexture(GL_TEXTURE_2D, 0); } // FBO identifier GLuint fbo = 0; //--------------------------------- // FBO // create FBO (off-screen framebuffer) glGenFramebuffers(1, &fbo); // bind offscreen framebuffer (that is, skip the window-specific render target) // glBindFramebuffer(GL_FRAMEBUFFER, fbo); //Execute { Timer tmr("LifeGame@gpu:"); for (int i = 0; i < generations; i++){ GLuint texSrc = textureID[(i % 2)]; GLuint texDst = textureID[(i % 2) ^ 1]; executeGpGpuProcess(programID, fbo, texSrc, texDst); } } { //download from framebuffer //Timer tmr("download:"); GLenum format = GL_RED; //single channel GLenum type = GL_FLOAT; //float void* data = imgDst.data; int width = imgDst.cols; int height = imgDst.rows; //wait for Rendering glFinish(); // ReadBuffer glReadBuffer(GL_COLOR_ATTACHMENT0); // ReadPixels glReadPixels(0, 0, width, height, format, type, data); } //clean up glDeleteTextures(sizeof(textureID) / sizeof(textureID[0]), textureID); glDeleteFramebuffers(1, &fbo); glDeleteProgram(programID); } //--------------------------------- //Execute CPU { cout << "Execute CPU" << endl; Mat imgBank[2] = { Mat::zeros(imgSrc.size(), imgSrc.type()), Mat::zeros(imgSrc.size(), imgSrc.type()) }; int bank = 0; imgBank[bank] = imgSrc.clone(); { Timer tmr("LifeGame@cpu:"); for (int i = 0; i < generations; i++){ updateCellLife(imgBank[bank], imgBank[bank ^ 1]); bank = bank ^ 1; } } imgRef = imgBank[bank].clone(); } #ifdef _DEBUG //dump { cout << "imgSrc" << endl; cout << imgSrc << endl; cout << "imgDst" << endl; cout << imgDst << endl; cout << "imgRef" << endl; cout << imgRef << endl; } #endif //verify int errNum = 0; { //verify int width = imgSrc.cols; int height = imgSrc.rows; for (int y = 0; y < height; y++){ for (int x = 0; x < width; x++){ float ref = imgRef.at<float>(y, x); float dst = imgDst.at<float>(y, x); if (ref != dst) errNum++; } } cout << "ErrNum:" << errNum << endl; } #if 0 //visualize { imshow("src", imgSrc); imshow("dst", imgDst); imshow("ref", imgRef); waitKey(); } #endif // Close OpenGL window and terminate GLFW glfwTerminate(); cout << "Hit return key" << endl; cin.get(); return errNum; }
void Rasterizer::getRayTraceData(int *count, Eigen::Vector3f **positions, Eigen::Vector3f **normals) { *count = 0; std::vector<int> frag_idx; if (!this->pbo_positions[0]) { int size = this->prepass_height * this->prepass_width; #ifdef USE_PBOS size *= sizeof(float); glGenBuffers(2, this->pbo_positions); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_positions[0]); glBufferData(GL_PIXEL_PACK_BUFFER, size*3, NULL, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_positions[1]); glBufferData(GL_PIXEL_PACK_BUFFER, size*3, NULL, GL_STREAM_READ); glGenBuffers(2, this->pbo_normals); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_normals[0]); glBufferData(GL_PIXEL_PACK_BUFFER, size*4, NULL, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_normals[1]); glBufferData(GL_PIXEL_PACK_BUFFER, size*4, NULL, GL_STREAM_READ); #else this->prepass_color0_buffer = new float[size*4]; this->prepass_color1_buffer = new float[size*3]; #endif } glBindFramebuffer(GL_FRAMEBUFFER, this->fbo_prepass); #ifdef USE_PBOS glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_normals[this->frame_toggle]); glReadBuffer(GL_COLOR_ATTACHMENT0); glReadPixels(0, 0, this->prepass_width, this->prepass_height, GL_RGBA, GL_FLOAT, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_normals[this->frame_toggle ^ 1]); this->prepass_color0_buffer = (float*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (!this->prepass_color0_buffer) { fprintf(stderr, "Error mapping Color0 Buffer\n"); return; } #else glReadBuffer(GL_COLOR_ATTACHMENT0); glReadPixels(0, 0, this->prepass_width, this->prepass_height, GL_RGBA, GL_FLOAT, this->prepass_color0_buffer); #endif int line_number = 0; for (int i = 0; i < this->prepass_width * this->prepass_height; i++) { if (this->prepass_color0_buffer[i*4 +3] > 0.0f) { frag_idx.push_back(i); } #ifdef INTERLEAVE if (i%this->prepass_width == 0) { line_number++; if (line_number%2 == this->frame_toggle) i += this->prepass_width; } #endif } *count = frag_idx.size(); *positions = this->position_transfer_buffer; *normals = this->normal_transfer_buffer; int idx; for (int i = 0; i < *count; i++) { idx = frag_idx[i]; (*normals)[i][0] = this->prepass_color0_buffer[idx*4 + 0] * 2.0 - 1.0; (*normals)[i][1] = this->prepass_color0_buffer[idx*4 + 1] * 2.0 - 1.0; (*normals)[i][2] = this->prepass_color0_buffer[idx*4 + 2] * 2.0 - 1.0; } #ifdef USE_PBOS glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_positions[this->frame_toggle]); glReadBuffer(GL_COLOR_ATTACHMENT1); glReadPixels(0, 0, this->prepass_width, this->prepass_height, GL_RGB, GL_FLOAT, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, this->pbo_positions[this->frame_toggle^1]); this->prepass_color1_buffer = (float*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); #else glReadBuffer(GL_COLOR_ATTACHMENT1); glReadPixels(0, 0, this->prepass_width, this->prepass_height, GL_RGB, GL_FLOAT, this->prepass_color1_buffer); #endif if (!this->prepass_color1_buffer) { fprintf(stderr, "Error mapping Color1 Buffer\n"); return; } for (int i = 0; i < *count; i++) { idx = frag_idx[i]; (*positions)[i][0] = this->prepass_color1_buffer[idx*3 + 0]; (*positions)[i][1] = this->prepass_color1_buffer[idx*3 + 1]; (*positions)[i][2] = this->prepass_color1_buffer[idx*3 + 2]; } #ifdef USE_PBOS glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); #endif glBindFramebuffer(GL_FRAMEBUFFER, 0); }
int YabSaveState(const char *filename) { u32 i; FILE *fp; int offset; IOCheck_struct check; u8 *buf; int totalsize; int outputwidth; int outputheight; int movieposition; int temp; u32 temp32; check.done = 0; check.size = 0; //use a second set of savestates for movies filename = MakeMovieStateName(filename); if (!filename) return -1; if ((fp = fopen(filename, "wb")) == NULL) return -1; // Write signature fprintf(fp, "YSS"); // Write endianness byte #ifdef WORDS_BIGENDIAN fputc(0x00, fp); #else fputc(0x01, fp); #endif // Write version(fix me) i = 2; ywrite(&check, (void *)&i, sizeof(i), 1, fp); // Skip the next 4 bytes for now i = 0; ywrite(&check, (void *)&i, sizeof(i), 1, fp); //write frame number ywrite(&check, (void *)&framecounter, 4, 1, fp); //this will be updated with the movie position later ywrite(&check, (void *)&framecounter, 4, 1, fp); // Go through each area and write each state i += CartSaveState(fp); i += Cs2SaveState(fp); i += SH2SaveState(MSH2, fp); i += SH2SaveState(SSH2, fp); i += SoundSaveState(fp); i += ScuSaveState(fp); i += SmpcSaveState(fp); i += Vdp1SaveState(fp); i += Vdp2SaveState(fp); offset = StateWriteHeader(fp, "OTHR", 1); // Other data ywrite(&check, (void *)BupRam, 0x10000, 1, fp); // do we really want to save this? ywrite(&check, (void *)HighWram, 0x100000, 1, fp); ywrite(&check, (void *)LowWram, 0x100000, 1, fp); ywrite(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); ywrite(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); ywrite(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); ywrite(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); temp = yabsys.DecilineStop >> YABSYS_TIMING_BITS; ywrite(&check, (void *)&temp, sizeof(int), 1, fp); temp = (yabsys.CurSH2FreqType == CLKTYPE_26MHZ) ? 268 : 286; ywrite(&check, (void *)&temp, sizeof(int), 1, fp); temp32 = (yabsys.UsecFrac * temp / 10) >> YABSYS_TIMING_BITS; ywrite(&check, (void *)&temp32, sizeof(u32), 1, fp); ywrite(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); ywrite(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); VIDCore->GetGlSize(&outputwidth, &outputheight); totalsize=outputwidth * outputheight * sizeof(u32); if ((buf = (u8 *)malloc(totalsize)) == NULL) { return -2; } YuiSwapBuffers(); #ifdef USE_OPENGL glPixelZoom(1,1); glReadBuffer(GL_BACK); glReadPixels(0, 0, outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); #endif YuiSwapBuffers(); ywrite(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); ywrite(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); ywrite(&check, (void *)buf, totalsize, 1, fp); movieposition=ftell(fp); //write the movie to the end of the savestate SaveMovieInState(fp, check); i += StateFinishHeader(fp, offset); // Go back and update size fseek(fp, 8, SEEK_SET); ywrite(&check, (void *)&i, sizeof(i), 1, fp); fseek(fp, 16, SEEK_SET); ywrite(&check, (void *)&movieposition, sizeof(movieposition), 1, fp); fclose(fp); OSDPushMessage(OSDMSG_STATUS, 150, "STATE SAVED"); return 0; }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; unsigned long mask; unsigned int current_DisplayMode = fgState.DisplayMode ; /* Save the display mode if we are creating a menu window */ if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; window->Window.VisualInfo = fgChooseVisual( ); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; if( ! window->Window.VisualInfo ) { /* * The "fgChooseVisual" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode &= ~GLUT_DOUBLE; } /* * GLUT also checks for multi-sampling, but I don't see that * anywhere else in FREEGLUT so I won't bother with it for the moment. */ } FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL, "Visual with necessary capabilities not found", "fgOpenWindow" ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.Display, fgDisplay.RootWindow, window->Window.VisualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu || ( gameMode == GL_TRUE ) ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } window->Window.Handle = XCreateWindow( fgDisplay.Display, window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, window->Window.VisualInfo->depth, InputOutput, window->Window.VisualInfo->visual, mask, &winAttr ); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateContext( fgDisplay.Display, fgStructure.MenuContext->VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } /* window->Window.Context = fgStructure.MenuContext->Context; */ window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else if( fgState.UseCurrentContext ) { window->Window.Context = glXGetCurrentContext( ); if( ! window->Window.Context ) window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); #if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) if( !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", title ); } #endif /* * XXX Assume the new window is visible by default * XXX Is this a safe assumption? */ window->State.Visible = GL_TRUE; sizeHints.flags = 0; if ( fgState.Position.Use ) sizeHints.flags |= USPosition; if ( fgState.Size.Use ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolete, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XFree( textProperty.value ); XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); XMapWindow( fgDisplay.Display, window->Window.Handle ); #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE WNDCLASS wc; DWORD flags; DWORD exFlags = 0; ATOM atom; /* Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found", "fgOpenWindow" ); if( gameMode ) { FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL, "Game mode being invoked on a subwindow", "fgOpenWindow" ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { #if !TARGET_HOST_WINCE if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* * Update the window dimensions, taking account of window * decorations. "freeglut" is to create the window with the * outside of its border at (x,y) and with dimensions (w,h). */ w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } #endif /* TARGET_HOST_WINCE */ if( ! fgState.Position.Use ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( ! fgState.Size.Use ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } /* * There's a small difference between creating the top, child and * game mode windows */ flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if !TARGET_HOST_WINCE else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif else flags |= WS_CHILD; } #if TARGET_HOST_WINCE { wchar_t* wstr = fghWstrFromStr(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowEx( exFlags, "FREEGLUT", title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.Instance, (LPVOID) window ); #endif /* TARGET_HOST_WINCE */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if TARGET_HOST_WINCE ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ #endif fgSetWindow( window ); window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0; if ( ! window->Window.DoubleBuffered ) { glDrawBuffer ( GL_FRONT ); glReadBuffer ( GL_FRONT ); } }
void R_InitFBOs(void) { int i; int width, height; Ren_Developer("------- R_InitFBOs -------\n"); if (!glConfig2.framebufferObjectAvailable) { return; } R_CheckDefaultBuffer(); tr.numFBOs = 0; GL_CheckErrors(); // make sure the render thread is stopped R_IssuePendingRenderCommands(); if (DS_STANDARD_ENABLED()) { // geometricRender FBO as G-Buffer for deferred shading Ren_Developer("Deferred Shading enabled\n"); if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth; height = glConfig.vidHeight; } else { width = NearestPowerOfTwo(glConfig.vidWidth); height = NearestPowerOfTwo(glConfig.vidHeight); } tr.geometricRenderFBO = R_CreateFBO("_geometricRender", width, height); R_BindFBO(tr.geometricRenderFBO); #if 0 if (glConfig2.framebufferPackedDepthStencilAvailable) { R_CreateFBOPackedDepthStencilBuffer(tr.geometricRenderFBO, GL_DEPTH24_STENCIL8); R_AttachFBOTexturePackedDepthStencil(tr.depthRenderImage->texnum); } else if (glConfig.hardwareType == GLHW_ATI || glConfig.hardwareType == GLHW_ATI_DX10) // || glConfig.hardwareType == GLHW_NV_DX10) { R_CreateFBODepthBuffer(tr.geometricRenderFBO, GL_DEPTH_COMPONENT16_ARB); R_AttachFBOTextureDepth(tr.depthRenderImage->texnum); } else #endif { R_CreateFBODepthBuffer(tr.geometricRenderFBO, GL_DEPTH_COMPONENT24_ARB); R_AttachFBOTextureDepth(tr.depthRenderImage->texnum); } // enable all attachments as draw buffers //glDrawBuffersARB(4, geometricRenderTargets); R_CreateFBOColorBuffer(tr.geometricRenderFBO, GL_RGBA, 0); R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.deferredRenderFBOImage->texnum, 0); R_CreateFBOColorBuffer(tr.geometricRenderFBO, GL_RGBA, 1); R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.deferredDiffuseFBOImage->texnum, 1); R_CreateFBOColorBuffer(tr.geometricRenderFBO, GL_RGBA, 2); R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.deferredNormalFBOImage->texnum, 2); R_CreateFBOColorBuffer(tr.geometricRenderFBO, GL_RGBA, 3); R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.deferredSpecularFBOImage->texnum, 3); R_CheckFBO(tr.geometricRenderFBO); } else { // forward shading if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth; height = glConfig.vidHeight; } else { width = NearestPowerOfTwo(glConfig.vidWidth); height = NearestPowerOfTwo(glConfig.vidHeight); } // deferredRender FBO for the HDR or LDR context tr.deferredRenderFBO = R_CreateFBO("_deferredRender", width, height); R_BindFBO(tr.deferredRenderFBO); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.deferredRenderFBO, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.deferredRenderFBO, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.deferredRenderFBOImage->texnum, 0); #if 0 if (glConfig2.framebufferPackedDepthStencilAvailable) { R_CreateFBOPackedDepthStencilBuffer(tr.deferredRenderFBO, GL_DEPTH24_STENCIL8); R_AttachFBOTexturePackedDepthStencil(tr.depthRenderImage->texnum); } else if (glConfig.hardwareType == GLHW_ATI || glConfig.hardwareType == GLHW_ATI_DX10) // || glConfig.hardwareType == GLHW_NV_DX10) { R_CreateFBODepthBuffer(tr.deferredRenderFBO, GL_DEPTH_COMPONENT16_ARB); R_AttachFBOTextureDepth(tr.depthRenderImage->texnum); } else #endif { R_CreateFBODepthBuffer(tr.deferredRenderFBO, GL_DEPTH_COMPONENT24_ARB); R_AttachFBOTextureDepth(tr.depthRenderImage->texnum); } R_CheckFBO(tr.deferredRenderFBO); } if (glConfig2.framebufferBlitAvailable) { if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth; height = glConfig.vidHeight; } else { width = NearestPowerOfTwo(glConfig.vidWidth); height = NearestPowerOfTwo(glConfig.vidHeight); } tr.occlusionRenderFBO = R_CreateFBO("_occlusionRender", width, height); R_BindFBO(tr.occlusionRenderFBO); if (glConfig.hardwareType == GLHW_ATI_DX10) { //R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA16F_ARB, 0); R_CreateFBODepthBuffer(tr.occlusionRenderFBO, GL_DEPTH_COMPONENT16_ARB); } else if (glConfig.hardwareType == GLHW_NV_DX10) { //R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA32F_ARB, 0); R_CreateFBODepthBuffer(tr.occlusionRenderFBO, GL_DEPTH_COMPONENT24_ARB); } else if (glConfig2.framebufferPackedDepthStencilAvailable) { //R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA32F_ARB, 0); R_CreateFBOPackedDepthStencilBuffer(tr.occlusionRenderFBO, GL_DEPTH24_STENCIL8); } else { //R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_RGBA, 0); R_CreateFBODepthBuffer(tr.occlusionRenderFBO, GL_DEPTH_COMPONENT24_ARB); } R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_RGBA, 0); R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.occlusionRenderFBOImage->texnum, 0); R_CheckFBO(tr.occlusionRenderFBO); } if (r_shadows->integer >= SHADOWING_ESM16 && glConfig2.textureFloatAvailable) { // shadowMap FBOs for shadow mapping offscreen rendering for (i = 0; i < MAX_SHADOWMAPS; i++) { width = height = shadowMapResolutions[i]; tr.shadowMapFBO[i] = R_CreateFBO(va("_shadowMap%d", i), width, height); R_BindFBO(tr.shadowMapFBO[i]); if ((glConfig.driverType == GLDRV_OPENGL3) || (glConfig.hardwareType == GLHW_NV_DX10 || glConfig.hardwareType == GLHW_ATI_DX10)) { if (r_shadows->integer == SHADOWING_ESM32) { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_ALPHA32F_ARB, 0); } else if (r_shadows->integer == SHADOWING_VSM32) { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_LUMINANCE_ALPHA32F_ARB, 0); } else if (r_shadows->integer == SHADOWING_EVSM32) { if (r_evsmPostProcess->integer) { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_ALPHA32F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_RGBA32F_ARB, 0); } } else { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_RGBA16F_ARB, 0); } } else { if (r_shadows->integer == SHADOWING_ESM16) { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_ALPHA16F_ARB, 0); } else if (r_shadows->integer == SHADOWING_VSM16) { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_LUMINANCE_ALPHA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.shadowMapFBO[i], GL_RGBA16F_ARB, 0); } } R_CreateFBODepthBuffer(tr.shadowMapFBO[i], GL_DEPTH_COMPONENT24_ARB); R_CheckFBO(tr.shadowMapFBO[i]); } // sun requires different resolutions for (i = 0; i < MAX_SHADOWMAPS; i++) { width = height = sunShadowMapResolutions[i]; tr.sunShadowMapFBO[i] = R_CreateFBO(va("_sunShadowMap%d", i), width, height); R_BindFBO(tr.sunShadowMapFBO[i]); if ((glConfig.driverType == GLDRV_OPENGL3) || (glConfig.hardwareType == GLHW_NV_DX10 || glConfig.hardwareType == GLHW_ATI_DX10)) { if (r_shadows->integer == SHADOWING_ESM32) { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_ALPHA32F_ARB, 0); } else if (r_shadows->integer == SHADOWING_VSM32) { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_LUMINANCE_ALPHA32F_ARB, 0); } else if (r_shadows->integer == SHADOWING_EVSM32) { if (!r_evsmPostProcess->integer) { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_RGBA32F_ARB, 0); } } else { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_RGBA16F_ARB, 0); } } else { if (r_shadows->integer == SHADOWING_ESM16) { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_ALPHA16F_ARB, 0); } else if (r_shadows->integer == SHADOWING_VSM16) { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_LUMINANCE_ALPHA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.sunShadowMapFBO[i], GL_RGBA16F_ARB, 0); } } R_CreateFBODepthBuffer(tr.sunShadowMapFBO[i], GL_DEPTH_COMPONENT24_ARB); if (r_shadows->integer == SHADOWING_EVSM32 && r_evsmPostProcess->integer) { R_AttachFBOTextureDepth(tr.sunShadowMapFBOImage[i]->texnum); /* Since we don't have a color attachment the framebuffer will be considered incomplete. Consequently, we must inform the driver that we do not wish to render to the color buffer. We do this with a call to set the draw-buffer and read-buffer to GL_NONE: */ glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } R_CheckFBO(tr.sunShadowMapFBO[i]); } } { if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth; height = glConfig.vidHeight; } else { width = NearestPowerOfTwo(glConfig.vidWidth); height = NearestPowerOfTwo(glConfig.vidHeight); } // portalRender FBO for portals, mirrors, water, cameras et cetera tr.portalRenderFBO = R_CreateFBO("_portalRender", width, height); R_BindFBO(tr.portalRenderFBO); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.portalRenderFBO, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.portalRenderFBO, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.portalRenderImage->texnum, 0); R_CheckFBO(tr.portalRenderFBO); } { if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth * 0.25f; height = glConfig.vidHeight * 0.25f; } else { width = NearestPowerOfTwo(glConfig.vidWidth * 0.25f); height = NearestPowerOfTwo(glConfig.vidHeight * 0.25f); } tr.downScaleFBO_quarter = R_CreateFBO("_downScale_quarter", width, height); R_BindFBO(tr.downScaleFBO_quarter); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.downScaleFBO_quarter, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.downScaleFBO_quarter, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.downScaleFBOImage_quarter->texnum, 0); R_CheckFBO(tr.downScaleFBO_quarter); tr.downScaleFBO_64x64 = R_CreateFBO("_downScale_64x64", 64, 64); R_BindFBO(tr.downScaleFBO_64x64); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.downScaleFBO_64x64, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.downScaleFBO_64x64, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.downScaleFBOImage_64x64->texnum, 0); R_CheckFBO(tr.downScaleFBO_64x64); #if 0 tr.downScaleFBO_16x16 = R_CreateFBO("_downScale_16x16", 16, 16); R_BindFBO(tr.downScaleFBO_16x16); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.downScaleFBO_16x16, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.downScaleFBO_16x16, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.downScaleFBOImage_16x16->texnum, 0); R_CheckFBO(tr.downScaleFBO_16x16); tr.downScaleFBO_4x4 = R_CreateFBO("_downScale_4x4", 4, 4); R_BindFBO(tr.downScaleFBO_4x4); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.downScaleFBO_4x4, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.downScaleFBO_4x4, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.downScaleFBOImage_4x4->texnum, 0); R_CheckFBO(tr.downScaleFBO_4x4); tr.downScaleFBO_1x1 = R_CreateFBO("_downScale_1x1", 1, 1); R_BindFBO(tr.downScaleFBO_1x1); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.downScaleFBO_1x1, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.downScaleFBO_1x1, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.downScaleFBOImage_1x1->texnum, 0); R_CheckFBO(tr.downScaleFBO_1x1); #endif if (glConfig2.textureNPOTAvailable) { width = glConfig.vidWidth * 0.25f; height = glConfig.vidHeight * 0.25f; } else { width = NearestPowerOfTwo(glConfig.vidWidth * 0.25f); height = NearestPowerOfTwo(glConfig.vidHeight * 0.25f); } tr.contrastRenderFBO = R_CreateFBO("_contrastRender", width, height); R_BindFBO(tr.contrastRenderFBO); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.contrastRenderFBO, GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.contrastRenderFBO, GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.contrastRenderFBOImage->texnum, 0); R_CheckFBO(tr.contrastRenderFBO); for (i = 0; i < 2; i++) { tr.bloomRenderFBO[i] = R_CreateFBO(va("_bloomRender%d", i), width, height); R_BindFBO(tr.bloomRenderFBO[i]); if (r_hdrRendering->integer && glConfig2.textureFloatAvailable) { R_CreateFBOColorBuffer(tr.bloomRenderFBO[i], GL_RGBA16F_ARB, 0); } else { R_CreateFBOColorBuffer(tr.bloomRenderFBO[i], GL_RGBA, 0); } R_AttachFBOTexture2D(GL_TEXTURE_2D, tr.bloomRenderFBOImage[i]->texnum, 0); R_CheckFBO(tr.bloomRenderFBO[i]); } } GL_CheckErrors(); R_BindNullFBO(); }
int main() { // Setup SDL wrapper sdl::set_error_callback([](const std::string &err) { std::cout << err << std::endl; }); sdl::window window(width, height, false, "Test Renderer"); sdl::ogl_context context(window); // Setup Simple Renderer renderer::set_log_callback([](const uint32_t id, const std::string &err) { std::cout << id << " : " << std::endl; }); renderer::initialize(); renderer::clear_color(0.4f, 0.2f, 0.2f); // Load assets and shader const auto resource_path = util::get_resource_path() + "assets/"; const std::vector<std::string> models = { "test_scene.obj", }; std::vector<renderer::vertex_buffer> buffers; for(const auto &m : models) { const auto model = util::load_obj(resource_path + m); // Load meshes for(const auto &mesh : model.meshes) { const auto gl_model = util::convert_to_open_gl_mesh(mesh); renderer::vertex_buffer vbo(gl_model.mesh_data); buffers.emplace_back(std::move(vbo)); assert(buffers.back().is_valid()); } } // Shaders const std::string fullbright_shader_code_raw = util::get_contents_from_file(resource_path + "fullbright.shd"); const std::string fullbright_shader_code_preprocessed = util::hash_include_string(fullbright_shader_code_raw, {resource_path}); const auto fullbright_shd_code = renderer::shader_utils::get_shader_code_from_tagged_string(fullbright_shader_code_preprocessed); renderer::shader fullbright_shader(fullbright_shd_code.vs_code, "", fullbright_shd_code.ps_code); assert(fullbright_shader.is_valid()); const std::string forward_shader_code_raw = util::get_contents_from_file(resource_path + "forward_lighting.shd"); const std::string forward_shader_code_preprocessed = util::hash_include_string(forward_shader_code_raw, {resource_path}); const auto forward_shd_code = renderer::shader_utils::get_shader_code_from_tagged_string(forward_shader_code_preprocessed); renderer::shader forward_shader(forward_shd_code.vs_code, "", forward_shd_code.ps_code); assert(forward_shader.is_valid()); const std::string shadow_sahder_code_raw = util::get_contents_from_file(resource_path + "shadow_map.shd"); const std::string shadow_sahder_code_preprocessed = util::hash_include_string(shadow_sahder_code_raw, {resource_path}); const auto shadow_map_shd_code = renderer::shader_utils::get_shader_code_from_tagged_string(shadow_sahder_code_preprocessed); renderer::shader shadow_shader(shadow_map_shd_code.vs_code, "", shadow_map_shd_code.ps_code); assert(shadow_shader.is_valid()); const std::vector<renderer::attr_format_desc> vertex_desc = { renderer::attr_format_desc{"in_vs_position", renderer::attr_type::FLOAT3}, renderer::attr_format_desc{"in_vs_texcoord", renderer::attr_type::FLOAT2}, renderer::attr_format_desc{"in_vs_normal", renderer::attr_type::FLOAT3}, }; renderer::vertex_format vert_fmt(vertex_desc); assert(vert_fmt.is_valid()); // Texture int32_t width = 0; int32_t height = 0; const auto file_path = resource_path + "test.png"; unsigned char *image0 = SOIL_load_image(file_path.c_str(), &width, &height, 0, SOIL_LOAD_RGBA); renderer::texture test_texture0(image0, width, height); assert(test_texture0.is_valid()); SOIL_free_image_data(image0); Light_utils::create_direction_light(&lights); Light_utils::create_random_point_lights_inside_range(&lights, 5, 5); // Shadow cube map GLuint m_fbo; GLuint m_shadowMap; GLuint m_depth; const uint32_t cube_size = 2048; // Create the FBO glGenFramebuffers(1, &m_fbo); // Create the depth buffer glGenTextures(1, &m_depth); glBindTexture(GL_TEXTURE_2D, m_depth); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 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); // Create the cube map glGenTextures(1, &m_shadowMap); glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowMap); 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); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); for (uint i = 0 ; i < 6 ; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, cube_size, cube_size, 0, GL_RED, GL_FLOAT, NULL); } glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depth, 0); // Disable writes to the color buffer glDrawBuffer(GL_NONE); // Disable reads from the color buffer glReadBuffer(GL_NONE); GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (Status != GL_FRAMEBUFFER_COMPLETE) { printf("FB error, status: 0x%x\n", Status); return false; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Game loop while(!window.wants_to_quit()) { sdl::message_pump(); const uint32_t NUM_OF_LAYERS = 6; struct Cam_dir { GLint cube; math::vec3 tar; math::vec3 up; }; std::array<Cam_dir, NUM_OF_LAYERS> cam_dirs = { Cam_dir{ GL_TEXTURE_CUBE_MAP_POSITIVE_X, math::vec3_init(1.0f, 0.0f, 0.0f), math::vec3_init(0.0f, -1.0f, 0.0f) }, Cam_dir{ GL_TEXTURE_CUBE_MAP_NEGATIVE_X, math::vec3_init(-1.0f, 0.0f, 0.0f), math::vec3_init(0.0f, -1.0f, 0.0f) }, Cam_dir{ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, math::vec3_init(0.0f, 1.0f, 0.0f), math::vec3_init(0.0f, 0.0f, -1.0f) }, Cam_dir{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, math::vec3_init(0.0f, -1.0f, 0.0f), math::vec3_init(0.0f, 0.0f, 1.0f) }, Cam_dir{ GL_TEXTURE_CUBE_MAP_POSITIVE_Z, math::vec3_init(0.0f, 0.0f, 1.0f), math::vec3_init(0.0f, -1.0f, 0.0f) }, Cam_dir{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, math::vec3_init(0.0f, 0.0f, -1.0f), math::vec3_init(0.0f, -1.0f, 0.0f) } }; renderer::clear(); renderer::reset(); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); //glEnable(GL_TEXTURE_CUBE_MAP); // Hack! we just copy them to remove errors from rotation transform static float angle = 0.f; angle += 0.005f; auto copy_lights = lights; Light_utils::rotate_points_around_origin(©_lights, angle); // Shadows { glCullFace(GL_FRONT); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); //glClearColor(1.0, 1.0, 1.0, 1.0); for (uint i = 0 ; i < NUM_OF_LAYERS ; i++) { // Bind FBO? glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cam_dirs.at(i).cube, m_shadowMap, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0); const math::mat4 sh_proj = math::mat4_projection(1, 1, 0.1f, 100.f, math::quart_tau()); const math::mat4 sh_world = math::mat4_id(); const math::vec3 light_pos = math::vec3_init(copy_lights.points[0].position[0], copy_lights.points[0].position[1], copy_lights.points[0].position[2]); const math::vec3 dir = math::vec3_add(light_pos, cam_dirs.at(i).tar); const math::mat4 sh_view = math::mat4_lookat(light_pos, dir, cam_dirs.at(i).up); const math::mat4 sh_wvp = math::mat4_multiply(sh_world, sh_view, sh_proj); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); shadow_shader.set_raw_data("uni_wvp_mat", math::mat4_get_data(sh_wvp), sizeof(float) * 16); shadow_shader.set_raw_data("uni_world_mat", math::mat4_get_data(sh_world), sizeof(float) * 16); shadow_shader.set_raw_data("uni_light_world_pos", ©_lights.points[0].position[0], sizeof(float) * 3); for(const auto &buff : buffers) { shadow_shader.bind(); buff.bind(vert_fmt, shadow_shader); const uint32_t number_of_vertices = buff.get_number_entries() / vert_fmt.get_number_of_entires(); glDrawArrays(GL_TRIANGLES, 0, number_of_vertices); } } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } renderer::reset(); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Lighting renderer::shader &curr_shader = [&]() -> renderer::shader& { if(current_render_path == Render_path::forward_lighting) { const float spec_power = 10.f; const float spec_intensity = 10.f; glUseProgram(forward_shader.get_program_gl_id()); // eek glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowMap); 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); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); forward_shader.set_raw_data("specular_intensity", &spec_power, sizeof(float)); forward_shader.set_raw_data("specular_power", &spec_power, sizeof(float)); forward_shader.set_raw_data("eye_position", &eye_position, sizeof(float) * 3); // For Dir lights for(uint32_t i = 0; i < std::min<uint32_t>(copy_lights.directionals.size(), 0); ++i) { forward_shader.set_raw_data("dir_light[" + std::to_string(i) + "].color", copy_lights.directionals[i].color, sizeof(float) * 3); forward_shader.set_raw_data("dir_light[" + std::to_string(i) + "].direction", copy_lights.directionals[i].direction, sizeof(float) * 3); forward_shader.set_raw_data("dir_light[" + std::to_string(i) + "].ambient", ©_lights.directionals[i].ambient, sizeof(float)); forward_shader.set_raw_data("dir_light[" + std::to_string(i) + "].diffuse", ©_lights.directionals[i].diffuse, sizeof(float)); } // For Point lights for(uint32_t i = 0; i < std::min<uint32_t>(copy_lights.points.size(), 1); ++i) { forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].color", copy_lights.points[i].color, sizeof(float) * 3); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].position", copy_lights.points[i].position, sizeof(float) * 3); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].ambient", ©_lights.points[i].ambient, sizeof(float)); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].diffuse", ©_lights.points[i].diffuse, sizeof(float)); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.constant", ©_lights.points[i].atten_constant, sizeof(float)); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.linear", ©_lights.points[i].atten_linear, sizeof(float)); forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.expon", ©_lights.points[i].atten_expon, sizeof(float)); } return forward_shader; } return fullbright_shader; }(); // functional burger! for(const auto &buff : buffers) { const math::vec3 light_pos = math::vec3_init(copy_lights.points[0].position[0], copy_lights.points[0].position[1], copy_lights.points[0].position[2]); const math::vec3 dir = math::vec3_add(light_pos, cam_dirs.at(0).tar); auto test_view = math::mat4_lookat(light_pos, dir, cam_dirs.at(0).up); curr_shader.set_raw_data("view", math::mat4_get_data(view), sizeof(float) * 16); curr_shader.set_raw_data("proj", math::mat4_get_data(proj), sizeof(float) * 16); curr_shader.set_raw_data("model", math::mat4_get_data(world), sizeof(float) * 16); curr_shader.set_texture("diffuse_map", test_texture0); renderer::draw(curr_shader, vert_fmt, buff); } window.flip_buffer(); } return 0; }
/** Detect which internal formats are allowed as RTT Also detect what combinations of stencil and depth are allowed with this internal format. */ void GLFBOManager::detectFBOFormats() { // Try all formats, and report which ones work as target GLuint fb, tid; GLint old_drawbuffer, old_readbuffer; GLenum target = GL_TEXTURE_2D; glGetIntegerv (GL_DRAW_BUFFER, &old_drawbuffer); glGetIntegerv (GL_READ_BUFFER, &old_readbuffer); for(size_t x=0; x<PF_COUNT; ++x) { mProps[x].valid = false; // Fetch GL format token GLenum fmt = GLPixelUtil::getGLInternalFormat((PixelFormat)x); if(fmt == GL_NONE && x!=0) continue; // No test for compressed formats if(PixelUtil::isCompressed((PixelFormat)x)) continue; // Buggy ATI cards *crash* on non-RGB(A) formats int depths[4]; PixelUtil::getBitDepths((PixelFormat)x, depths); if(fmt!=GL_NONE && mATIMode && (!depths[0] || !depths[1] || !depths[2])) continue; // Create and attach framebuffer glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); if (fmt!=GL_NONE) { // Create and attach texture glGenTextures(1, &tid); glBindTexture(target, tid); // Set some default parameters so it won't fail on NVidia cards if (GLEW_VERSION_1_2) glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, tid, 0); } else { // Draw to nowhere -- stencil/depth only glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } // Check status GLuint status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Ignore status in case of fmt==GL_NONE, because no implementation will accept // a buffer without *any* attachment. Buffers with only stencil and depth attachment // might still be supported, so we must continue probing. if(fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE_EXT) { mProps[x].valid = true; StringUtil::StrStreamType str; str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) << " depth/stencil support: "; // For each depth/stencil formats for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth) { if (depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT) { // General depth/stencil combination for (size_t stencil = 0; stencil < STENCILFORMAT_COUNT; ++stencil) { //StringUtil::StrStreamType l; //l << "Trying " << PixelUtil::getFormatName((PixelFormat)x) // << " D" << depthBits[depth] // << "S" << stencilBits[stencil]; //LogManager::getSingleton().logMessage(l.str()); if (_tryFormat(depthFormats[depth], stencilFormats[stencil])) { /// Add mode to allowed modes str << "D" << depthBits[depth] << "S" << stencilBits[stencil] << " "; FormatProperties::Mode mode; mode.depth = depth; mode.stencil = stencil; mProps[x].modes.push_back(mode); } } } else { // Packed depth/stencil format // #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX // It now seems as if this workaround now *breaks* nvidia cards on Linux with the 169.12 drivers on Linux #if 0 // Only query packed depth/stencil formats for 32-bit // non-floating point formats (ie not R32!) // Linux nVidia driver segfaults if you query others if (PixelUtil::getNumElemBits((PixelFormat)x) != 32 || PixelUtil::isFloatingPoint((PixelFormat)x)) { continue; } #endif if (_tryPackedFormat(depthFormats[depth])) { /// Add mode to allowed modes str << "Packed-D" << depthBits[depth] << "S" << 8 << " "; FormatProperties::Mode mode; mode.depth = depth; mode.stencil = 0; // unuse mProps[x].modes.push_back(mode); } } } LogManager::getSingleton().logMessage(str.str()); } // Delete texture and framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &fb); // Workaround for NVIDIA / Linux 169.21 driver problem // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25 glFinish(); if (fmt!=GL_NONE) glDeleteTextures(1, &tid); } // It seems a bug in nVidia driver: glBindFramebufferEXT should restore // draw and read buffers, but in some unclear circumstances it won't. glDrawBuffer(old_drawbuffer); glReadBuffer(old_readbuffer); String fmtstring; for(size_t x=0; x<PF_COUNT; ++x) { if(mProps[x].valid) fmtstring += PixelUtil::getFormatName((PixelFormat)x)+" "; } LogManager::getSingleton().logMessage("[GL] : Valid FBO targets " + fmtstring); }
static int SaveTIFF( ClientData cl,Tcl_Interp *interp,int argc,char **argv ) { unsigned char *buffer; char fname[256]; int nx, ny, ox, oy, viewp[4]; TIFF *image; int y, stride; // Determine file name: //--------------------- if( argc < 2 ) { strcpy( fname, "elmerpost.tif" ); } else { strncpy( fname,argv[1], 256 ); } image = TIFFOpen( fname, "w" ); if( image==NULL ) { #if defined(WIN32) || defined(win32) sprintf( interp->result, "savetiff: can't open [%s] for writing!\n",fname ); #else sprintf( interp->result, "savetiff: can't open [%s] for writing:\n%s\n", fname, strerror(errno) ); #endif return TCL_ERROR; } // Determine picture size: //------------------------ glGetIntegerv( GL_VIEWPORT, viewp ); ox = viewp[0]; oy = viewp[1]; nx = viewp[2]+1; ny = viewp[3]+1; // Allocate buffer: //------------------ buffer = (unsigned char *) malloc( nx*ny*3 ); if ( buffer==NULL ) { TIFFClose( image ); #if defined(WIN32) || defined(win32) sprintf( interp->result, "savetiff: can't allocate memory!\n" ); #else sprintf( interp->result, "savetiff: can't allocate memory:\n%s\n", strerror(errno) ); #endif return TCL_ERROR; } fprintf( stdout, "Saving %s ... ", fname ); fflush( stdout ); // Copy RGB-data into buffer: //---------------------------- glReadBuffer( GL_FRONT ); glReadPixels( ox, oy, nx, ny, GL_RGB, GL_UNSIGNED_BYTE, buffer ); // Flip the picture: //------------------ stride = 3*nx; for( y=0; y<ny/2; y++ ) { unsigned char *r1 = buffer + stride*y; unsigned char *r2 = buffer + stride*(ny-1-y); memcpy( buffer, r1, stride ); memcpy( r1, r2, stride ); memcpy( r2, buffer, stride ); } TIFFSetField( image, TIFFTAG_IMAGEWIDTH, nx ); TIFFSetField( image, TIFFTAG_IMAGELENGTH, ny ); TIFFSetField( image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE ); TIFFSetField( image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ); TIFFSetField( image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB ); TIFFSetField( image, TIFFTAG_BITSPERSAMPLE, 8 ); TIFFSetField( image, TIFFTAG_SAMPLESPERPIXEL, 3 ); if( TIFFWriteEncodedStrip( image, 0, buffer, nx*ny*3) == 0 ) { TIFFClose( image ); #if defined(WIN32) || defined(win32) sprintf( interp->result, "savetiff: unable to encode picture\n" ); #else sprintf( interp->result, "savetiff: unable to encode picture\n%s\n", strerror(errno) ); #endif free( buffer ); return TCL_ERROR; } TIFFClose( image ); free( buffer ); fprintf( stdout, "done\n"); fflush( stdout ); return TCL_OK; }
void EDA_3D_CANVAS::TakeScreenshot( wxCommandEvent& event ) { static wxFileName fn; // Remember path between saves during this session only. wxString FullFileName; wxString file_ext, mask; bool fmt_is_jpeg = false; // First time path is set to the project path. if( !fn.IsOk() ) fn = Parent()->Prj().GetProjectFullName(); if( event.GetId() == ID_MENU_SCREENCOPY_JPEG ) fmt_is_jpeg = true; if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD ) { file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" ); mask = wxT( "*." ) + file_ext; fn.SetExt( file_ext ); FullFileName = EDA_FileSelector( _( "3D Image File Name:" ), fn.GetPath(), fn.GetFullName(), file_ext, mask, this, wxFD_SAVE | wxFD_OVERWRITE_PROMPT, true ); if( FullFileName.IsEmpty() ) return; fn = FullFileName; // Be sure the screen area destroyed by the file dialog is redrawn before making // a screen copy. // Without this call, under Linux the screen refresh is made to late. wxYield(); } struct viewport_params { GLint originx; GLint originy; GLint x; GLint y; } viewport; // Be sure we have the latest 3D view (remember 3D view is buffered) Refresh(); wxYield(); // Build image from the 3D buffer wxWindowUpdateLocker noUpdates( this ); glGetIntegerv( GL_VIEWPORT, (GLint*) &viewport ); unsigned char* pixelbuffer = (unsigned char*) malloc( viewport.x * viewport.y * 3 ); unsigned char* alphabuffer = (unsigned char*) malloc( viewport.x * viewport.y ); wxImage image( viewport.x, viewport.y ); glPixelStorei( GL_PACK_ALIGNMENT, 1 ); glReadBuffer( GL_BACK_LEFT ); glReadPixels( viewport.originx, viewport.originy, viewport.x, viewport.y, GL_RGB, GL_UNSIGNED_BYTE, pixelbuffer ); glReadPixels( viewport.originx, viewport.originy, viewport.x, viewport.y, GL_ALPHA, GL_UNSIGNED_BYTE, alphabuffer ); image.SetData( pixelbuffer ); image.SetAlpha( alphabuffer ); image = image.Mirror( false ); wxBitmap bitmap( image ); if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD ) { if( wxTheClipboard->Open() ) { wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap ); if( !wxTheClipboard->SetData( dobjBmp ) ) wxMessageBox( _( "Failed to copy image to clipboard" ) ); wxTheClipboard->Flush(); /* the data in clipboard will stay * available after the application exits */ wxTheClipboard->Close(); } } else { wxImage image = bitmap.ConvertToImage(); if( !image.SaveFile( FullFileName, fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) ) wxMessageBox( _( "Can't save file" ) ); image.Destroy(); } }
/* ARGSUSED5 */ /* Only Win32 uses gameMode parameter. */ GLUTwindow * __glutCreateWindow(GLUTwindow * parent, int x, int y, int width, int height, int gameMode) { GLUTwindow *window; XSetWindowAttributes wa; unsigned long attribMask; int winnum; int i; #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) GLXFBConfigSGIX fbc; #else void *fbc; #endif #if defined(_WIN32) WNDCLASS wc; int style; int pixelFormat; if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) { __glutOpenWin32Connection(NULL); } #else if (!__glutDisplay) { __glutOpenXConnection(NULL); } #endif if (__glutGameModeWindow) { __glutFatalError("cannot create windows in game mode."); } winnum = getUnusedWindowSlot(); window = (GLUTwindow *) malloc(sizeof(GLUTwindow)); if (!window) { __glutFatalError("out of memory."); } window->num = winnum; #if !defined(_WIN32) window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, &window->visAlloced, (void**) &fbc); if (!window->vis) { __glutFatalError( "visual with necessary capabilities not found."); } __glutSetupColormap(window->vis, &window->colormap, &window->cmap); #endif window->eventMask = StructureNotifyMask | ExposureMask; attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; wa.background_pixmap = None; wa.border_pixel = 0; wa.colormap = window->cmap; wa.event_mask = window->eventMask; if (parent) { if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) { wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK; } attribMask |= CWDontPropagate; wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; } else { wa.do_not_propagate_mask = 0; } /* Stash width and height before Win32's __glutAdjustCoords possibly overwrites the values. */ window->width = width; window->height = height; window->forceReshape = True; window->ignoreKeyRepeat = False; #if defined(_WIN32) __glutAdjustCoords(parent ? parent->win : NULL, &x, &y, &width, &height); if (parent) { style = WS_CHILD; } else { if (gameMode) { /* Game mode window should be a WS_POPUP window to ensure that the taskbar is hidden by it. A standard WS_OVERLAPPEDWINDOW does not hide the task bar. */ style = WS_POPUP | WS_MAXIMIZE; } else { /* A standard toplevel window with borders and such. */ style = WS_OVERLAPPEDWINDOW; } } window->win = CreateWindow("GLUT", "GLUT", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, x, y, width, height, parent ? parent->win : __glutRoot, NULL, GetModuleHandle(NULL), 0); window->hdc = GetDC(window->win); /* Must set the XHDC for fake glXChooseVisual & fake glXCreateContext & fake XAllocColorCells. */ XHDC = window->hdc; window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, &window->visAlloced, &fbc); if (!window->vis) { __glutFatalError( "pixel format with necessary capabilities not found."); } pixelFormat = window->vis->num; if (pixelFormat == 0) { __glutFatalError("ChoosePixelFormat failed during window create."); } if (!SetPixelFormat(window->hdc, pixelFormat, &window->vis->pfd)) { __glutFatalError("SetPixelFormat failed during window create."); } __glutSetupColormap(window->vis, &window->colormap, &window->cmap); /* Make sure subwindows get a windowStatus callback. */ if (parent) { PostMessage(parent->win, WM_ACTIVATE, 0, 0); } window->renderDc = window->hdc; #else /* X Window System */ window->win = XCreateWindow(__glutDisplay, parent == NULL ? __glutRoot : parent->win, x, y, width, height, 0, window->vis->depth, InputOutput, window->vis->visual, attribMask, &wa); #endif window->renderWin = window->win; #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) if (fbc) { window->ctx = glXCreateContextWithConfigSGIX(__glutDisplay, fbc, GLX_RGBA_TYPE_SGIX, None, __glutTryDirect); } else #endif { #ifdef _WIN32 window->ctx = wglCreateContext(window->hdc); #else window->ctx = glXCreateContext(__glutDisplay, window->vis, None, __glutTryDirect); #endif } if (!window->ctx) { __glutFatalError( "failed to create OpenGL rendering context."); } window->renderCtx = window->ctx; #if !defined(_WIN32) window->isDirect = glXIsDirect(__glutDisplay, window->ctx); if (__glutForceDirect) { if (!window->isDirect) { __glutFatalError("direct rendering not possible."); } } #endif window->parent = parent; if (parent) { window->siblings = parent->children; parent->children = window; } else { window->siblings = NULL; } window->overlay = NULL; window->children = NULL; window->display = defaultDisplay; window->reshape = __glutDefaultReshape; window->mouse = NULL; window->motion = NULL; window->passive = NULL; window->entry = NULL; window->keyboard = NULL; window->keyboardUp = NULL; window->windowStatus = NULL; window->visibility = NULL; window->special = NULL; window->specialUp = NULL; window->buttonBox = NULL; window->dials = NULL; window->spaceMotion = NULL; window->spaceRotate = NULL; window->spaceButton = NULL; window->tabletMotion = NULL; window->tabletButton = NULL; #ifdef _WIN32 window->joystick = NULL; window->joyPollInterval = 0; #endif window->tabletPos[0] = -1; window->tabletPos[1] = -1; window->shownState = 0; window->visState = -1; /* not VisibilityUnobscured, VisibilityPartiallyObscured, or VisibilityFullyObscured */ window->entryState = -1; /* not EnterNotify or LeaveNotify */ window->desiredConfMask = 0; window->buttonUses = 0; window->cursor = GLUT_CURSOR_INHERIT; /* Setup window to be mapped when glutMainLoop starts. */ window->workMask = GLUT_MAP_WORK; #ifdef _WIN32 if (gameMode) { /* When mapping a game mode window, just show the window. We have already created the game mode window with a maximize flag at creation time. Doing a ShowWindow(window->win, SW_SHOWNORMAL) would be wrong for a game mode window since it would unmaximize the window. */ window->desiredMapState = GameModeState; } else { window->desiredMapState = NormalState; } #else window->desiredMapState = NormalState; #endif window->prevWorkWin = __glutWindowWorkList; __glutWindowWorkList = window; /* Initially, no menus attached. */ for (i = 0; i < GLUT_MAX_MENUS; i++) { window->menu[i] = 0; } /* Add this new window to the window list. */ __glutWindowList[winnum] = window; /* Make the new window the current window. */ __glutSetWindow(window); __glutDetermineMesaSwapHackSupport(); if (window->treatAsSingle) { /* We do this because either the window really is single buffered (in which case this is redundant, but harmless, because this is the initial single-buffered context state); or we are treating a double buffered window as a single-buffered window because the system does not appear to export any suitable single- buffered visuals (in which the following are necessary). */ glDrawBuffer(GL_FRONT); glReadBuffer(GL_FRONT); } return window; }
Scene::Scene(std::istream& ins) :projection(NULL), view(NULL), numLights(0), shadowMapSize(windWidth*2), texUnitBase(0) { srand(0);//TODO SEED WITH TIME parseScene(ins); //create shadow map texture glGenTextures(1, &shadowMapTexture); glGenFramebuffersEXT(1, &FBOID); glGenFramebuffersEXT(1, &recordFBOID); glGenTextures(2, recordTexBase); glGenFramebuffersEXT(1, &directFBOID); glGenTextures(2, directTex); glBindTexture(GL_TEXTURE_2D, directTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windWidth, windHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, directTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windWidth, windHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, directFBOID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, directTex[0], 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, directTex[1], 0); glGenFramebuffersEXT(1, &splatBufFBOID); glGenTextures(1, &splatTex); glActiveTexture(texUnitEnums[0]); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapTexture); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); std::cout << "numlights: " << numLights << std::endl; glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, numLights, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOID); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); //set up splat buffer glBindTexture(GL_TEXTURE_2D, splatTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, windWidth, windHeight, 0, GL_RGBA, GL_FLOAT, NULL); //it doesn't need a depth attachment //set up "color" attachment, alpha channel with be depth glBindTexture(GL_TEXTURE_2D, recordTexBase[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, recordWidth, recordHeight, 0, GL_RGBA, GL_FLOAT, NULL); //set up depth attachment glBindTexture(GL_TEXTURE_2D, recordTexBase[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, recordWidth, recordHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);//window buffer loadShadowShader(); loadSplatShader(); loadFinalShader(); readCoordNormals(); // std::cout << "constructor completed" << std::endl; IMap = new float[4*recordWidth*recordHeight]; splatBuffer = new float[4*windWidth*windHeight]; timer.start(); std::cout << "before warmup" <<timer.split() << std::endl; warmupCache(1000);//generate starting records std::cout << "after warmup" << timer.split() << std::endl; }