Example #1
0
//==========================================================================
//
//
//
//==========================================================================
void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin)
{
	float fU1,fU2,fV1,fV2;

	FMaterial *gltexture=FMaterial::ValidateTexture(src, false);
	
	if (!gltexture) return;

	gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
	
	// scaling is not used here.
	if (!local_origin)
	{
		fU1 = float(left) / src->GetWidth();
		fV1 = float(top) / src->GetHeight();
		fU2 = float(right) / src->GetWidth();
		fV2 = float(bottom) / src->GetHeight();
	}
	else
	{		
		fU1 = 0;
		fV1 = 0;
		fU2 = float(right-left) / src->GetWidth();
		fV2 = float(bottom-top) / src->GetHeight();
	}
	gl_RenderState.ResetColor();
	gl_RenderState.Apply();

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(left, top, 0, fU1, fV1); ptr++;
	ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
	ptr->Set(right, top, 0, fU2, fV1); ptr++;
	ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
}
Example #2
0
bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
{
    Clock += ticks;

    float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
    float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());

    gl_RenderState.SetTextureMode(TM_OPAQUE);
    gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();
    fb->wipestartscreen->Bind(0, 0, false);

    FFlatVertex *ptr;
    unsigned int offset, count;
    ptr = GLRenderer->mVBO->GetBuffer();
    ptr->Set(0, 0, 0, 0, vb);
    ptr++;
    ptr->Set(0, fb->Height, 0, 0, 0);
    ptr++;
    ptr->Set(fb->Width, 0, 0, ur, vb);
    ptr++;
    ptr->Set(fb->Width, fb->Height, 0, ur, 0);
    ptr++;
    GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);

    fb->wipeendscreen->Bind(0, 0, false);
    gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f));
    gl_RenderState.Apply();
    GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
    gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
    gl_RenderState.SetTextureMode(TM_MODULATE);

    return Clock >= 32;
}
Example #3
0
void FDrawInfo::ClearFloodStencil(wallseg * ws)
{
	int recursion = GLPortal::GetRecursion();

	glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
	gl_RenderState.EnableTexture(false);
	glColorMask(0,0,0,0);						// don't write to the graphics buffer
	gl_RenderState.ResetColor();

	gl_RenderState.Apply();
	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
	ptr++;
	ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
	ptr++;
	ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
	ptr++;
	ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);

	// restore old stencil op.
	glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
	glStencilFunc(GL_EQUAL,recursion,~0);
	gl_RenderState.EnableTexture(true);
	glColorMask(1,1,1,1);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(true);
}
Example #4
0
void FDrawInfo::SetupFloodStencil(wallseg * ws)
{
	int recursion = GLPortal::GetRecursion();

	// Create stencil 
	glStencilFunc(GL_EQUAL,recursion,~0);		// create stencil
	glStencilOp(GL_KEEP,GL_KEEP,GL_INCR);		// increment stencil of valid pixels
	glColorMask(0,0,0,0);						// don't write to the graphics buffer
	gl_RenderState.EnableTexture(false);
	gl_RenderState.ResetColor();
	glEnable(GL_DEPTH_TEST);
	glDepthMask(true);

	gl_RenderState.Apply();
	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
	ptr++;
	ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
	ptr++;
	ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
	ptr++;
	ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);


	glStencilFunc(GL_EQUAL,recursion+1,~0);		// draw sky into stencil
	glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);		// this stage doesn't modify the stencil

	glColorMask(1,1,1,1);						// don't write to the graphics buffer
	gl_RenderState.EnableTexture(true);
	glDisable(GL_DEPTH_TEST);
	glDepthMask(false);
}
Example #5
0
void FGLRenderer::ClearBorders()
{
	OpenGLFrameBuffer *glscreen = static_cast<OpenGLFrameBuffer*>(screen);

	// Letterbox time! Draw black top and bottom borders.
	int width = glscreen->GetWidth();
	int height = glscreen->GetHeight();
	int trueHeight = glscreen->GetTrueHeight();

	int borderHeight = (trueHeight - height) / 2;

	glViewport(0, 0, width, trueHeight);
	gl_RenderState.mProjectionMatrix.loadIdentity();
	gl_RenderState.mProjectionMatrix.ortho(0.0f, width * 1.0f, 0.0f, trueHeight, -1.0f, 1.0f);
	gl_RenderState.SetColor(0.f ,0.f ,0.f ,1.f);
	gl_RenderState.Set2DMode(true);
	gl_RenderState.EnableTexture(false);
	gl_RenderState.Apply();
	gl_RenderState.ApplyMatrices(); 

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(0, borderHeight, 0, 0, 0); ptr++;
	ptr->Set(0, 0, 0, 0, 0); ptr++;
	ptr->Set(width, 0, 0, 0, 0); ptr++;
	ptr->Set(width, borderHeight, 0, 0, 0); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	ptr->Set(0, trueHeight, 0, 0, 0); ptr++;
	ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++;
	ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++;
	ptr->Set(width, trueHeight, 0, 0, 0); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	gl_RenderState.EnableTexture(true);

	glViewport(0, (trueHeight - height) / 2, width, height); 
}
void GLWall::RenderWall(int textured, unsigned int *store)
{
	static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check.
	bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT));

	tcs[0]=lolft;
	tcs[1]=uplft;
	tcs[2]=uprgt;
	tcs[3]=lorgt;
	if ((flags&GLWF_GLOW) && (textured & RWF_GLOW))
	{
		gl_RenderState.SetGlowPlanes(topplane, bottomplane);
		gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
	}

	if (!(textured & RWF_NORENDER))
	{
		gl_RenderState.Apply();
		gl_RenderState.ApplyLightIndex(dynlightindex);
	}

	// the rest of the code is identical for textured rendering and lights
	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	unsigned int count, offset;

	ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
	ptr++;
	if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
	ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v);
	ptr++;
	if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
	ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v);
	ptr++;
	if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
	ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v);
	ptr++;
	if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
	count = GLRenderer->mVBO->GetCount(ptr, &offset);
	if (!(textured & RWF_NORENDER))
	{
		GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count);
		vertexcount += count;
	}
	if (store != NULL)
	{
		store[0] = offset;
		store[1] = count;
	}
}
Example #7
0
void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
	gl_RenderState.EnableTexture(false);
	gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	gl_RenderState.AlphaFunc(GL_GREATER,0);
	gl_RenderState.SetColorAlpha(color, damount);
	gl_RenderState.Apply();
	
	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(x1, y1, 0, 0, 0); ptr++;
	ptr->Set(x1, y1+h, 0, 0, 0); ptr++;
	ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++;
	ptr->Set(x1+w, y1, 0, 0, 0); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);

	gl_RenderState.EnableTexture(true);
}
Example #8
0
//==========================================================================
//
//
//
//==========================================================================
void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
{
	PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor];
	gl_RenderState.EnableTexture(false);
	gl_RenderState.SetColorAlpha(p, 1.f);
	gl_RenderState.Apply();

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(x1, y1, 0, 0, 0); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS);

	gl_RenderState.EnableTexture(true);
}
Example #9
0
void GLWall::MakeVertices(bool nosplit)
{
	if (vertcount == 0)
	{
		bool split = (gl_seamless && !nosplit && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT));

		FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();

		ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
		ptr++;
		if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
		ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
		ptr++;
		if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr);
		ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
		ptr++;
		if (split && glseg.fracright == 1) SplitRightEdge(ptr);
		ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
		ptr++;
		if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr);
		vertcount = GLRenderer->mVBO->GetCount(ptr, &vertindex);
	}
}
Example #10
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//
// Horizon Portal
//
// This simply draws the area in medium sized squares. Drawing it as a whole
// polygon creates visible inaccuracies.
//
// Originally I tried to minimize the amount of data to be drawn but there
// are 2 problems with it:
//
// 1. Setting this up completely negates any performance gains.
// 2. It doesn't work with a 360° field of view (as when you are looking up.)
//
//
// So the brute force mechanism is just as good.
//
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// GLHorizonPortal::DrawContents
//
//-----------------------------------------------------------------------------
void GLHorizonPortal::DrawContents()
{
	PortalAll.Clock();

	GLSectorPlane * sp=&origin->plane;
	FMaterial * gltexture;
	PalEntry color;
	float z;
	player_t * player=&players[consoleplayer];

	gltexture=FMaterial::ValidateTexture(sp->texture, false, true);
	if (!gltexture) 
	{
		ClearScreen();
		PortalAll.Unclock();
		return;
	}
	gl_RenderState.SetCameraPos(ViewPos.X, ViewPos.Y, ViewPos.Z);


	z=sp->Texheight;


	if (gltexture && gltexture->tex->isFullbright())
	{
		// glowing textures are always drawn full bright without color
		gl_SetColor(255, 0, origin->colormap, 1.f);
		gl_SetFog(255, 0, &origin->colormap, false);
	}
	else 
	{
		int rel = getExtraLight();
		gl_SetColor(origin->lightlevel, rel, origin->colormap, 1.0f);
		gl_SetFog(origin->lightlevel, rel, &origin->colormap, false);
	}


	gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);

	gl_SetPlaneTextureRotation(sp, gltexture);
	gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
	gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
	gl_RenderState.Apply();



	float vx= ViewPos.X;
	float vy= ViewPos.Y;

	// Draw to some far away boundary
	// This is not drawn as larher strips because it causes visual glitches.
	for(float x=-32768+vx; x<32768+vx; x+=4096)
	{
		for(float y=-32768+vy; y<32768+vy;y+=4096)
		{
			FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
			ptr->Set(x, z, y, x / 64, -y / 64);
			ptr++;
			ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64);
			ptr++;
			ptr->Set(x, z, y + 4096, x / 64, -y / 64 - 64);
			ptr++;
			ptr->Set(x + 4096, z, y + 4096, x / 64 + 64, -y / 64 - 64);
			ptr++;
			GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
		}
	}

	float vz= ViewPos.Z;
	float tz=(z-vz);///64.0f;

	// fill the gap between the polygon and the true horizon
	// Since I can't draw into infinity there can always be a
	// small gap

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0);
	ptr++;
	ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz);
	ptr++;
	ptr->Set(-32768 + vx, z, 32768 + vy, -512.f, 0);
	ptr++;
	ptr->Set(-32768 + vx, vz, 32768 + vy, -512.f, tz);
	ptr++;
	ptr->Set(32768 + vx, z, 32768 + vy, 512.f, 0);
	ptr++;
	ptr->Set(32768 + vx, vz, 32768 + vy, 512.f, tz);
	ptr++;
	ptr->Set(32768 + vx, z, -32768 + vy, -512.f, 0);
	ptr++;
	ptr->Set(32768 + vx, vz, -32768 + vy, -512.f, tz);
	ptr++;
	ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0);
	ptr++;
	ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

	gl_RenderState.EnableTextureMatrix(false);
	PortalAll.Unclock();

}
Example #11
0
//==========================================================================
//
// Draw the plane segment into the gap
//
//==========================================================================
void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bool ceiling)
{
	GLSectorPlane plane;
	int lightlevel;
	FColormap Colormap;
	FMaterial * gltexture;

	plane.GetFromSector(sec, ceiling);

	gltexture=FMaterial::ValidateTexture(plane.texture, true);
	if (!gltexture) return;

	if (gl_fixedcolormap) 
	{
		Colormap.Clear();
		lightlevel=255;
	}
	else
	{
		Colormap=sec->ColorMap;
		if (gltexture->tex->isFullbright())
		{
			Colormap.LightColor.r = Colormap.LightColor.g = Colormap.LightColor.b = 0xff;
			lightlevel=255;
		}
		else lightlevel=abs(ceiling? sec->GetCeilingLight() : sec->GetFloorLight());
	}

	int rel = getExtraLight();
	gl_SetColor(lightlevel, rel, Colormap, 1.0f);
	gl_SetFog(lightlevel, rel, &Colormap, false);
	gltexture->Bind();

	float fviewx = FIXED2FLOAT(viewx);
	float fviewy = FIXED2FLOAT(viewy);
	float fviewz = FIXED2FLOAT(viewz);

	gl_SetPlaneTextureRotation(&plane, gltexture);
	gl_RenderState.Apply();

	float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz);
	float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz);

	float px1 = fviewx + prj_fac1 * (ws->x1-fviewx);
	float py1 = fviewy + prj_fac1 * (ws->y1-fviewy);

	float px2 = fviewx + prj_fac2 * (ws->x1-fviewx);
	float py2 = fviewy + prj_fac2 * (ws->y1-fviewy);

	float px3 = fviewx + prj_fac2 * (ws->x2-fviewx);
	float py3 = fviewy + prj_fac2 * (ws->y2-fviewy);

	float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
	float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64);
	ptr++;
	ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64);
	ptr++;
	ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64);
	ptr++;
	ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);

	gl_RenderState.EnableTextureMatrix(false);
}
Example #12
0
void GLWall::RenderWall(int textured)
{
	gl_RenderState.Apply();
	gl_RenderState.ApplyLightIndex(dynlightindex);

#ifdef NO_VBO
    bool nosplit = !!(textured&RWF_NOSPLIT);
    bool split = (gl_seamless && !nosplit && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT));

