Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


[Solved]glCopyTexImage alternative?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 25 February 2012 - 05:23 PM

Hello gamedev.net!
I'm making a 2D soft shadow engine and i am currently experiencing a speed problem with glCopyTexImage.

Here is a quick summary of what happens during rendering:
step 1: I fill the stencil buffer with shadow regions for each convexhull.
step 2: I render a radial gradient while the stencil buffer is enabled so that It stencils away areas of the radial gradient that were previously covering the shadow region
step 3: for each light, I render shadow fins, that are within the radius of each light. I use the stencil buffer to make sure that the shadows are within the lights radius.
step 4: I needed a way to save each lighting pass so i decided that i would copy the framebuffer as a texture using glCopyTexImage and then I clear the framebuffer each Iteration/Pass.
step 5: I iterate through all lighting passes,and render a fullscreen quad with additive blending enabled.Yielding Soft-looking edges for shadows.

Here is the rendering routine as code:
unsigned int K= 0;
extern Wrapper BindedClasses;
bool loaded = false;
GLuint ID[50];
int RecsFilled = 0;
void Frame::OnRender(){
	//void RenderParticles(std::vector<Particle> & ParticleList);
	//void RenderParticles(std::vector<Particle> & ParticleList,float R,float G,float B);
	void RenderConvexHulls(std::vector<Convex_Hull*> & ActiveBodies);
	//void RenderPositionList(std::vector<Particle> & TempVertexList);
	void RenderShadows(std::vector<Convex_Hull*> & ActiveBodies,Light & CL);
	void OpenStencil();
	void CloseStencil();
	void ClearStencil();
	void ClearAlphaChannel(float TranslateX,float TranslateY);
	void RenderFins(std::vector<Convex_Hull*> & ActiveBodies, Light & CL);
	void CloseStencilUnlocked();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glLoadIdentity();
	glScalef(Scale.X,Scale.Y,1.0f);
	glTranslatef(Translate.X,Translate.Y,0.0f);

	glEnable(GL_BLEND);
	ClearAlphaChannel(0,0);
	for(unsigned int K = 0; K < LightList.size();K++){
		Light & CL = LightList[K];
		OpenStencil();
		RenderShadows(ActiveBodies,CL);
		CloseStencil();
		glBlendFunc(GL_ONE, GL_ONE);
		CL.RenderLight();
		ClearStencil();
		OpenStencil();
			TextureProcedures::FillRect(0,0,10000,10000,1,1,1,1);
			CL.RenderLight();
		CloseStencilUnlocked();
		glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
		RenderFins(ActiveBodies,CL);
		ClearStencil();
	  
		//Save shadow pass as a texture
		glEnable(GL_TEXTURE_2D);
			glGenTextures(1,&ID[RecsFilled]);
			glBindTexture(GL_TEXTURE_2D,ID[RecsFilled]);
			glCopyTexImage2DEXT(GL_TEXTURE_2D,0,GL_RGBA,0,0,1920,1080,0);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			RecsFilled++;
		glDisable(GL_TEXTURE_2D);
		//clear Framebuffer
		glClear(GL_COLOR_BUFFER_BIT);
	}
	ClearStencil();
	//Additively blends all shadow passes
	glClear(GL_COLOR_BUFFER_BIT);
	glBlendFunc(GL_ONE,GL_ONE);
	for(int K = 0; K < RecsFilled;K++){
		GLuint & CID = ID[K];
		TextureProcedures::RenderInvertedQuad(0,0,1920,1080,CID,false);
	}
	glDeleteTextures(RecsFilled,ID);
	RecsFilled = 0;

	RenderConvexHulls(ActiveBodies);

	glLoadIdentity();
	SDL_GL_SwapBuffers();
}
void RenderConvexHulls(std::vector<Convex_Hull*> & ActiveBodies){
	for(K = 0; K < ActiveBodies.size();K++){
		Convex_Hull * CH = ActiveBodies[K];
		CH->V_Render();
	}
}
void RenderPositionList(std::vector<Particle> & TempVertexList){
	glBegin(GL_LINE_LOOP);
		for(K = 0; K < TempVertexList.size();K++){
			Particle & CV = TempVertexList[K];
			glVertex2f(CV.Position.X,CV.Position.Y);
		}
	glEnd();
}
void RenderShadows(std::vector<Convex_Hull*> & ActiveBodies,Light & CL){
	for(unsigned int K = 0;K < ActiveBodies.size();K++){
		Convex_Hull * CH = ActiveBodies[K];
		CH->RenderShadows(CL);
	}
}
void OpenStencil(){
	glEnable(GL_STENCIL_TEST);
	glStencilFunc(GL_NEVER, 0x0, 0x0);
	glStencilOp(GL_INCR, GL_INCR, GL_INCR);
}
void CloseStencil(){
	glStencilFunc(GL_EQUAL, 0x00, 0xFF);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
}
void CloseStencilUnlocked(){
	glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
}
void ClearStencil(){
	glClear(GL_STENCIL_BUFFER_BIT);
}
void ClearAlphaChannel(float TranslateX,float TranslateY){
	glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); //only write to alpha
		TextureProcedures::FillRect(TranslateX*-1,TranslateY*-1,100000,100000,0.0f,0.0f,0.0f,0.1f);
	glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //enable color writes
}

void RenderFins(std::vector<Convex_Hull*> & ActiveBodies, Light & CL){
	BindedClasses.TestShader->Begin();
	for(unsigned int K = 0; K < ActiveBodies.size();K++){
		ActiveBodies[K]->RenderShadowFin(CL);
	}
	BindedClasses.TestShader->End();
}

Basically in order for the shadow fins to render correctly i have to render each iteration separately and then use additive blending otherwise
the shadow fins will be rendered with dark edges rather than faded edges.


Am I using glCopyTexImage incorrectly or is it just slow?

Footage: http://www.youtube.com/watch?v=6Nc1boqxyZA&feature=youtu.be

Sponsor:

#2 Brother Bob   Moderators   -  Reputation: 9210

Like
2Likes
Like

Posted 25 February 2012 - 05:47 PM

At the very least, you should use glCopyTexSubImage instead of allocating new textures and destroying them every time. Make an empty textrure (pass a null-pointer to glTexImage but with the desired dimensions and internal format), and then update it with the Sub-family of functions instead of allocating new textures and destroying them all the time.

There are also more modern render-to-texture alternatives if you want to go that route, but just Sub-imaging existing texture should at least be a good start.

#3 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 25 February 2012 - 06:58 PM

Thanks for the advice.
It now runs waaaay faster than before.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS