示例#1
0
void fhPointBuffer::entry_t::Commit() {
  const int verticesUsed = vertices.Num();

  if (verticesUsed > 0)
  {
    glPointSize(size);
    GL_UseProgram(vertexColorProgram);

    fhRenderProgram::SetModelViewMatrix(GL_ModelViewMatrix.Top());
    fhRenderProgram::SetProjectionMatrix(GL_ProjectionMatrix.Top());
	fhRenderProgram::SetDiffuseColor(idVec4(1,1,1,1));
	fhRenderProgram::SetColorAdd(idVec4(0,0,0,0));
	fhRenderProgram::SetColorModulate(idVec4(1,1,1,1));

    int verticesCommitted = 0;
    while (verticesCommitted < verticesUsed)
    {
      int verticesToCommit = std::min(maxVerticesPerCommit, verticesUsed - verticesCommitted);

      auto vert = vertexCache.AllocFrameTemp(&vertices[verticesCommitted], verticesToCommit * sizeof(fhSimpleVert));
      int offset = vertexCache.Bind(vert);

	  GL_SetupVertexAttributes(fhVertexLayout::DrawPosColorOnly, offset);

      glDrawElements(GL_POINTS,
        verticesToCommit,
        GL_UNSIGNED_SHORT,
        ::indices());

      verticesCommitted += verticesToCommit;
    }

    glPointSize(1);
  }
}
示例#2
0
void fhImmediateMode::End()
{
	active = false;
	if (!drawVertsUsed)
		return;

	auto vert = vertexCache.AllocFrameTemp(drawVerts, drawVertsUsed * sizeof(fhSimpleVert));
	drawCallVertexSize += drawVertsUsed * sizeof(fhSimpleVert);
	int offset = vertexCache.Bind(vert);

	if (!geometryOnly) {
		if (currentTexture) {
			currentTexture->Bind(1);

			if (currentTexture->type == TT_CUBIC) {
				GL_UseProgram(skyboxProgram);
			}
			else if (currentTexture->internalFormat == GL_DEPTH_COMPONENT) {
				GL_UseProgram(debugDepthProgram);
			}
			else {
				GL_UseProgram(defaultProgram);			
			}
		}
		else {
			GL_UseProgram(vertexColorProgram);
		}

		fhRenderProgram::SetModelViewMatrix(GL_ModelViewMatrix.Top());
		fhRenderProgram::SetProjectionMatrix(GL_ProjectionMatrix.Top());
		fhRenderProgram::SetDiffuseColor(idVec4::one);
		fhRenderProgram::SetColorAdd(idVec4::zero);
		fhRenderProgram::SetColorModulate(idVec4::one);
		fhRenderProgram::SetBumpMatrix(idVec4(1,0,0,0), idVec4(0,1,0,0));
	}

	GL_SetupVertexAttributes(fhVertexLayout::Simple, offset);

	GLenum mode = currentMode;

	if (mode == GL_QUADS || mode == GL_POLYGON || mode == GL_QUAD_STRIP) //quads and polygons are replaced by triangles in GLSL mode
		mode = GL_TRIANGLES;

	glDrawElements(mode,
		drawVertsUsed,
		GL_UNSIGNED_SHORT,
		lineIndices);

	drawCallCount++;

	GL_SetVertexLayout(fhVertexLayout::None);

	if (!geometryOnly) {
		GL_UseProgram(nullptr);
	}

	drawVertsUsed = 0;
	currentMode = GL_INVALID_ENUM;
}
示例#3
0
void fhTrisBuffer::Commit(idImage* texture, const idVec4& colorModulate, const idVec4& colorAdd) {
  const int verticesUsed = vertices.Num();

  if (verticesUsed > 0)
  {
    if (texture) {
      texture->Bind(1);
      if (texture->type == TT_CUBIC)
        GL_UseProgram(skyboxProgram);
      else
        GL_UseProgram(defaultProgram);
    }
    else {
      GL_UseProgram(vertexColorProgram);
    }

    fhRenderProgram::SetModelViewMatrix(GL_ModelViewMatrix.Top());
    fhRenderProgram::SetProjectionMatrix(GL_ProjectionMatrix.Top());
    fhRenderProgram::SetDiffuseColor(idVec4(1,1,1,1));
	fhRenderProgram::SetColorAdd(colorAdd);
	fhRenderProgram::SetColorModulate(colorModulate);
	fhRenderProgram::SetBumpMatrix(idVec4(1,0,0,0), idVec4(0,1,0,0));

    int verticesCommitted = 0;
    while (verticesCommitted < verticesUsed)
    {
      int verticesToCommit = std::min(maxVerticesPerCommit, verticesUsed - verticesCommitted);

      auto vert = vertexCache.AllocFrameTemp(&vertices[verticesCommitted], verticesToCommit * sizeof(fhSimpleVert));
      int offset = vertexCache.Bind(vert);

	  GL_SetupVertexAttributes(fhVertexLayout::Simple, offset);

      glDrawElements(GL_TRIANGLES,
        verticesToCommit,
        GL_UNSIGNED_SHORT,
        indices());

      verticesCommitted += verticesToCommit;
    }
  }
}
示例#4
0
void fhLineBuffer::Commit()
{
  if(verticesUsed > 0)
  {
    GL_UseProgram(vertexColorProgram);

    fhRenderProgram::SetModelViewMatrix(GL_ModelViewMatrix.Top());
    fhRenderProgram::SetProjectionMatrix(GL_ProjectionMatrix.Top());
	fhRenderProgram::SetDiffuseColor(idVec4::one);
	fhRenderProgram::SetColorAdd(idVec4::zero);
	fhRenderProgram::SetColorModulate(idVec4::one);
	fhRenderProgram::SetBumpMatrix(idVec4(1,0,0,0), idVec4(0,1,0,0));

    int verticesCommitted = 0;
    while(verticesCommitted < verticesUsed)
    {
      static const int maxVerticesPerCommit = (sizeof(lineIndices)/sizeof(lineIndices[0]))/2;

      int verticesToCommit = Min(maxVerticesPerCommit, verticesUsed - verticesCommitted);

      auto vert = vertexCache.AllocFrameTemp(&vertices[verticesCommitted], verticesToCommit * sizeof(fhSimpleVert));
      int offset = vertexCache.Bind(vert);

	  GL_SetupVertexAttributes(fhVertexLayout::Simple, offset);

      glDrawElements(GL_LINES,
        verticesToCommit,
        GL_UNSIGNED_SHORT,
        lineIndices);

      verticesCommitted += verticesToCommit;
    }
  }

  verticesUsed = 0;
}
示例#5
0
void fhImmediateMode::Sphere(float radius, int rings, int sectors, bool inverse)
{
  assert(!active);
  assert(radius > 0.0f);
  assert(rings > 1);
  assert(sectors > 1);

  float const R = 1. / (float)(rings - 1);
  float const S = 1. / (float)(sectors - 1);  

  int vertexNum = 0;   
  for (int r = 0; r < rings; r++) {
    for (int s = 0; s < sectors; s++) {
      float const y = sin(-(idMath::PI/2.0f) + idMath::PI * r * R);
      float const x = cos(2 * idMath::PI * s * S) * sin(idMath::PI * r * R);
      float const z = sin(2 * idMath::PI * s * S) * sin(idMath::PI * r * R);

      drawVerts[vertexNum].xyz.x = x * radius;
      drawVerts[vertexNum].xyz.y = y * radius;
      drawVerts[vertexNum].xyz.z = z * radius;
      drawVerts[vertexNum].st.x = s*S;
      drawVerts[vertexNum].st.y = r*R;
      drawVerts[vertexNum].color[0] = currentColor[0];
      drawVerts[vertexNum].color[1] = currentColor[1];
      drawVerts[vertexNum].color[2] = currentColor[2];
      drawVerts[vertexNum].color[3] = currentColor[3];

      vertexNum += 1;
    }
  }

  int indexNum = 0;
  for (int r = 0; r < rings - 1; r++) {
    for (int s = 0; s < sectors - 1; s++) {
      if(r == 0) {
        //faces of first ring are single triangles
        sphereIndices[indexNum + 2] = r * sectors + s;        
        sphereIndices[indexNum + 1] = (r + 1) * sectors + s;
        sphereIndices[indexNum + 0] = (r + 1) * sectors + (s + 1);

        indexNum += 3;
      } else if (r == rings - 2) {
        //faces of last ring are single triangles
        sphereIndices[indexNum + 0] = r * sectors + s;
        sphereIndices[indexNum + 1] = r * sectors + (s + 1);
        sphereIndices[indexNum + 2] = (r + 1) * sectors + (s + 1);

        indexNum += 3;
      } else {
        //faces of remaining rings are quads (two triangles)
        sphereIndices[indexNum + 0] = r * sectors + s;
        sphereIndices[indexNum + 1] = r * sectors + (s + 1);
        sphereIndices[indexNum + 2] = (r + 1) * sectors + (s + 1);

        sphereIndices[indexNum + 3] = sphereIndices[indexNum + 2];
        sphereIndices[indexNum + 4] = (r + 1) * sectors + s;
        sphereIndices[indexNum + 5] = sphereIndices[indexNum + 0];

        indexNum += 6;
      }
    }
  } 

  if(inverse) {
    for(int i = 0; i+2 < indexNum; i += 3) {
      unsigned short tmp = sphereIndices[i];
      sphereIndices[i] = sphereIndices[i+2];
      sphereIndices[i+2] = tmp;
    }
  }
  
  GL_UseProgram(vertexColorProgram);  

  auto vert = vertexCache.AllocFrameTemp(drawVerts, vertexNum * sizeof(fhSimpleVert));
  int offset = vertexCache.Bind(vert);

  fhRenderProgram::SetModelViewMatrix(GL_ModelViewMatrix.Top());
  fhRenderProgram::SetProjectionMatrix(GL_ProjectionMatrix.Top());
  fhRenderProgram::SetDiffuseColor(idVec4::one);
  fhRenderProgram::SetBumpMatrix(idVec4(1,0,0,0), idVec4(0,1,0,0));

  GL_SetupVertexAttributes(fhVertexLayout::Simple, offset);

  glDrawElements(GL_TRIANGLES,
    indexNum,
    GL_UNSIGNED_SHORT,
    sphereIndices);

  GL_SetVertexLayout(fhVertexLayout::None);  
  GL_UseProgram(nullptr);
}
static void RB_GLSL_SubmitDrawInteractions(const viewLight_t& vLight, const InteractionList& interactionList) {
	if (interactionList.IsEmpty())
		return;

	// perform setup here that will be constant for all interactions
	GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );

	GL_UseProgram( interactionProgram );

	fhRenderProgram::SetShading( r_shading.GetInteger() );
	fhRenderProgram::SetSpecularExp( r_specularExp.GetFloat() );
	fhRenderProgram::SetAmbientLight( vLight.lightDef->lightShader->IsAmbientLight() ? 1 : 0 );

	if (vLight.lightDef->ShadowMode() == shadowMode_t::ShadowMap) {
		const idVec4 globalLightOrigin = idVec4( vLight.globalLightOrigin, 1 );
		fhRenderProgram::SetGlobalLightOrigin( globalLightOrigin );

		const float shadowBrightness = vLight.lightDef->ShadowBrightness();
		const float shadowSoftness = vLight.lightDef->ShadowSoftness();
		fhRenderProgram::SetShadowParams( idVec4( shadowSoftness, shadowBrightness, vLight.nearClip[0], vLight.farClip[0] ) );

		if(vLight.lightDef->parms.parallel) {
			//parallel light
			fhRenderProgram::SetShadowMappingMode( 3 );
			fhRenderProgram::SetPointLightProjectionMatrices( vLight.viewProjectionMatrices[0].ToFloatPtr() );
			fhRenderProgram::SetShadowCoords( vLight.shadowCoords, 6 );
			fhRenderProgram::SetCascadeDistances(
				r_smCascadeDistance0.GetFloat(),
				r_smCascadeDistance1.GetFloat(),
				r_smCascadeDistance2.GetFloat(),
				r_smCascadeDistance3.GetFloat(),
				r_smCascadeDistance4.GetFloat());

			idVec4 shadowmapSizes[6] = {
				idVec4(vLight.nearClip[0], vLight.farClip[0], vLight.width[0], vLight.height[0]),
				idVec4(vLight.nearClip[1], vLight.farClip[1], vLight.width[1], vLight.height[1]),
				idVec4(vLight.nearClip[2], vLight.farClip[2], vLight.width[2], vLight.height[2]),
				idVec4(vLight.nearClip[3], vLight.farClip[3], vLight.width[3], vLight.height[3]),
				idVec4(vLight.nearClip[4], vLight.farClip[4], vLight.width[4], vLight.height[4]),
				idVec4(vLight.nearClip[5], vLight.farClip[5], vLight.width[5], vLight.height[5])
			};

			fhRenderProgram::SetShadowMapSize(shadowmapSizes, 6);
		}
		else if (vLight.lightDef->parms.pointLight) {
			//point light
			fhRenderProgram::SetShadowMappingMode( 1 );
			fhRenderProgram::SetPointLightProjectionMatrices( vLight.viewProjectionMatrices[0].ToFloatPtr() );
			fhRenderProgram::SetShadowCoords(vLight.shadowCoords, 6);

			{
				const idMat3 axis = vLight.lightDef->parms.axis;

				float viewerMatrix[16];

				viewerMatrix[0] = axis[0][0];
				viewerMatrix[4] = axis[0][1];
				viewerMatrix[8] = axis[0][2];
				viewerMatrix[12] = 0;

				viewerMatrix[1] = axis[1][0];
				viewerMatrix[5] = axis[1][1];
				viewerMatrix[9] = axis[1][2];
				viewerMatrix[13] = 0;

				viewerMatrix[2] = axis[2][0];
				viewerMatrix[6] = axis[2][1];
				viewerMatrix[10] = axis[2][2];
				viewerMatrix[14] = 0;

				viewerMatrix[3] = 0;
				viewerMatrix[7] = 0;
				viewerMatrix[11] = 0;
				viewerMatrix[15] = 1;

				fhRenderProgram::SetInverseLightRotation( viewerMatrix );
			}
		}
		else {
			//projected light
			fhRenderProgram::SetShadowMappingMode( 2 );
			fhRenderProgram::SetSpotLightProjectionMatrix( vLight.viewProjectionMatrices[0].ToFloatPtr() );
			fhRenderProgram::SetShadowCoords(vLight.shadowCoords, 1);
		}
	}
	else {
		//no shadows
		fhRenderProgram::SetShadowMappingMode( 0 );
	}

	//make sure depth hacks are disabled
	//FIXME(johl): why is (sometimes) a depth hack enabled at this point?
	RB_LeaveDepthHack();

	fhRenderProgram::SetProjectionMatrix( backEnd.viewDef->projectionMatrix );
	fhRenderProgram::SetPomMaxHeight( -1 );

	const viewEntity_t* currentSpace = nullptr;
	stageVertexColor_t currentVertexColor = (stageVertexColor_t)-1;
	bool currentPomEnabled = false;
	idScreenRect currentScissor;
	bool depthHackActive = false;
	bool currentHasBumpMatrix = false;
	bool currentHasDiffuseMatrix = false;
	bool currentHasSpecularMatrix = false;
	idVec4 currentDiffuseColor = idVec4( 1, 1, 1, 1 );
	idVec4 currentSpecularColor = idVec4( 1, 1, 1, 1 );

	fhRenderProgram::SetDiffuseColor( currentDiffuseColor );
	fhRenderProgram::SetSpecularColor( currentSpecularColor );
	fhRenderProgram::SetBumpMatrix( idVec4::identityS, idVec4::identityT );
	fhRenderProgram::SetSpecularMatrix( idVec4::identityS, idVec4::identityT );
	fhRenderProgram::SetDiffuseMatrix( idVec4::identityS, idVec4::identityT );

	glDepthRange(0, 1);

	if (r_useScissor.GetBool()) {
		auto fb = fhFramebuffer::GetCurrentDrawBuffer();
		glScissor( 0, 0, fb->GetWidth(), fb->GetHeight() );
		currentScissor.x1 = 0;
		currentScissor.y1 = 0;
		currentScissor.x2 = fb->GetWidth();
		currentScissor.y2 = fb->GetHeight();
	}

	const int num = interactionList.Num();
	for (int i = 0; i < num; ++i) {
		const auto& din = interactionList[i];

		const auto offset = vertexCache.Bind( din.surf->geo->ambientCache );
		GL_SetupVertexAttributes( fhVertexLayout::Draw, offset );

		if (currentSpace != din.surf->space) {
			fhRenderProgram::SetModelMatrix( din.surf->space->modelMatrix );
			fhRenderProgram::SetModelViewMatrix( din.surf->space->modelViewMatrix );

			if (din.surf->space->modelDepthHack) {
				RB_EnterModelDepthHack( din.surf->space->modelDepthHack );
				fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() );
				depthHackActive = true;
			}
			else if (din.surf->space->weaponDepthHack) {
				RB_EnterWeaponDepthHack();
				fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() );
				depthHackActive = true;
			}
			else if (depthHackActive) {
				RB_LeaveDepthHack();
				fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() );
				depthHackActive = false;
			}

			// change the scissor if needed
			if (r_useScissor.GetBool() && !currentScissor.Equals( din.surf->scissorRect )) {
				currentScissor = din.surf->scissorRect;
				glScissor( backEnd.viewDef->viewport.x1 + currentScissor.x1,
					backEnd.viewDef->viewport.y1 + currentScissor.y1,
					currentScissor.x2 + 1 - currentScissor.x1,
					currentScissor.y2 + 1 - currentScissor.y1 );
			}

			currentSpace = din.surf->space;
		}

		fhRenderProgram::SetLocalLightOrigin( din.localLightOrigin );
		fhRenderProgram::SetLocalViewOrigin( din.localViewOrigin );
		fhRenderProgram::SetLightProjectionMatrix( din.lightProjection[0], din.lightProjection[1], din.lightProjection[2] );
		fhRenderProgram::SetLightFallOff( din.lightProjection[3] );

		if (din.hasBumpMatrix) {
			fhRenderProgram::SetBumpMatrix( din.bumpMatrix[0], din.bumpMatrix[1] );
			currentHasBumpMatrix = true;
		}
		else if (currentHasBumpMatrix) {
			fhRenderProgram::SetBumpMatrix( idVec4::identityS, idVec4::identityT );
			currentHasBumpMatrix = false;
		}

		if (din.hasDiffuseMatrix) {
			fhRenderProgram::SetDiffuseMatrix( din.diffuseMatrix[0], din.diffuseMatrix[1] );
			currentHasDiffuseMatrix = true;
		}
		else if (currentHasDiffuseMatrix) {
			fhRenderProgram::SetDiffuseMatrix( idVec4::identityS, idVec4::identityT );
			currentHasDiffuseMatrix = false;
		}

		if (din.hasSpecularMatrix) {
			fhRenderProgram::SetSpecularMatrix( din.specularMatrix[0], din.specularMatrix[1] );
			currentHasSpecularMatrix = true;
		}
		else if (currentHasSpecularMatrix) {
			fhRenderProgram::SetSpecularMatrix( idVec4::identityS, idVec4::identityT );
			currentHasSpecularMatrix = false;
		}

		if (currentVertexColor != din.vertexColor) {
			switch (din.vertexColor) {
			case SVC_IGNORE:
				fhRenderProgram::SetColorModulate( idVec4::zero );
				fhRenderProgram::SetColorAdd( idVec4::one );
				break;
			case SVC_MODULATE:
				fhRenderProgram::SetColorModulate( idVec4::one );
				fhRenderProgram::SetColorAdd( idVec4::zero );
				break;
			case SVC_INVERSE_MODULATE:
				fhRenderProgram::SetColorModulate( idVec4::negOne );
				fhRenderProgram::SetColorAdd( idVec4::one );
				break;
			}
			currentVertexColor = din.vertexColor;
		}

		if (din.diffuseColor != currentDiffuseColor) {
			fhRenderProgram::SetDiffuseColor( din.diffuseColor );
			currentDiffuseColor = din.diffuseColor;
		}

		if (din.specularColor != currentSpecularColor) {
			fhRenderProgram::SetSpecularColor( din.specularColor );
			currentSpecularColor = din.specularColor;
		}

		const bool pomEnabled = r_pomEnabled.GetBool() && din.specularImage->hasAlpha;
		if (pomEnabled != currentPomEnabled) {
			if (pomEnabled) {
				fhRenderProgram::SetPomMaxHeight( r_pomMaxHeight.GetFloat() );
			}
			else {
				fhRenderProgram::SetPomMaxHeight( -1 );
			}
		}

		fhRenderProgram::SetNormalMapEncoding( RB_GetNormalEncoding( din.bumpImage ) );

		din.bumpImage->Bind( 1 );
		din.lightFalloffImage->Bind( 2 );
		din.lightImage->Bind( 3 );
		din.diffuseImage->Bind( 4 );
		din.specularImage->Bind( 5 );

		// draw it
		backEnd.stats.groups[backEndGroup::Interaction].drawcalls += 1;
		backEnd.stats.groups[backEndGroup::Interaction].tris += din.surf->geo->numIndexes / 3;
		RB_DrawElementsWithCounters( din.surf->geo );
	}

	if (depthHackActive) {
		RB_LeaveDepthHack();
		fhRenderProgram::SetProjectionMatrix( GL_ProjectionMatrix.Top() );
	}

	if (r_useScissor.GetBool()) {
		auto fb = fhFramebuffer::GetCurrentDrawBuffer();
		glScissor( 0, 0, fb->GetWidth(), fb->GetHeight() );
		backEnd.currentScissor.x1 = 0;
		backEnd.currentScissor.y1 = 0;
		backEnd.currentScissor.x2 = fb->GetWidth();
		backEnd.currentScissor.y2 = fb->GetHeight();
	}
}