/* ================== CM_ValidateFacet If the facet isn't bounded by its borders, we screwed up. ================== */ static qboolean CM_ValidateFacet(cFacet_t * facet) { float plane[4]; int j; winding_t *w; vec3_t bounds[2]; if(facet->surfacePlane == -1) { return qfalse; } VectorCopy4(planes[facet->surfacePlane].plane, plane); w = BaseWindingForPlane(plane, plane[3]); for(j = 0; j < facet->numBorders && w; j++) { if(facet->borderPlanes[j] == -1) { FreeWinding(w); return qfalse; } VectorCopy4(planes[facet->borderPlanes[j]].plane, plane); if(!facet->borderInward[j]) { VectorSubtract(vec3_origin, plane, plane); plane[3] = -plane[3]; } ChopWindingInPlace(&w, plane, plane[3], 0.1f); } if(!w) { return qfalse; // winding was completely chopped away } // see if the facet is unreasonably large WindingBounds(w, bounds[0], bounds[1]); FreeWinding(w); for(j = 0; j < 3; j++) { if(bounds[1][j] - bounds[0][j] > MAX_WORLD_COORD) { return qfalse; // we must be missing a plane } if(bounds[0][j] >= MAX_WORLD_COORD) { return qfalse; } if(bounds[1][j] <= MIN_WORLD_COORD) { return qfalse; } } return qtrue; // winding is fine }
/* ================== CM_FindPlane2 ================== */ static int CM_FindPlane2(float plane[4], int *flipped) { int i; // see if the points are close enough to an existing plane for(i = 0; i < numPlanes; i++) { if(CM_PlaneEqual(&planes[i], plane, flipped)) return i; } // add a new plane if(numPlanes == MAX_PATCH_PLANES) { Com_Error(ERR_DROP, "CM_FindPlane2: MAX_PATCH_PLANES"); } VectorCopy4(plane, planes[numPlanes].plane); planes[numPlanes].signbits = CM_SignbitsForNormal(plane); numPlanes++; *flipped = qfalse; return numPlanes - 1; }
// shows current date and JA++ version static void DrawClientInfo( float fade ) { struct tm *timeinfo; time_t tm; char buf[256]; const qhandle_t fontHandle = MenuFontToHandle( FONT_JAPPMONO ); const float fontScale = 0.5f; const float lineHeight = trap->R_Font_HeightPixels( fontHandle, fontScale ); float y = SCREEN_HEIGHT - lineHeight - 4.0f; vector4 colour; VectorCopy4( &g_color_table[ColorIndex( COLOR_ORANGE )], &colour ); colour.a = fade; #ifdef REVISION // JA++ version trap->R_Font_DrawString( SCREEN_WIDTH - trap->R_Font_StrLenPixels( REVISION, fontHandle, fontScale ) - 21.0f, y, REVISION, &colour, fontHandle | STYLE_DROPSHADOW, -1, fontScale ); y -= lineHeight; #endif // date time( &tm ); timeinfo = localtime( &tm ); Com_sprintf( buf, sizeof(buf), "%s %i%s %04i, %02i:%02i:%02i", months[timeinfo->tm_mon], timeinfo->tm_mday, GetDateSuffix( timeinfo->tm_mday ), 1900 + timeinfo->tm_year, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec ); trap->R_Font_DrawString( SCREEN_WIDTH - trap->R_Font_StrLenPixels( buf, fontHandle, fontScale ) - 12.0f, y, buf, &colour, fontHandle | STYLE_DROPSHADOW, -1, fontScale ); }
/* ============== RB_InstantQuad based on Tess_InstantQuad from xreal ============== */ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4]) { GLimp_LogComment("--- RB_InstantQuad2 ---\n"); tess.numVertexes = 0; tess.numIndexes = 0; tess.firstIndex = 0; VectorCopy4(quadVerts[0], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[0], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[1], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[1], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[2], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[2], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[3], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[3], tess.texCoords[tess.numVertexes]); tess.numVertexes++; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 1; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; tess.minIndex = 0; tess.maxIndex = 3; RB_UpdateTessVao(ATTR_POSITION | ATTR_TEXCOORD); R_DrawElementsVao(tess.numIndexes, tess.firstIndex, tess.minIndex, tess.maxIndex); tess.numIndexes = 0; tess.numVertexes = 0; tess.firstIndex = 0; tess.minIndex = 0; tess.maxIndex = 0; }
/* ================== CM_FindPlane ================== */ static int CM_FindPlane(float *p1, float *p2, float *p3) { float plane[4]; int i; float d; if(!CM_PlaneFromPoints(plane, p1, p2, p3)) { return -1; } // see if the points are close enough to an existing plane for(i = 0; i < numPlanes; i++) { if(DotProduct(plane, planes[i].plane) < 0) { continue; // allow backwards planes? } d = DotProduct(p1, planes[i].plane) - planes[i].plane[3]; if(d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON) { continue; } d = DotProduct(p2, planes[i].plane) - planes[i].plane[3]; if(d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON) { continue; } d = DotProduct(p3, planes[i].plane) - planes[i].plane[3]; if(d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON) { continue; } // found it return i; } // add a new plane if(numPlanes == MAX_PATCH_PLANES) { Com_Error(ERR_DROP, "MAX_PATCH_PLANES"); } VectorCopy4(plane, planes[numPlanes].plane); planes[numPlanes].signbits = CM_SignbitsForNormal(plane); numPlanes++; return numPlanes - 1; }
void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v) { GLint *uniforms = program->uniforms; vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); if (uniforms[uniformNum] == -1) return; if (uniformsInfo[uniformNum].type != GLSL_VEC4) { ri.Printf( PRINT_WARNING, "GLSL_SetUniformVec4: wrong type for uniform %i in program %s\n", uniformNum, program->name); return; } if (VectorCompare4(v, compare)) { return; } VectorCopy4(v, compare); qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]); }
/* ================ CG_DrawHealth ================ */ static void CG_DrawHealth( menuDef_t *menuHUD ) { vec4_t glowColor; playerState_t *ps; int healthAmt, maxAmt; //int i,currValue,inc; double percentage, factor; itemDef_t *focusItem; const char *text; int x; static double fcurrent = 0; vec4_t fadecolor = {1, 1, 1, 0.5f}; static vec4_t draincolor = {1, 0.4f, 0.4f, 1}; static vec4_t fillcolor = {0.4f, 1, 0.4f, 1}; vec4_t opacity; int state = 0; MAKERGBA(opacity, 1, 1, 1, cg.jkg_HUDOpacity); // Can we find the menu? if (!menuHUD) { return; } ps = &cg.snap->ps; // What's the health? healthAmt = ps->stats[STAT_HEALTH]; maxAmt = ps->stats[STAT_MAX_HEALTH]; //if (healthAmt > ps->stats[STAT_MAX_HEALTH]) //{ // healthAmt = ps->stats[STAT_MAX_HEALTH]; //} focusItem = Menu_FindItemByName(menuHUD, "healthbar"); if (focusItem) { percentage = (double)healthAmt / (double)maxAmt; if (percentage > 1) { percentage = 1; } else if (percentage < 0) { percentage = 0; } factor = /*0.62109375f **/ percentage /*+ 0.330078125f*/; /*if(factor > 0.95f) { factor = 1.0f; //eezstreet - mega hack }*/ if (fcurrent < factor) { // Raise it fcurrent += (cg.frameDelta * .0003); // Go up 30% per second if (fcurrent > factor) { // We passed it fcurrent = factor; } } else if (fcurrent > factor) { // Lower it fcurrent -= (cg.frameDelta * .0003); // Go up 30% per second if (fcurrent < factor) { fcurrent = factor; } } else { //Stay the same } if (fcurrent != 0) { if (fcurrent < factor) { state = 1; // We're filling up, draw up to fcurrent solid, and up to factor translucent trap_R_SetColor(opacity); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * fcurrent, focusItem->window.rect.h, 0, 0, fcurrent, 1, focusItem->window.background); fadecolor[3] *= cg.jkg_HUDOpacity; trap_R_SetColor(fadecolor); trap_R_DrawStretchPic(focusItem->window.rect.x + focusItem->window.rect.w * fcurrent, focusItem->window.rect.y, focusItem->window.rect.w * (factor - fcurrent), focusItem->window.rect.h, fcurrent, 0, factor, 1, focusItem->window.background); trap_R_SetColor(NULL); } else if (fcurrent > factor) { state = 2; // We're draining, draw up to factor solid, and up to fcurrent translucent trap_R_SetColor(opacity); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * factor, focusItem->window.rect.h, 0, 0, factor, 1, focusItem->window.background); fadecolor[3] *= cg.jkg_HUDOpacity; trap_R_SetColor(fadecolor); trap_R_DrawStretchPic(focusItem->window.rect.x + focusItem->window.rect.w * factor, focusItem->window.rect.y, focusItem->window.rect.w * (fcurrent - factor), focusItem->window.rect.h, factor, 0, fcurrent, 1, focusItem->window.background); trap_R_SetColor(NULL); } else { state = 0; // Just solid trap_R_SetColor(opacity); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * factor, focusItem->window.rect.h, 0, 0, factor, 1, focusItem->window.background); } } } focusItem = Menu_FindItemByName(menuHUD, "healthtext"); if (focusItem) { // Center and draw the text, apply glow if needed if (state == 1) { VectorCopy4(fillcolor, glowColor); } else if (state == 2) { VectorCopy4(draincolor, glowColor); } else { VectorCopy4(colorWhite, glowColor); if (healthAmt < 25) { // Glow the text from red to white float fade = 0.5f + cos((float)cg.time/250) *.5; glowColor[1] = glowColor[2] = fade; } } glowColor[3] *= cg.jkg_HUDOpacity; text = va("%i / %i", healthAmt, maxAmt); x = ((focusItem->window.rect.w/2) - (trap_R_Font_StrLenPixels(text, cgs.media.hudfont1, 0.6f) / 2)) + focusItem->window.rect.x; trap_R_Font_DrawString( x, focusItem->window.rect.y, text, glowColor, cgs.media.hudfont1, -1, 0.6f); trap_R_SetColor(NULL); } }
/* ============= RB_StretchPic ============= */ const void *RB_StretchPic ( const void *data ) { const stretchPicCommand_t *cmd; shader_t *shader; int numVerts, numIndexes; cmd = (const stretchPicCommand_t *)data; // FIXME: HUGE hack if (glRefConfig.framebufferObject) { if (!tr.renderFbo || backEnd.framePostProcessed) { FBO_Bind(NULL); } else { FBO_Bind(tr.renderFbo); } } RB_SetGL2D(); shader = cmd->shader; if ( shader != tess.shader ) { if ( tess.numIndexes ) { RB_EndSurface(); } backEnd.currentEntity = &backEnd.entity2D; RB_BeginSurface( shader, 0, 0 ); } RB_CHECKOVERFLOW( 4, 6 ); numVerts = tess.numVertexes; numIndexes = tess.numIndexes; tess.numVertexes += 4; tess.numIndexes += 6; tess.indexes[ numIndexes ] = numVerts + 3; tess.indexes[ numIndexes + 1 ] = numVerts + 0; tess.indexes[ numIndexes + 2 ] = numVerts + 2; tess.indexes[ numIndexes + 3 ] = numVerts + 2; tess.indexes[ numIndexes + 4 ] = numVerts + 0; tess.indexes[ numIndexes + 5 ] = numVerts + 1; { vec4_t color; VectorScale4(backEnd.color2D, 1.0f / 255.0f, color); VectorCopy4(color, tess.vertexColors[ numVerts ]); VectorCopy4(color, tess.vertexColors[ numVerts + 1]); VectorCopy4(color, tess.vertexColors[ numVerts + 2]); VectorCopy4(color, tess.vertexColors[ numVerts + 3 ]); } tess.xyz[ numVerts ][0] = cmd->x; tess.xyz[ numVerts ][1] = cmd->y; tess.xyz[ numVerts ][2] = 0; tess.texCoords[ numVerts ][0][0] = cmd->s1; tess.texCoords[ numVerts ][0][1] = cmd->t1; tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w; tess.xyz[ numVerts + 1 ][1] = cmd->y; tess.xyz[ numVerts + 1 ][2] = 0; tess.texCoords[ numVerts + 1 ][0][0] = cmd->s2; tess.texCoords[ numVerts + 1 ][0][1] = cmd->t1; tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w; tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h; tess.xyz[ numVerts + 2 ][2] = 0; tess.texCoords[ numVerts + 2 ][0][0] = cmd->s2; tess.texCoords[ numVerts + 2 ][0][1] = cmd->t2; tess.xyz[ numVerts + 3 ][0] = cmd->x; tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h; tess.xyz[ numVerts + 3 ][2] = 0; tess.texCoords[ numVerts + 3 ][0][0] = cmd->s1; tess.texCoords[ numVerts + 3 ][0][1] = cmd->t2; return (const void *)(cmd + 1); }
void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend) { ivec4_t dstBox, srcBox; vec2_t srcTexScale; vec4_t color; vec4_t quadVerts[4]; vec2_t texCoords[4]; vec2_t invTexRes; FBO_t *oldFbo = glState.currentFBO; mat4_t projection; int width, height; if (!src) return; if (inSrcBox) { VectorSet4(srcBox, inSrcBox[0], inSrcBox[1], inSrcBox[0] + inSrcBox[2], inSrcBox[1] + inSrcBox[3]); } else { VectorSet4(srcBox, 0, 0, src->width, src->height); } // framebuffers are 0 bottom, Y up. if (inDstBox) { if (dst) { dstBox[0] = inDstBox[0]; dstBox[1] = dst->height - inDstBox[1] - inDstBox[3]; dstBox[2] = inDstBox[0] + inDstBox[2]; dstBox[3] = dst->height - inDstBox[1]; } else { dstBox[0] = inDstBox[0]; dstBox[1] = glConfig.vidHeight - inDstBox[1] - inDstBox[3]; dstBox[2] = inDstBox[0] + inDstBox[2]; dstBox[3] = glConfig.vidHeight - inDstBox[1]; } } else if (dst) { VectorSet4(dstBox, 0, dst->height, dst->width, 0); } else { VectorSet4(dstBox, 0, glConfig.vidHeight, glConfig.vidWidth, 0); } if (inSrcTexScale) { VectorCopy2(inSrcTexScale, srcTexScale); } else { srcTexScale[0] = srcTexScale[1] = 1.0f; } if (inColor) { VectorCopy4(inColor, color); } else { VectorCopy4(colorWhite, color); } if (!shaderProgram) { shaderProgram = &tr.textureColorShader; } FBO_Bind(dst); if (glState.currentFBO) { width = glState.currentFBO->width; height = glState.currentFBO->height; } else { width = glConfig.vidWidth; height = glConfig.vidHeight; } qglViewport( 0, 0, width, height ); qglScissor( 0, 0, width, height ); Mat4Ortho(0, width, height, 0, 0, 1, projection); qglDisable( GL_CULL_FACE ); GL_BindToTMU(src, TB_COLORMAP); VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1); VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0, 1); VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0, 1); VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0, 1); texCoords[0][0] = srcBox[0] / (float)src->width; texCoords[0][1] = 1.0f - srcBox[1] / (float)src->height; texCoords[1][0] = srcBox[2] / (float)src->width; texCoords[1][1] = 1.0f - srcBox[1] / (float)src->height; texCoords[2][0] = srcBox[2] / (float)src->width; texCoords[2][1] = 1.0f - srcBox[3] / (float)src->height; texCoords[3][0] = srcBox[0] / (float)src->width; texCoords[3][1] = 1.0f - srcBox[3] / (float)src->height; invTexRes[0] = 1.0f / src->width * srcTexScale[0]; invTexRes[1] = 1.0f / src->height * srcTexScale[1]; GL_State( blend ); GLSL_BindProgram(shaderProgram); GLSL_SetUniformMat4(shaderProgram, UNIFORM_MODELVIEWPROJECTIONMATRIX, projection); GLSL_SetUniformVec4(shaderProgram, UNIFORM_COLOR, color); GLSL_SetUniformVec2(shaderProgram, UNIFORM_INVTEXRES, invTexRes); GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax); GLSL_SetUniformVec3(shaderProgram, UNIFORM_TONEMINAVGMAXLINEAR, tr.refdef.toneMinAvgMaxLinear); RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); FBO_Bind(oldFbo); }
void CG_FilledBar( float x, float y, float w, float h, const float *startColorIn, float *endColor, const float *bgColor, float frac, int flags ) { vec4_t backgroundcolor = {1, 1, 1, 0.25f}, colorAtPos; // colorAtPos is the lerped color if necessary vec4_t startColor; int indent = BAR_BORDERSIZE; VectorCopy4( startColorIn, startColor ); if ( ( flags & BAR_BG ) && bgColor ) { // BAR_BG set, and color specified, use specified bg color Vector4Copy( bgColor, backgroundcolor ); } // hud alpha if ( !( flags & BAR_NOHUDALPHA ) ) { startColor[3] *= cg_hudAlpha.value; if ( endColor ) { endColor[3] *= cg_hudAlpha.value; } if ( backgroundcolor ) { backgroundcolor[3] *= cg_hudAlpha.value; } } if ( flags & BAR_LERP_COLOR ) { Vector4Average( startColor, endColor, frac, colorAtPos ); } // background if ( ( flags & BAR_BG ) ) { // draw background at full size and shrink the remaining box to fit inside with a border. (alternate border may be specified by a BAR_BGSPACING_xx) CG_FillRect( x, y, w, h, backgroundcolor ); if ( flags & BAR_BGSPACING_X0Y0 ) { // fill the whole box (no border) } else if ( flags & BAR_BGSPACING_X0Y5 ) { // spacing created for weapon heat indent *= 3; y += indent; h -= ( 2 * indent ); } else { // default spacing of 2 units on each side x += indent; y += indent; w -= ( 2 * indent ); h -= ( 2 * indent ); } } // adjust for horiz/vertical and draw the fractional box if ( flags & BAR_VERT ) { if ( flags & BAR_LEFT ) { // TODO: remember to swap colors on the ends here y += ( h * ( 1 - frac ) ); } else if ( flags & BAR_CENTER ) { y += ( h * ( 1 - frac ) / 2 ); } if ( flags & BAR_LERP_COLOR ) { CG_FillRect( x, y, w, h * frac, colorAtPos ); } else { // CG_FillRectGradient ( x, y, w, h * frac, startColor, endColor, 0 ); CG_FillRect( x, y, w, h * frac, startColor ); } } else { if ( flags & BAR_LEFT ) { // TODO: remember to swap colors on the ends here x += ( w * ( 1 - frac ) ); } else if ( flags & BAR_CENTER ) { x += ( w * ( 1 - frac ) / 2 ); } if ( flags & BAR_LERP_COLOR ) { CG_FillRect( x, y, w * frac, h, colorAtPos ); } else { // CG_FillRectGradient ( x, y, w * frac, h, startColor, endColor, 0 ); CG_FillRect( x, y, w * frac, h, startColor ); } } }
void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend) { ivec4_t dstBox; vec4_t color; vec4_t quadVerts[4]; vec2_t texCoords[4]; vec2_t invTexRes; FBO_t *oldFbo = glState.currentFBO; mat4_t projection; int width, height; if (!src) { ri.Printf(PRINT_WARNING, "Tried to blit from a NULL texture!\n"); return; } width = dst ? dst->width : glConfig.vidWidth; height = dst ? dst->height : glConfig.vidHeight; if (inSrcTexCorners) { VectorSet2(texCoords[0], inSrcTexCorners[0], inSrcTexCorners[1]); VectorSet2(texCoords[1], inSrcTexCorners[2], inSrcTexCorners[1]); VectorSet2(texCoords[2], inSrcTexCorners[2], inSrcTexCorners[3]); VectorSet2(texCoords[3], inSrcTexCorners[0], inSrcTexCorners[3]); } else { VectorSet2(texCoords[0], 0.0f, 1.0f); VectorSet2(texCoords[1], 1.0f, 1.0f); VectorSet2(texCoords[2], 1.0f, 0.0f); VectorSet2(texCoords[3], 0.0f, 0.0f); } // framebuffers are 0 bottom, Y up. if (inDstBox) { dstBox[0] = inDstBox[0]; dstBox[1] = height - inDstBox[1] - inDstBox[3]; dstBox[2] = inDstBox[0] + inDstBox[2]; dstBox[3] = height - inDstBox[1]; } else { VectorSet4(dstBox, 0, height, width, 0); } if (inSrcTexScale) { VectorCopy2(inSrcTexScale, invTexRes); } else { VectorSet2(invTexRes, 1.0f, 1.0f); } if (inColor) { VectorCopy4(inColor, color); } else { VectorCopy4(colorWhite, color); } if (!shaderProgram) { shaderProgram = &tr.textureColorShader; } FBO_Bind(dst); qglViewport( 0, 0, width, height ); qglScissor( 0, 0, width, height ); Mat4Ortho(0, width, height, 0, 0, 1, projection); GL_Cull( CT_TWO_SIDED ); GL_BindToTMU(src, TB_COLORMAP); VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0.0f, 1.0f); VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0.0f, 1.0f); VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0.0f, 1.0f); VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0.0f, 1.0f); invTexRes[0] /= src->width; invTexRes[1] /= src->height; GL_State( blend ); GLSL_BindProgram(shaderProgram); GLSL_SetUniformMat4(shaderProgram, UNIFORM_MODELVIEWPROJECTIONMATRIX, projection); GLSL_SetUniformVec4(shaderProgram, UNIFORM_COLOR, color); GLSL_SetUniformVec2(shaderProgram, UNIFORM_INVTEXRES, invTexRes); GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax); GLSL_SetUniformVec3(shaderProgram, UNIFORM_TONEMINAVGMAXLINEAR, tr.refdef.toneMinAvgMaxLinear); RB_InstantQuad2(quadVerts, texCoords); FBO_Bind(oldFbo); }
/* ================== CM_AddFacetBevels ================== */ static inline void CM_AddFacetBevels( facet_t *facet ) { int i, j, k, l; int axis, dir, order, flipped; float plane[4], d, newplane[4]; winding_t *w, *w2; vec3_t mins, maxs, vec, vec2; VectorCopy4( planes[ facet->surfacePlane ].plane, plane ); w = BaseWindingForPlane( plane, plane[3] ); for ( j = 0 ; j < facet->numBorders && w ; j++ ) { if (facet->borderPlanes[j] == facet->surfacePlane) continue; VectorCopy4( planes[ facet->borderPlanes[j] ].plane, plane ); if ( !facet->borderInward[j] ) { VectorSubtract( vec3_origin, plane, plane ); plane[3] = -plane[3]; } ChopWindingInPlace( &w, plane, plane[3], 0.1f ); } if ( !w ) { return; } WindingBounds(w, mins, maxs); // add the axial planes order = 0; for ( axis = 0 ; axis < 3 ; axis++ ) { for ( dir = -1 ; dir <= 1 ; dir += 2, order++ ) { VectorClear(plane); plane[axis] = dir; if (dir == 1) { plane[3] = maxs[axis]; } else { plane[3] = -mins[axis]; } //if it's the surface plane if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) { continue; } // see if the plane is allready present for ( i = 0 ; i < facet->numBorders ; i++ ) { if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped)) break; } if ( i == facet->numBorders ) { if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n"); facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped); facet->borderNoAdjust[facet->numBorders] = (qboolean)0; facet->borderInward[facet->numBorders] = flipped; facet->numBorders++; } } } // // add the edge bevels // // test the non-axial plane edges for ( j = 0 ; j < w->numpoints ; j++ ) { k = (j+1)%w->numpoints; VectorSubtract (w->p[j], w->p[k], vec); //if it's a degenerate edge if (VectorNormalize (vec) < 0.5) continue; CM_SnapVector(vec); for ( k = 0; k < 3 ; k++ ) if ( vec[k] == -1 || vec[k] == 1 ) break; // axial if ( k < 3 ) continue; // only test non-axial edges // try the six possible slanted axials from this edge for ( axis = 0 ; axis < 3 ; axis++ ) { for ( dir = -1 ; dir <= 1 ; dir += 2 ) { // construct a plane VectorClear (vec2); vec2[axis] = dir; CrossProduct (vec, vec2, plane); if (VectorNormalize (plane) < 0.5) continue; plane[3] = DotProduct (w->p[j], plane); // if all the points of the facet winding are // behind this plane, it is a proper edge bevel for ( l = 0 ; l < w->numpoints ; l++ ) { d = DotProduct (w->p[l], plane) - plane[3]; if (d > 0.1) break; // point in front } if ( l < w->numpoints ) continue; //if it's the surface plane if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) { continue; } // see if the plane is allready present for ( i = 0 ; i < facet->numBorders ; i++ ) { if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped)) { break; } } if ( i == facet->numBorders ) { if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n"); facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped); for ( k = 0 ; k < facet->numBorders ; k++ ) { if (facet->borderPlanes[facet->numBorders] == facet->borderPlanes[k]) Com_Printf("WARNING: bevel plane already used\n"); } facet->borderNoAdjust[facet->numBorders] = (qboolean)0; facet->borderInward[facet->numBorders] = flipped; // w2 = CopyWinding(w); VectorCopy4(planes[facet->borderPlanes[facet->numBorders]].plane, newplane); if (!facet->borderInward[facet->numBorders]) { VectorNegate(newplane, newplane); newplane[3] = -newplane[3]; } //end if ChopWindingInPlace( &w2, newplane, newplane[3], 0.1f ); if (!w2) { #ifndef BSPC Com_DPrintf("WARNING: CM_AddFacetBevels... invalid bevel\n"); #endif continue; } else { FreeWinding(w2); } // facet->numBorders++; //already got a bevel // break; } } } } FreeWinding( w ); #ifndef BSPC //add opposite plane facet->borderPlanes[facet->numBorders] = facet->surfacePlane; facet->borderNoAdjust[facet->numBorders] = (qboolean)0; facet->borderInward[facet->numBorders] = qtrue; facet->numBorders++; #endif //BSPC }
/* ============== RB_AddQuadStampExt ============== */ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) { vec3_t normal; int16_t iNormal[4]; uint16_t iColor[4]; int ndx; RB_CheckVao(tess.vao); RB_CHECKOVERFLOW( 4, 6 ); ndx = tess.numVertexes; // triangle indexes for a simple quad tess.indexes[ tess.numIndexes ] = ndx; tess.indexes[ tess.numIndexes + 1 ] = ndx + 1; tess.indexes[ tess.numIndexes + 2 ] = ndx + 3; tess.indexes[ tess.numIndexes + 3 ] = ndx + 3; tess.indexes[ tess.numIndexes + 4 ] = ndx + 1; tess.indexes[ tess.numIndexes + 5 ] = ndx + 2; tess.xyz[ndx][0] = origin[0] + left[0] + up[0]; tess.xyz[ndx][1] = origin[1] + left[1] + up[1]; tess.xyz[ndx][2] = origin[2] + left[2] + up[2]; tess.xyz[ndx+1][0] = origin[0] - left[0] + up[0]; tess.xyz[ndx+1][1] = origin[1] - left[1] + up[1]; tess.xyz[ndx+1][2] = origin[2] - left[2] + up[2]; tess.xyz[ndx+2][0] = origin[0] - left[0] - up[0]; tess.xyz[ndx+2][1] = origin[1] - left[1] - up[1]; tess.xyz[ndx+2][2] = origin[2] - left[2] - up[2]; tess.xyz[ndx+3][0] = origin[0] + left[0] - up[0]; tess.xyz[ndx+3][1] = origin[1] + left[1] - up[1]; tess.xyz[ndx+3][2] = origin[2] + left[2] - up[2]; // constant normal all the way around VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal ); R_VaoPackNormal(iNormal, normal); VectorCopy4(iNormal, tess.normal[ndx]); VectorCopy4(iNormal, tess.normal[ndx + 1]); VectorCopy4(iNormal, tess.normal[ndx + 2]); VectorCopy4(iNormal, tess.normal[ndx + 3]); // standard square texture coordinates VectorSet2(tess.texCoords[ndx], s1, t1); VectorSet2(tess.lightCoords[ndx], s1, t1); VectorSet2(tess.texCoords[ndx+1], s2, t1); VectorSet2(tess.lightCoords[ndx+1], s2, t1); VectorSet2(tess.texCoords[ndx+2], s2, t2); VectorSet2(tess.lightCoords[ndx+2], s2, t2); VectorSet2(tess.texCoords[ndx+3], s1, t2); VectorSet2(tess.lightCoords[ndx+3], s1, t2); // constant color all the way around // should this be identity and let the shader specify from entity? R_VaoPackColor(iColor, color); VectorCopy4(iColor, tess.color[ndx]); VectorCopy4(iColor, tess.color[ndx + 1]); VectorCopy4(iColor, tess.color[ndx + 2]); VectorCopy4(iColor, tess.color[ndx + 3]); tess.numVertexes += 4; tess.numIndexes += 6; }
/* ==================== CM_TraceThroughPatchCollide ==================== */ void CM_TraceThroughPatchCollide( traceWork_t *tw, trace_t &trace, const struct patchCollide_s *pc ) { int i, j, hit, hitnum; float offset, enterFrac, leaveFrac, t; patchPlane_t *planes; facet_t *facet; float plane[4], bestplane[4]; vec3_t startp, endp; #ifndef BSPC static cvar_t *cv; #endif //BSPC #ifndef CULL_BBOX // I'm not sure if test is strictly correct. Are all // bboxes axis aligned? Do I care? It seems to work // good enough... for ( i = 0 ; i < 3 ; i++ ) { if ( tw->bounds[0][i] > pc->bounds[1][i] || tw->bounds[1][i] < pc->bounds[0][i] ) { return; } } #endif if (tw->isPoint) { CM_TracePointThroughPatchCollide( tw, trace, pc ); return; } // facet = pc->facets; for ( i = 0 ; i < pc->numFacets ; i++, facet++ ) { enterFrac = -1.0; leaveFrac = 1.0; hitnum = -1; // planes = &pc->planes[ facet->surfacePlane ]; VectorCopy(planes->plane, plane); plane[3] = planes->plane[3]; if ( tw->sphere.use ) { // adjust the plane distance appropriately for radius plane[3] += tw->sphere.radius; // find the closest point on the capsule to the plane t = DotProduct( plane, tw->sphere.offset ); if ( t > 0.0f ) { VectorSubtract( tw->start, tw->sphere.offset, startp ); VectorSubtract( tw->end, tw->sphere.offset, endp ); } else { VectorAdd( tw->start, tw->sphere.offset, startp ); VectorAdd( tw->end, tw->sphere.offset, endp ); } } else { offset = DotProduct( tw->offsets[ planes->signbits ], plane); plane[3] -= offset; VectorCopy( tw->start, startp ); VectorCopy( tw->end, endp ); } // if (!CM_CheckFacetPlane(plane, startp, endp, &enterFrac, &leaveFrac, &hit)) continue; if (hit) { VectorCopy4(plane, bestplane); } // for ( j = 0 ; j < facet->numBorders ; j++ ) { planes = &pc->planes[ facet->borderPlanes[j] ]; if (facet->borderInward[j]) { VectorNegate(planes->plane, plane); plane[3] = -planes->plane[3]; } else { VectorCopy(planes->plane, plane); plane[3] = planes->plane[3]; } if ( tw->sphere.use ) { // adjust the plane distance appropriately for radius plane[3] += tw->sphere.radius; // find the closest point on the capsule to the plane t = DotProduct( plane, tw->sphere.offset ); if ( t > 0.0f ) { VectorSubtract( tw->start, tw->sphere.offset, startp ); VectorSubtract( tw->end, tw->sphere.offset, endp ); } else { VectorAdd( tw->start, tw->sphere.offset, startp ); VectorAdd( tw->end, tw->sphere.offset, endp ); } } else { // NOTE: this works even though the plane might be flipped because the bbox is centered offset = DotProduct( tw->offsets[ planes->signbits ], plane); plane[3] += fabs(offset); VectorCopy( tw->start, startp ); VectorCopy( tw->end, endp ); } // if (!CM_CheckFacetPlane(plane, startp, endp, &enterFrac, &leaveFrac, &hit)) break; if (hit) { hitnum = j; VectorCopy4(plane, bestplane); } } if (j < facet->numBorders) continue; //never clip against the back side if (hitnum == facet->numBorders - 1) continue; // if (enterFrac < leaveFrac && enterFrac >= 0) { if (enterFrac < trace.fraction) { if (enterFrac < 0) { enterFrac = 0; } #ifndef BSPC if (!cv) { cv = Cvar_Get( "r_debugSurfaceUpdate", "1", 0 ); } if (cv && cv->integer) { debugPatchCollide = pc; debugFacet = facet; } #endif // BSPC trace.fraction = enterFrac; VectorCopy( bestplane, trace.plane.normal ); trace.plane.dist = bestplane[3]; } } } }
void JKG_BG_ParseGangWarsTeam(const char *filename) { fileHandle_t f; int len; char buffer[8192]; char parseBuf[4096]; len = trap->FS_Open(filename, &f, FS_READ); if(!f) { Com_Printf("^1Error loading Gang wars file (%s): NULL handle\n", filename); return; } if(!len || len >= 8192) { Com_Printf("^1Error loading Gang wars file (%s): Invalid file size range\n", filename); trap->FS_Close(f); return; } trap->FS_Read(buffer, len, f); trap->FS_Close(f); buffer[len] = '\0'; if (BG_GetPairedValue(buffer, "name", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].name, parseBuf); } else { Com_Error(ERR_DROP, "Gang wars team (%s) with no name!\n", filename); return; } if (BG_GetPairedValue(buffer, "reference", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].refPtr, parseBuf); } else { Com_Error(ERR_DROP, "Gang wars team (%s) with no reference name!\n", filename); return; } memset(bgGangWarsTeams[bgnumGangWarTeams].modelStore, 0, sizeof(bgGangWarsTeams[bgnumGangWarTeams].modelStore)); #if defined(_GAME) || defined(_UI) bgGangWarsTeams[bgnumGangWarTeams].teamIcon = 0; #elif defined(_CGAME) if (BG_GetPairedValue(buffer, "icon", parseBuf)) { bgGangWarsTeams[bgnumGangWarTeams].teamIcon = trap->R_RegisterShader(parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].teamIcon = trap->R_RegisterShader("sprites/team_red"); } #endif if ( BG_GetPairedValue( buffer, "useTeamColors", parseBuf ) ) { bgGangWarsTeams[bgnumGangWarTeams].useTeamColors = (qboolean)atoi(parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].useTeamColors = qfalse; } if (BG_GetPairedValue(buffer, "joinstring", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].joinstring, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].joinstring[0] = 0; } if (BG_GetPairedValue(buffer, "leadstring", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].leadstring, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].leadstring[0] = 0; } if (BG_GetPairedValue(buffer, "longname", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].longname, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].longname[0] = 0; } if (BG_GetPairedValue(buffer, "menujoinstring", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].menujoinstring, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].menujoinstring[0] = 0; } if (BG_GetPairedValue(buffer, "menustring", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].menustring, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].menustring[0] = 0; } if (BG_GetPairedValue(buffer, "toomanystring", parseBuf)) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].toomanystring, parseBuf); } else { bgGangWarsTeams[bgnumGangWarTeams].toomanystring[0] = 0; } // Team colors! :3 if (BG_GetPairedValue(buffer, "teamColor", parseBuf)) { // Parse this good char *buffer = parseBuf+1; char tempBuffer[8]; vec4_t tempColor; int i = 0; int j; for(j = 0; j < 4; j++) { while(buffer[i] != ',' && buffer[i] != '\0' && buffer[i] != '\r' && buffer[i] != '\n' && buffer[i] != '}') { tempBuffer[i] = buffer[i]; i++; } tempBuffer[i] = '\0'; // Grab the value tempColor[j] = atof(tempBuffer); tempColor[j] /= 255.0f; tempBuffer[0] = '\0'; buffer += i; i = 0; buffer++; } VectorCopy4(tempColor, bgGangWarsTeams[bgnumGangWarTeams].teamColor); } else { vec4_t tempColor; tempColor[0] = tempColor[1] = tempColor[2] = tempColor[3] = 1.0f; VectorCopy4(tempColor, bgGangWarsTeams[bgnumGangWarTeams].teamColor); } // Now we do a mega hack if (BG_GetPairedValue(buffer, "modelstore", parseBuf)) { // These are comma-delimited fields which specify each model // E.G.: "kyle/default,jan/default" would be the default int l = strlen(parseBuf); int i, j; j = 0; for(i = 0; i < l; i++) { if(parseBuf[i] == ',') { strncpy(bgGangWarsTeams[bgnumGangWarTeams].modelStore[bgGangWarsTeams[bgnumGangWarTeams].numModelsInStore], parseBuf+j, i-j); bgGangWarsTeams[bgnumGangWarTeams].modelStore[bgGangWarsTeams[bgnumGangWarTeams].numModelsInStore][i-j+1] = '\0'; bgGangWarsTeams[bgnumGangWarTeams].numModelsInStore++; j = i + 1; } if(parseBuf[i] == '\n') { break; } if(parseBuf[i] == '\0') { break; } } } else { //Just use Kyle for default I guess.. char defaultModel[MAX_QPATH]; strcpy(defaultModel, "kyle/default"); strcpy(bgGangWarsTeams[bgnumGangWarTeams].modelStore[0], defaultModel); strcpy(defaultModel, "jan/default"); strcpy(bgGangWarsTeams[bgnumGangWarTeams].modelStore[1], defaultModel); } if ( BG_GetPairedValue( buffer, "defaultModel", parseBuf ) ) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].defaultModel, parseBuf); size_t lastChar = strlen(bgGangWarsTeams[bgnumGangWarTeams].defaultModel)-1; if(bgGangWarsTeams[bgnumGangWarTeams].defaultModel[lastChar] == ',') { // This isn't a list. Commas don't belong in this field. bgGangWarsTeams[bgnumGangWarTeams].defaultModel[lastChar] = '\0'; } } else { if(!Q_stricmp(bgGangWarsTeams[bgnumGangWarTeams].modelStore[0], "NULL")) { strcpy(bgGangWarsTeams[bgnumGangWarTeams].defaultModel, "kyle"); } else { strcpy(bgGangWarsTeams[bgnumGangWarTeams].defaultModel, bgGangWarsTeams[bgnumGangWarTeams].modelStore[0]); // Use the first model as the default if none specified } } bgnumGangWarTeams++; }
int main(int argc, char** argv) { FileSystem::getExePath(); Renderer = new API_OpenGL(SCREEN_X, SCREEN_Y); #if defined(USE_GLUT) glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(SCREEN_X, SCREEN_Y); glutCreateWindow("jade3D Viewer"); #endif // RENDERER Renderer->InitGL(); Renderer->clearColor(0.45f,0.45f,0.45f,1); Renderer->setRendererState(RENDER_TEXTURE, true); Renderer->setRendererState(RENDER_GRID, true); Renderer->setRendererState(RENDER_NORMAL, !true); Renderer->setRendererState(RENDER_LIGHTNING, true); Renderer->setRendererState(RENDER_MATERIAL, true); Renderer->ReSizeGLScene(SCREEN_X, SCREEN_Y); // SCENE scene = new Scene(Renderer); #if 1 scene->importScene("scene01.jscene"); #else // CAMERA Camera * camera = new Camera(); camera->setCameraPos(1.0f, 4.0f, 10.0f); //camera->setCameraPos(1.0f, 4.0f, 80.0f); camera->setCameraRot(-20, 10, 0); // LIGHT Light_t light1; vec4_t la = { 0.0f, 0.0f, 0.0f, 1.0f }; vec4_t ld = { 1.0f, 1.0f, 1.0f, 1.0f }; vec4_t ls = {0.0f, 0.0f, 0.0f, 0}; vec4_t lp = {-3.0f, 4.0f, 2.0f, 0}; VectorCopy4(la, light1.ambient); VectorCopy4(ld, light1.diffuse); VectorCopy4(ls, light1.specular); VectorCopy4(lp, light1.position); // BRUSH MeshManager * cube = new MeshManager(Renderer); bool res = cube->loadMeshFromFile("gun1.ase", true); // Cube.obj // boule.obj // gun1.ase vec3_t p = {0, -3, 0}; vec3_t s = {0.2f, 0.2f, 0.2f}; cube->SetPos(p); cube->SetSize(s); MeshManager * cube2 = new MeshManager(Renderer); cube2->loadMeshFromFile("gun2.ase", true); vec3_t p2 = {0, -8, 25}; vec3_t s2 = {0.4f, 0.4f, 0.4f}; cube2->SetPos(p2); cube2->SetSize(s2); MeshManager * cube3 = new MeshManager(Renderer); cube3->loadMeshFromFile("Cube.obj", true); vec3_t p3 = {-3, 1, 0}; //vec3_t s2 = {0.2f, 0.2f, 0.2f}; cube3->SetPos(p3); //cube3->SetSize(s); MeshManager * cube4 = new MeshManager(Renderer); cube4->loadMeshFromFile("boule.obj", true); vec3_t p4 = {-3, 2, 5}; cube4->SetPos(p4); MeshManager * cube5 = new MeshManager(Renderer); cube5->loadMeshFromFile("boule2.obj", true); vec3_t p5 = {2, 2, 7}; vec3_t s5 = {3.0f, 3.0f, 3.0f}; cube5->SetPos(p5); cube5->SetSize(s5); MeshManager * cube6 = new MeshManager(Renderer); cube6->loadMeshFromFile("Cube.obj", true); vec3_t p6 = {3, -2, 3}; vec3_t s6 = {0.3f, 0.3f, 0.3f}; cube6->SetPos(p6); cube6->SetSize(s6); scene->addCamera(camera); scene->addLight(light1); scene->addBrush(cube); scene->addBrush(cube2); scene->addBrush(cube3); scene->addBrush(cube4); scene->addBrush(cube5); scene->addBrush(cube6); scene->exportScene("scene01.jscene"); #endif #if defined(USE_GLUT) glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); glutKeyboardFunc(processNormalKeys); glutSpecialFunc(processSpecialKeys); glutMainLoop(); #endif return EXIT_SUCCESS; }
static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIndexes, glIndex_t *indexes, int dlightBits, int pshadowBits) { int i; glIndex_t *inIndex; srfVert_t *dv; float *xyz, *texCoords, *lightCoords; int16_t *lightdir; int16_t *normal; int16_t *tangent; glIndex_t *outIndex; uint16_t *color; RB_CheckVao(tess.vao); RB_CHECKOVERFLOW( numVerts, numIndexes ); inIndex = indexes; outIndex = &tess.indexes[ tess.numIndexes ]; for ( i = 0 ; i < numIndexes ; i++ ) { *outIndex++ = tess.numVertexes + *inIndex++; } tess.numIndexes += numIndexes; if ( tess.shader->vertexAttribs & ATTR_POSITION ) { dv = verts; xyz = tess.xyz[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, xyz+=4 ) VectorCopy(dv->xyz, xyz); } if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { dv = verts; normal = tess.normal[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 ) VectorCopy4(dv->normal, normal); } if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { dv = verts; tangent = tess.tangent[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 ) VectorCopy4(dv->tangent, tangent); } if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) { dv = verts; texCoords = tess.texCoords[tess.numVertexes]; for ( i = 0 ; i < numVerts ; i++, dv++, texCoords+=2 ) VectorCopy2(dv->st, texCoords); } if ( tess.shader->vertexAttribs & ATTR_LIGHTCOORD ) { dv = verts; lightCoords = tess.lightCoords[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, lightCoords+=2 ) VectorCopy2(dv->lightmap, lightCoords); } if ( tess.shader->vertexAttribs & ATTR_COLOR ) { dv = verts; color = tess.color[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, color+=4 ) VectorCopy4(dv->color, color); } if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION ) { dv = verts; lightdir = tess.lightdir[ tess.numVertexes ]; for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 ) VectorCopy4(dv->lightdir, lightdir); } #if 0 // nothing even uses vertex dlightbits for ( i = 0 ; i < numVerts ; i++ ) { tess.vertexDlightBits[ tess.numVertexes + i ] = dlightBits; } #endif tess.dlightBits |= dlightBits; tess.pshadowBits |= pshadowBits; tess.numVertexes += numVerts; }
/* ============= RB_SurfaceGrid Just copy the grid of points and triangulate ============= */ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { int i, j; float *xyz; float *texCoords, *lightCoords; int16_t *normal; int16_t *tangent; uint16_t *color; int16_t *lightdir; srfVert_t *dv; int rows, irows, vrows; int used; int widthTable[MAX_GRID_SIZE]; int heightTable[MAX_GRID_SIZE]; float lodError; int lodWidth, lodHeight; int numVertexes; int dlightBits; int pshadowBits; //int *vDlightBits; if (RB_SurfaceVaoCached(srf->numVerts, srf->verts, srf->numIndexes, srf->indexes, srf->dlightBits, srf->pshadowBits)) { return; } RB_CheckVao(tess.vao); dlightBits = srf->dlightBits; tess.dlightBits |= dlightBits; pshadowBits = srf->pshadowBits; tess.pshadowBits |= pshadowBits; // determine the allowable discrepance lodError = LodErrorForVolume( srf->lodOrigin, srf->lodRadius ); // determine which rows and columns of the subdivision // we are actually going to use widthTable[0] = 0; lodWidth = 1; for ( i = 1 ; i < srf->width-1 ; i++ ) { if ( srf->widthLodError[i] <= lodError ) { widthTable[lodWidth] = i; lodWidth++; } } widthTable[lodWidth] = srf->width-1; lodWidth++; heightTable[0] = 0; lodHeight = 1; for ( i = 1 ; i < srf->height-1 ; i++ ) { if ( srf->heightLodError[i] <= lodError ) { heightTable[lodHeight] = i; lodHeight++; } } heightTable[lodHeight] = srf->height-1; lodHeight++; // very large grids may have more points or indexes than can be fit // in the tess structure, so we may have to issue it in multiple passes used = 0; while ( used < lodHeight - 1 ) { // see how many rows of both verts and indexes we can add without overflowing do { vrows = ( SHADER_MAX_VERTEXES - tess.numVertexes ) / lodWidth; irows = ( SHADER_MAX_INDEXES - tess.numIndexes ) / ( lodWidth * 6 ); // if we don't have enough space for at least one strip, flush the buffer if ( vrows < 2 || irows < 1 ) { RB_EndSurface(); RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex ); } else { break; } } while ( 1 ); rows = irows; if ( vrows < irows + 1 ) { rows = vrows - 1; } if ( used + rows > lodHeight ) { rows = lodHeight - used; } numVertexes = tess.numVertexes; xyz = tess.xyz[numVertexes]; normal = tess.normal[numVertexes]; tangent = tess.tangent[numVertexes]; texCoords = tess.texCoords[numVertexes]; lightCoords = tess.lightCoords[numVertexes]; color = tess.color[numVertexes]; lightdir = tess.lightdir[numVertexes]; //vDlightBits = &tess.vertexDlightBits[numVertexes]; for ( i = 0 ; i < rows ; i++ ) { for ( j = 0 ; j < lodWidth ; j++ ) { dv = srf->verts + heightTable[ used + i ] * srf->width + widthTable[ j ]; if ( tess.shader->vertexAttribs & ATTR_POSITION ) { VectorCopy(dv->xyz, xyz); xyz += 4; } if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { VectorCopy4(dv->normal, normal); normal += 4; } if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { VectorCopy4(dv->tangent, tangent); tangent += 4; } if ( tess.shader->vertexAttribs & ATTR_TEXCOORD ) { VectorCopy2(dv->st, texCoords); texCoords += 2; } if ( tess.shader->vertexAttribs & ATTR_LIGHTCOORD ) { VectorCopy2(dv->lightmap, lightCoords); lightCoords += 2; } if ( tess.shader->vertexAttribs & ATTR_COLOR ) { VectorCopy4(dv->color, color); color += 4; } if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION ) { VectorCopy4(dv->lightdir, lightdir); lightdir += 4; } //*vDlightBits++ = dlightBits; } } // add the indexes { int numIndexes; int w, h; h = rows - 1; w = lodWidth - 1; numIndexes = tess.numIndexes; for (i = 0 ; i < h ; i++) { for (j = 0 ; j < w ; j++) { int v1, v2, v3, v4; // vertex order to be reckognized as tristrips v1 = numVertexes + i*lodWidth + j + 1; v2 = v1 - 1; v3 = v2 + lodWidth; v4 = v3 + 1; tess.indexes[numIndexes] = v2; tess.indexes[numIndexes+1] = v3; tess.indexes[numIndexes+2] = v1; tess.indexes[numIndexes+3] = v1; tess.indexes[numIndexes+4] = v3; tess.indexes[numIndexes+5] = v4; numIndexes += 6; } } tess.numIndexes = numIndexes; } tess.numVertexes += rows * lodWidth; used += rows - 1; } }
/* ================ CG_DrawArmor ================ */ static void CG_DrawArmor( menuDef_t *menuHUD ) { //vec4_t calcColor; vec4_t glowColor; playerState_t *ps; int armor, maxArmor; itemDef_t *focusItem; double percentage, factor ; //quarterArmor; //int i,currValue,inc; const char *text; int x; static double fcurrent = 0; vec4_t fadecolor = {1, 1, 1, 0.5f}; static vec4_t draincolor = {1, 0.4f, 0.4f, 1}; static vec4_t fillcolor = {0.4f, 1, 0.4f, 1}; vec4_t opacity; int state = 0; MAKERGBA(opacity, 1, 1, 1, cg.jkg_HUDOpacity); //ps = &cg.snap->ps; ps = &cg.predictedPlayerState; // Can we find the menu? if (!menuHUD) { return; } armor = ps->stats[STAT_ARMOR]; maxArmor = ps->stats[STAT_MAX_ARMOR]; // TEST: just render the whole thing for now, we'll fix it later focusItem = Menu_FindItemByName(menuHUD, "shieldbar"); if (focusItem) { percentage = (double)armor / (double)maxArmor; if (percentage > 1) { percentage = 1; } else if (percentage < 0) { percentage = 0; } factor = /*0.6171875f **/ percentage /*+ 0.34375f*/; /*if(factor > 0.95f) { factor = 1.0f; //eezstreet - mega hack }*/ // Fade our fcurrent to this factor if (fcurrent < factor) { // Raise it fcurrent += (cg.frameDelta * .0003); // Go up 30% per second if (fcurrent > factor) { // We passed it fcurrent = factor; } } else if (fcurrent > factor) { // Lower it fcurrent -= (cg.frameDelta * .0003); // Go up 30% per second if (fcurrent < factor) { fcurrent = factor; } } if (fcurrent != 0) { if (fcurrent < factor) { state = 1; // We're filling up, draw up to fcurrent solid, and up to factor translucent trap_R_SetColor(opacity); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * fcurrent, focusItem->window.rect.h, 0, 0, fcurrent, 1, focusItem->window.background); fadecolor[3] *= cg.jkg_HUDOpacity; trap_R_SetColor(fadecolor); trap_R_DrawStretchPic(focusItem->window.rect.x + focusItem->window.rect.w * fcurrent, focusItem->window.rect.y, focusItem->window.rect.w * (factor - fcurrent), focusItem->window.rect.h, fcurrent, 0, factor, 1, focusItem->window.background); trap_R_SetColor(opacity); } else if (fcurrent > factor) { state = 2; // We're draining, draw up to factor solid, and up to fcurrent translucent trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * factor, focusItem->window.rect.h, 0, 0, factor, 1, focusItem->window.background); fadecolor[3] *= cg.jkg_HUDOpacity; trap_R_SetColor(fadecolor); trap_R_DrawStretchPic(focusItem->window.rect.x + focusItem->window.rect.w * factor, focusItem->window.rect.y, focusItem->window.rect.w * (fcurrent - factor), focusItem->window.rect.h, factor, 0, fcurrent, 1, focusItem->window.background); trap_R_SetColor(opacity); } else { state = 0; // Just solid trap_R_SetColor(opacity); trap_R_DrawStretchPic(focusItem->window.rect.x, focusItem->window.rect.y, focusItem->window.rect.w * factor, focusItem->window.rect.h, 0, 0, factor, 1, focusItem->window.background); } } } if (!armor) { return; } focusItem = Menu_FindItemByName(menuHUD, "shieldtext"); if (focusItem) { if (state == 1) { VectorCopy4(fillcolor, glowColor); } else if (state == 2) { VectorCopy4(draincolor, glowColor); } else { VectorCopy4(colorWhite, glowColor); } glowColor[3] *= cg.jkg_HUDOpacity; // Center and draw the text, positioning will be finetuned later on :P text = va("%i / %i", armor, maxArmor); x = ((focusItem->window.rect.w/2) - (trap_R_Font_StrLenPixels(text, cgs.media.hudfont1, 0.6f) / 2)) + focusItem->window.rect.x; trap_R_Font_DrawString( x, focusItem->window.rect.y, text, glowColor, cgs.media.hudfont1, -1, 0.6f); trap_R_SetColor(NULL); } }
void CM_DrawDebugSurface( void (*drawPoly)(int color, int numPoints, float *points) ) { static cvar_t *cv; #ifndef BSPC static cvar_t *cv2; #endif const patchCollide_t *pc; facet_t *facet; winding_t *w; int i, j, k, n; int curplanenum, planenum, curinward, inward; float plane[4]; vec3_t mins = {-15, -15, -28}, maxs = {15, 15, 28}; //vec3_t mins = {0, 0, 0}, maxs = {0, 0, 0}; vec3_t v1, v2; #ifndef BSPC if ( !cv2 ) { cv2 = Cvar_Get( "r_debugSurface", "0", 0 ); } if (cv2->integer != 1) { BotDrawDebugPolygons(drawPoly, cv2->integer); return; } #endif if ( !debugPatchCollide ) { return; } #ifndef BSPC if ( !cv ) { cv = Cvar_Get( "cm_debugSize", "2", 0 ); } #endif pc = debugPatchCollide; for ( i = 0, facet = pc->facets ; i < pc->numFacets ; i++, facet++ ) { for ( k = 0 ; k < facet->numBorders + 1; k++ ) { // if (k < facet->numBorders) { planenum = facet->borderPlanes[k]; inward = facet->borderInward[k]; } else { planenum = facet->surfacePlane; inward = qfalse; //continue; } VectorCopy4( pc->planes[ planenum ].plane, plane ); //planenum = facet->surfacePlane; if ( inward ) { VectorSubtract( vec3_origin, plane, plane ); plane[3] = -plane[3]; } plane[3] += cv->value; //* for (n = 0; n < 3; n++) { if (plane[n] > 0) v1[n] = maxs[n]; else v1[n] = mins[n]; } //end for VectorNegate(plane, v2); plane[3] += fabs(DotProduct(v1, v2)); //*/ w = BaseWindingForPlane( plane, plane[3] ); for ( j = 0 ; j < facet->numBorders + 1 && w; j++ ) { // if (j < facet->numBorders) { curplanenum = facet->borderPlanes[j]; curinward = facet->borderInward[j]; } else { curplanenum = facet->surfacePlane; curinward = qfalse; //continue; } // if (curplanenum == planenum) continue; VectorCopy4( pc->planes[ curplanenum ].plane, plane ); if ( !curinward ) { VectorSubtract( vec3_origin, plane, plane ); plane[3] = -plane[3]; } // if ( !facet->borderNoAdjust[j] ) { plane[3] -= cv->value; // } for (n = 0; n < 3; n++) { if (plane[n] > 0) v1[n] = maxs[n]; else v1[n] = mins[n]; } //end for VectorNegate(plane, v2); plane[3] -= fabs(DotProduct(v1, v2)); ChopWindingInPlace( &w, plane, plane[3], 0.1f ); } if ( w ) { if ( facet == debugFacet ) { drawPoly( 4, w->numpoints, w->p[0] ); //Com_Printf("blue facet has %d border planes\n", facet->numBorders); } else { drawPoly( 1, w->numpoints, w->p[0] ); } FreeWinding( w ); } else Com_Printf("winding chopped away by border planes\n"); } } // draw the debug block { matrix3_t v; VectorCopy( debugBlockPoints[0], v[0] ); VectorCopy( debugBlockPoints[1], v[1] ); VectorCopy( debugBlockPoints[2], v[2] ); drawPoly( 2, 3, v[0] ); VectorCopy( debugBlockPoints[2], v[0] ); VectorCopy( debugBlockPoints[3], v[1] ); VectorCopy( debugBlockPoints[0], v[2] ); drawPoly( 2, 3, v[0] ); } #if 0 vec3_t v[4]; v[0][0] = pc->bounds[1][0]; v[0][1] = pc->bounds[1][1]; v[0][2] = pc->bounds[1][2]; v[1][0] = pc->bounds[1][0]; v[1][1] = pc->bounds[0][1]; v[1][2] = pc->bounds[1][2]; v[2][0] = pc->bounds[0][0]; v[2][1] = pc->bounds[0][1]; v[2][2] = pc->bounds[1][2]; v[3][0] = pc->bounds[0][0]; v[3][1] = pc->bounds[1][1]; v[3][2] = pc->bounds[1][2]; drawPoly( 4, v[0] ); #endif }
static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp) { float *outXyz; int16_t *outNormal, *outTangent; mdvVertex_t *newVerts; int vertNum; newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts; outXyz = tess.xyz[tess.numVertexes]; outNormal = tess.normal[tess.numVertexes]; outTangent = tess.tangent[tess.numVertexes]; if (backlerp == 0) { // // just copy the vertexes // for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { VectorCopy(newVerts->xyz, outXyz); VectorCopy4(newVerts->normal, outNormal); VectorCopy4(newVerts->tangent, outTangent); newVerts++; outXyz += 4; outNormal += 4; outTangent += 4; } } else { // // interpolate and copy the vertex and normal // mdvVertex_t *oldVerts; oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts; for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz); outNormal[0] = (int16_t)(newVerts->normal[0] * (1.0f - backlerp) + oldVerts->normal[0] * backlerp); outNormal[1] = (int16_t)(newVerts->normal[1] * (1.0f - backlerp) + oldVerts->normal[1] * backlerp); outNormal[2] = (int16_t)(newVerts->normal[2] * (1.0f - backlerp) + oldVerts->normal[2] * backlerp); outNormal[3] = 0; outTangent[0] = (int16_t)(newVerts->tangent[0] * (1.0f - backlerp) + oldVerts->tangent[0] * backlerp); outTangent[1] = (int16_t)(newVerts->tangent[1] * (1.0f - backlerp) + oldVerts->tangent[1] * backlerp); outTangent[2] = (int16_t)(newVerts->tangent[2] * (1.0f - backlerp) + oldVerts->tangent[2] * backlerp); outTangent[3] = newVerts->tangent[3]; newVerts++; oldVerts++; outXyz += 4; outNormal += 4; outTangent += 4; } } }