Пример #1
0
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();


}
Пример #2
0
/* 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);
	}
}
Пример #3
0
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;
}
Пример #4
0
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");
        }
        
    }
Пример #6
0
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();
	}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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);
}
Пример #14
0
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);
}
Пример #15
0
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);
	}
}
Пример #16
0
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__ );
}
Пример #17
0
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;
}
Пример #18
0
//////////////////////////////////////////////////////////////////////
//  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;
}
Пример #19
0
GLenum getSnapshot(u8 *buf) {
	glReadBuffer(GL_FRONT);
	glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buf);
	return glGetError();
}
Пример #20
0
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);
}
Пример #22
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;
}
Пример #23
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 );
    }
}
Пример #24
0
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();
}
Пример #25
0
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(&copy_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", &copy_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",    &copy_lights.directionals[i].ambient,     sizeof(float));
          forward_shader.set_raw_data("dir_light[" + std::to_string(i) + "].diffuse",    &copy_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",          &copy_lights.points[i].ambient,        sizeof(float));
          forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].diffuse",          &copy_lights.points[i].diffuse,        sizeof(float));
          forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.constant",   &copy_lights.points[i].atten_constant, sizeof(float));
          forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.linear",     &copy_lights.points[i].atten_linear,   sizeof(float));
          forward_shader.set_raw_data("point_light[" + std::to_string(i) + "].atten.expon",      &copy_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);
    }
Пример #27
0
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;
}
Пример #28
0
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();
    }
}
Пример #29
0
/* 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;
}
Пример #30
0
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;
}