#if 1 // A bit quicker due to batching, still not very fast..
	glBegin(GL_TRIANGLE_FAN);

	// lower left corner
	if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v);
	glVertex3f(glseg.x1,zbottom[0],glseg.y1);

	//if (split && glseg.fracleft==0) SplitLeftEdge(tcs);

	// upper left corner
	if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v);
	glVertex3f(glseg.x1,ztop[0],glseg.y1);

	//if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs);

	// color for right side
	//if (color2) glColor4fv(color2);

	// upper right corner
	if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v);
	glVertex3f(glseg.x2,ztop[1],glseg.y2);

	//if (split && glseg.fracright==1) SplitRightEdge(tcs);

	// lower right corner
	if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v);
	glVertex3f(glseg.x2,zbottom[1],glseg.y2);

	//if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);

	glEnd();

	vertexcount+=4;
#else

    static FFlatVertex vtx[100]; // Yes this is static. It's only used once, and I think it's faster as the address doesn't keep changing
    FFlatVertex *ptr = &vtx[0];

	ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
    ptr++;
    if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
    ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
    ptr++;
    if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr);
    ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
    ptr++;
    if (split && glseg.fracright == 1) SplitRightEdge(ptr);
    ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
    ptr++;
    if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr);

    // We can workout how many from the difference in pointers
    vertcount = (ptr - &vtx[0]);

    glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex),&vtx[0].u);
    glVertexPointer  (3,GL_FLOAT, sizeof(FFlatVertex),&vtx[0].x);

    glEnableClientState (GL_VERTEX_ARRAY);
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
    glDisableClientState (GL_COLOR_ARRAY);

    glBindBuffer (GL_ARRAY_BUFFER, 0); // NO VBO
    glDrawArrays (GL_TRIANGLE_FAN, 0, vertcount);

    vertexcount += vertcount;
    #endif
#else
	if (gl.buffermethod != BM_DEFERRED)
	{
		MakeVertices(!!(textured&RWF_NOSPLIT));
	}
	else if (vertcount == 0)
	{
		// This should never happen but in case it actually does, use the quad drawer as fallback (without edge splitting.)
		// This way it at least gets drawn.
		FQuadDrawer qd;
		qd.Set(0, glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
		qd.Set(1, glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
		qd.Set(2, glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
		qd.Set(3, glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
		qd.Render(GL_TRIANGLE_FAN);
		vertexcount += 4;
		return;
	}
	GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, vertindex, vertcount);
	vertexcount += vertcount;
#endif
}
Example #13
0
void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
	double originx, double originy, double scalex, double scaley,
	DAngle rotation, FDynamicColormap *colormap, int lightlevel)
{
	if (npoints < 3)
	{ // This is no polygon.
		return;
	}

	FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);

	if (gltexture == NULL)
	{
		return;
	}

	FColormap cm;
	cm = colormap;

	// We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering.
	SBYTE savedlightmode = glset.lightmode;
	if (glset.lightmode == 8) glset.lightmode = 0;

	gl_SetColor(lightlevel, 0, cm, 1.f);

	glset.lightmode = savedlightmode;

	gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);

	int i;
	bool dorotate = rotation != 0;

	float cosrot = cos(rotation.Radians());
	float sinrot = sin(rotation.Radians());

	//float yoffs = GatheringWipeScreen ? 0 : LBOffset;
	float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
	float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
	if (gltexture->tex->bHasCanvas)
	{
		vscale = 0 - vscale;
	}
	float ox = float(originx);
	float oy = float(originy);

	gl_RenderState.Apply();

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	for (i = 0; i < npoints; ++i)
	{
		float u = points[i].X - 0.5f - ox;
		float v = points[i].Y - 0.5f - oy;
		if (dorotate)
		{
			float t = u;
			u = t * cosrot - v * sinrot;
			v = v * cosrot + t * sinrot;
		}
		ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
		ptr++;
	}
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
}
Example #14
0
void FGLRenderer::DrawTexture(FTexture *img, DrawParms &parms)
{
	double xscale = parms.destwidth / parms.texwidth;
	double yscale = parms.destheight / parms.texheight;
	double x = parms.x - parms.left * xscale;
	double y = parms.y - parms.top * yscale;
	double w = parms.destwidth;
	double h = parms.destheight;
	float u1, v1, u2, v2;
	int light = 255;

	FMaterial * gltex = FMaterial::ValidateTexture(img, false);

	if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
	{
		// Right now there's only black. Should be implemented properly later
		light = 255 - APART(parms.colorOverlay);
		parms.colorOverlay = 0;
	}

	gl_SetRenderStyle(parms.style, !parms.masked, false);
	if (!img->bHasCanvas)
	{
		int translation = 0;
		if (!parms.alphaChannel)
		{
			if (parms.remap != NULL && !parms.remap->Inactive)
			{
				GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
				if (pal) translation = -pal->GetIndex();
			}
		}
		gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, -1, !!(parms.style.Flags & STYLEF_RedIsAlpha));

		u1 = gltex->GetUL();
		v1 = gltex->GetVT();
		u2 = gltex->GetUR();
		v2 = gltex->GetVB();

	}
	else
	{
		gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false);
		u1 = 0.f;
		v1 = 1.f;
		u2 = 1.f;
		v2 = 0.f;
		gl_RenderState.SetTextureMode(TM_OPAQUE);
	}
	
	if (parms.flipX)
	{
		float temp = u1;
		u1 = u2;
		u2 = temp;
	}
	

	if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
	{
		double wi = MIN(parms.windowright, parms.texwidth);
		x += parms.windowleft * xscale;
		w -= (parms.texwidth - wi + parms.windowleft) * xscale;

		u1 = float(u1 + parms.windowleft / parms.texwidth);
		u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
	}

	PalEntry color;
	if (parms.style.Flags & STYLEF_ColorIsFixed)
	{
		color = parms.fillcolor;
	}
	else
	{
		color = PalEntry(light, light, light);
	}
	color.a = (BYTE)(parms.Alpha * 255);

	// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
	int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
	btm = SCREENHEIGHT - btm;

	glEnable(GL_SCISSOR_TEST);
	int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2;
	glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip);
	
	gl_RenderState.SetColor(color);
	gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
	gl_RenderState.Apply();

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(x, y, 0, u1, v1); ptr++;
	ptr->Set(x, y + h, 0, u1, v2); ptr++;
	ptr->Set(x + w, y, 0, u2, v1); ptr++;
	ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

	if (parms.colorOverlay)
	{
		gl_RenderState.SetTextureMode(TM_MASK);
		gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		gl_RenderState.BlendEquation(GL_FUNC_ADD);
		gl_RenderState.SetColor(PalEntry(parms.colorOverlay));
		gl_RenderState.Apply();

		FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(x, y, 0, u1, v1); ptr++;
		ptr->Set(x, y + h, 0, u1, v2); ptr++;
		ptr->Set(x + w, y, 0, u2, v1); ptr++;
		ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	}

	glScissor(0, 0, screen->GetWidth(), screen->GetHeight());
	glDisable(GL_SCISSOR_TEST);
	gl_RenderState.SetTextureMode(TM_MODULATE);
	gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	gl_RenderState.BlendEquation(GL_FUNC_ADD);
}
Example #15
0
bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
{
    bool done;

    BurnTime += ticks;
    ticks *= 2;

    // Make the fire burn
    done = false;
    while (!done && ticks--)
    {
        Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
        done = (Density < 0);
    }

    if (BurnTexture != NULL) delete BurnTexture;
    BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true);

    // Update the burn texture with the new burn data
    BYTE rgb_buffer[WIDTH*HEIGHT*4];

    const BYTE *src = BurnArray;
    DWORD *dest = (DWORD *)rgb_buffer;
    for (int y = HEIGHT; y != 0; --y)
    {
        for (int x = WIDTH; x != 0; --x)
        {
            BYTE s = clamp<int>((*src++)*2, 0, 255);
            *dest++ = MAKEARGB(s,255,255,255);
        }
    }

    float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
    float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());


    // Put the initial screen back to the buffer.
    gl_RenderState.SetTextureMode(TM_OPAQUE);
    gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();
    fb->wipestartscreen->Bind(0, 0, false);
    FFlatVertex *ptr;
    unsigned int offset, count;
    ptr = GLRenderer->mVBO->GetBuffer();
    ptr->Set(0, 0, 0, 0, vb);
    ptr++;
    ptr->Set(0, fb->Height, 0, 0, 0);
    ptr++;
    ptr->Set(fb->Width, 0, 0, ur, vb);
    ptr++;
    ptr->Set(fb->Width, fb->Height, 0, ur, 0);
    ptr++;
    GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);

    gl_RenderState.SetTextureMode(TM_MODULATE);
    gl_RenderState.SetEffect(EFF_BURN);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();

    // Burn the new screen on top of it.
    fb->wipeendscreen->Bind(0, 0, false);

    BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0);

    GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
    gl_RenderState.SetEffect(EFF_NONE);

    // The fire may not always stabilize, so the wipe is forced to end
    // after an arbitrary maximum time.
    return done || (BurnTime > 40);
}
Example #16
0
bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
{
    float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
    float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());

    // Draw the new screen on the bottom.
    gl_RenderState.SetTextureMode(TM_OPAQUE);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();
    fb->wipeendscreen->Bind(0, 0, false);
    FFlatVertex *ptr;
    ptr = GLRenderer->mVBO->GetBuffer();
    ptr->Set(0, 0, 0, 0, vb);
    ptr++;
    ptr->Set(0, fb->Height, 0, 0, 0);
    ptr++;
    ptr->Set(fb->Width, 0, 0, ur, vb);
    ptr++;
    ptr->Set(fb->Width, fb->Height, 0, ur, 0);
    ptr++;
    GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

    int i, dy;
    bool done = false;

    fb->wipestartscreen->Bind(0, 0, false);
    // Copy the old screen in vertical strips on top of the new one.
    while (ticks--)
    {
        done = true;
        for (i = 0; i < WIDTH; i++)
        {
            if (y[i] < 0)
            {
                y[i]++;
                done = false;
            }
            else if (y[i] < HEIGHT)
            {
                dy = (y[i] < 16) ? y[i]+1 : 8;
                y[i] = MIN(y[i] + dy, HEIGHT);
                done = false;
            }
            if (ticks == 0)
            {
                // Only draw for the final tick.
                // No need for optimization. Wipes won't ever be drawn with anything else.
                RECT rect;
                POINT dpt;

                dpt.x = i * fb->Width / WIDTH;
                dpt.y = MAX(0, y[i] * fb->Height / HEIGHT);
                rect.left = dpt.x;
                rect.top = 0;
                rect.right = (i + 1) * fb->Width / WIDTH;
                rect.bottom = fb->Height - dpt.y;
                if (rect.bottom > rect.top)
                {
                    float tw = (float)FHardwareTexture::GetTexDimension(fb->Width);
                    float th = (float)FHardwareTexture::GetTexDimension(fb->Height);
                    rect.bottom = fb->Height - rect.bottom;
                    rect.top = fb->Height - rect.top;

                    ptr = GLRenderer->mVBO->GetBuffer();
                    ptr->Set(rect.left, rect.bottom, 0, rect.left / tw, rect.top / th);
                    ptr++;
                    ptr->Set(rect.left, rect.top, 0, rect.left / tw, rect.bottom / th);
                    ptr++;
                    ptr->Set(rect.right, rect.bottom, 0, rect.right / tw, rect.top / th);
                    ptr++;
                    ptr->Set(rect.right, rect.top, 0, rect.right / tw, rect.bottom / th);
                    ptr++;
                    GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
                }
            }
        }
    }
    gl_RenderState.SetTextureMode(TM_MODULATE);
    return done;
}
Example #17
0
void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture)
{
	float			fU1,fV1;
	float			fU2,fV2;
	float			tx;
	float			x1,y1,x2,y2;
	float			scale;
	float			scalex;
	float			ftexturemid;
	                      // 4:3  16:9   16:10  17:10    5:4  17:10    21:9
	static float xratio[] = {1.f, 3.f/4, 5.f/6, 40.f/51, 1.f, 40.f/51, 4.f/7};
	
	// [BB] In the HUD model step we just render the model and break out. 
	if ( hudModelStep )
	{
		gl_RenderHUDModel(psp, sx, sy);
		return;
	}

	// decide which patch to use
	bool mirror;
	FTextureID lump = gl_GetSpriteFrame(psp->GetSprite(), psp->GetFrame(), 0, 0, &mirror);
	if (!lump.isValid()) return;

	FMaterial * tex = FMaterial::ValidateTexture(lump, true, false);
	if (!tex) return;

	gl_RenderState.SetMaterial(tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture);

	float vw = (float)viewwidth;
	float vh = (float)viewheight;

	FloatRect r;
	tex->GetSpriteRect(&r);

	// calculate edges of the shape
	scalex = xratio[WidescreenRatio] * vw / 320;

	tx = sx - (160 - r.left);
	x1 = tx * scalex + vw/2;
	if (x1 > vw)	return; // off the right side
	x1 += viewwindowx;

	tx += r.width;
	x2 = tx * scalex + vw / 2;
	if (x2 < 0) return; // off the left side
	x2 += viewwindowx;


	// killough 12/98: fix psprite positioning problem
	ftexturemid = 100.f - sy - r.top;

	AWeapon * wi=player->ReadyWeapon;
	if (wi && wi->YAdjust != 0)
	{
		float fYAd = wi->YAdjust;
		if (screenblocks >= 11)
		{
			ftexturemid -= fYAd;
		}
		else if (!st_scale)
		{
			ftexturemid -= StatusBar->GetDisplacement () * fYAd;
		}
	}

	scale = (SCREENHEIGHT*vw) / (SCREENWIDTH * 200.0f);
	y1 = viewwindowy + vh / 2 - (ftexturemid * scale);
	y2 = y1 + (r.height * scale) + 1;

	if (!mirror)
	{
		fU1=tex->GetSpriteUL();
		fV1=tex->GetSpriteVT();
		fU2=tex->GetSpriteUR();
		fV2=tex->GetSpriteVB();
	}
	else
	{
		fU2=tex->GetSpriteUL();
		fV1=tex->GetSpriteVT();
		fU1=tex->GetSpriteUR();
		fV2=tex->GetSpriteVB();
	}

	if (tex->GetTransparent() || OverrideShader != -1)
	{
		gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
	}
	gl_RenderState.Apply();
	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(x1, y1, 0, fU1, fV1);
	ptr++;
	ptr->Set(x1, y2, 0, fU1, fV2);
	ptr++;
	ptr->Set(x2, y1, 0, fU2, fV1);
	ptr++;
	ptr->Set(x2, y2, 0, fU2, fV2);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
}
Example #18
0
static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool sky2)
{
	FSkyBox * sb = static_cast<FSkyBox*>(gltex->tex);
	int faces;
	FMaterial * tex;

	gl_RenderState.EnableModelMatrix(true);
	gl_RenderState.mModelMatrix.loadIdentity();

	if (!sky2)
		gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y);
	else
		gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y);

	FFlatVertex *ptr;
	if (sb->faces[5]) 
	{
		faces=4;

		// north
		tex = FMaterial::ValidateTexture(sb->faces[0], false);
		gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
		gl_RenderState.Apply();

		ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(128.f, 128.f, -128.f, 0, 0);
		ptr++;
		ptr->Set(-128.f, 128.f, -128.f, 1, 0);
		ptr++;
		ptr->Set(128.f, -128.f, -128.f, 0, 1);
		ptr++;
		ptr->Set(-128.f, -128.f, -128.f, 1, 1);
		ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

		// east
		tex = FMaterial::ValidateTexture(sb->faces[1], false);
		gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
		gl_RenderState.Apply();

		ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(-128.f, 128.f, -128.f, 0, 0);
		ptr++;
		ptr->Set(-128.f, 128.f, 128.f, 1, 0);
		ptr++;
		ptr->Set(-128.f, -128.f, -128.f, 0, 1);
		ptr++;
		ptr->Set(-128.f, -128.f, 128.f, 1, 1);
		ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

		// south
		tex = FMaterial::ValidateTexture(sb->faces[2], false);
		gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
		gl_RenderState.Apply();

		ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(-128.f, 128.f, 128.f, 0, 0);
		ptr++;
		ptr->Set(128.f, 128.f, 128.f, 1, 0);
		ptr++;
		ptr->Set(-128.f, -128.f, 128.f, 0, 1);
		ptr++;
		ptr->Set(128.f, -128.f, 128.f, 1, 1);
		ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

		// west
		tex = FMaterial::ValidateTexture(sb->faces[3], false);
		gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
		gl_RenderState.Apply();

		ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(128.f, 128.f, 128.f, 0, 0);
		ptr++;
		ptr->Set(128.f, 128.f, -128.f, 1, 0);
		ptr++;
		ptr->Set(128.f, -128.f, 128.f, 0, 1);
		ptr++;
		ptr->Set(128.f, -128.f, -128.f, 1, 1);
		ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	}
	else 
	{
		faces=1;
		tex = FMaterial::ValidateTexture(sb->faces[0], false);
		gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
		gl_RenderState.Apply();

		ptr = GLRenderer->mVBO->GetBuffer();
		ptr->Set(128.f, 128.f, -128.f, 0, 0);
		ptr++;
		ptr->Set(128.f, -128.f, -128.f, 0, 1);
		ptr++;
		ptr->Set(-128.f, 128.f, -128.f, 0.25f, 0);
		ptr++;
		ptr->Set(-128.f, -128.f, -128.f, 0.25f, 1);
		ptr++;
		ptr->Set(-128.f, 128.f, 128.f, 0.5f, 0);
		ptr++;
		ptr->Set(-128.f, -128.f, 128.f, 0.5f, 1);
		ptr++;
		ptr->Set(128.f, 128.f, 128.f, 0.75f, 0);
		ptr++;
		ptr->Set(128.f, -128.f, 128.f, 0.75f, 1);
		ptr++;
		ptr->Set(128.f, 128.f, -128.f, 1, 0);
		ptr++;
		ptr->Set(128.f, -128.f, -128.f, 1, 1);
		ptr++;
		GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	}

	// top
	tex = FMaterial::ValidateTexture(sb->faces[faces], false);
	gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
	gl_RenderState.Apply();

	ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(128.f, 128.f, -128.f, 0, sb->fliptop);
	ptr++;
	ptr->Set(-128.f, 128.f, -128.f, 1, sb->fliptop);
	ptr++;
	ptr->Set(128.f, 128.f, 128.f, 0, !sb->fliptop);
	ptr++;
	ptr->Set(-128.f, 128.f, 128.f, 1, !sb->fliptop);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

	// bottom
	tex = FMaterial::ValidateTexture(sb->faces[faces+1], false);
	gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
	gl_RenderState.Apply();

	ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(128.f, -128.f, -128.f, 0, 0);
	ptr++;
	ptr->Set(-128.f, -128.f, -128.f, 1, 0);
	ptr++;
	ptr->Set(128.f, -128.f, 128.f, 0, 1);
	ptr++;
	ptr->Set(-128.f, -128.f, 128.f, 1, 1);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
	gl_RenderState.EnableModelMatrix(false);
}