void idGLWidget::OnPaint() { if( !initialized ) { CDC *dc = GetDC(); QEW_SetupPixelFormat( dc->m_hDC, false ); ReleaseDC( dc ); initialized = true; } CPaintDC dc( this ); // device context for painting CRect rect; GetClientRect( rect ); if( !wglMakeCurrent( dc.m_hDC, win32.hGLRC ) ) { } GL_Viewport( 0, 0, rect.Width(), rect.Height() ); GL_Scissor( 0, 0, rect.Width(), rect.Height() ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glClearColor( 0.4f, 0.4f, 0.4f, 0.7f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_BLEND ); glOrtho( 0, rect.Width(), 0, rect.Height(), -256, 256 ); if( drawable ) { drawable->draw( 1, 1, rect.Width() - 1, rect.Height() - 1 ); } else { GL_Viewport( 0, 0, rect.Width(), rect.Height() ); GL_Scissor( 0, 0, rect.Width(), rect.Height() ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glClearColor( 0.4f, 0.4f, 0.4f, 0.7f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); } wglSwapBuffers( dc ); glFlush(); wglMakeCurrent( win32.hDC, win32.hGLRC ); }
void idGLDrawableConsole::draw( int x, int y, int w, int h ) { glPushAttrib( GL_ALL_ATTRIB_BITS ); glClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); GL_Scissor( 0, 0, w, h ); glClear( GL_COLOR_BUFFER_BIT ); renderSystem->BeginFrame( w, h ); console->Draw( true ); renderSystem->EndFrame( NULL, NULL ); glPopAttrib(); }
/* ================ RB_SimpleWorldSetup ================ */ static void RB_SimpleWorldSetup() { backEnd.currentSpace = &backEnd.viewDef->worldSpace; qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix ); GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1, backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 ); backEnd.currentScissor = backEnd.viewDef->scissor; }
static void SetViewportAndScissor( void ) { #if defined( USE_D3D10 ) // TODO #else GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix ); // set the window clipping GL_Viewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight ); GL_Scissor( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight ); #endif }
/* ================ RB_SimpleSurfaceSetup ================ */ static void RB_SimpleSurfaceSetup( const drawSurf_t *drawSurf ) { // change the matrix if needed if ( drawSurf->space != backEnd.currentSpace ) { qglLoadMatrixf( drawSurf->space->modelViewMatrix ); backEnd.currentSpace = drawSurf->space; } // change the scissor if needed if ( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) { GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1, drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); backEnd.currentScissor = drawSurf->scissorRect; } }
/* ================ RB_SetGL2D ================ */ static void RB_SetGL2D( void ) { matrix_t proj; GLimp_LogComment( "--- RB_SetGL2D ---\n" ); #if defined( USE_D3D10 ) // TODO #else // disable offscreen rendering if ( glConfig.framebufferObjectAvailable ) { R_BindNullFBO(); } #endif backEnd.projection2D = qtrue; #if defined( USE_D3D10 ) // TODO #else // set 2D virtual screen size GL_Viewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); GL_Scissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); MatrixOrthogonalProjection( proj, 0, glConfig.vidWidth, glConfig.vidHeight, 0, 0, 1 ); GL_LoadProjectionMatrix( proj ); GL_LoadModelViewMatrix( matrixIdentity ); GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglDisable( GL_CULL_FACE ); qglDisable( GL_CLIP_PLANE0 ); #endif // set time for 2D shaders backEnd.refdef.time = ri.Milliseconds(); backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; }
void idGLDrawable::draw( int x, int y, int w, int h ) { GL_State( GLS_DEFAULT ); GL_Viewport( x, y, w, h ); GL_Scissor( x, y, w, h ); glMatrixMode( GL_PROJECTION ); glClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); glLineWidth( 0.5 ); GL_Color( 1.0f, 1.0f, 1.0f ); globalImages->BindNull(); glBegin( GL_LINE_LOOP ); GL_Color( 1.0f, 0.0f, 0.0f ); glVertex2f( x + 3, y + 3 ); GL_Color( 0.0f, 1.0f, 0.0f ); glVertex2f( x + 3, h - 3 ); GL_Color( 0.0f, 0.0f, 1.0f ); glVertex2f( w - 3, h - 3 ); GL_Color( 1.0f, 1.0f, 1.0f ); glVertex2f( w - 3, y + 3 ); glEnd(); }
/* * R_RenderMeshGLSL_Shadowmap */ static void R_RenderMeshGLSL_Shadowmap( r_glslfeat_t programFeatures ) { int i; int state; int scissor[4], old_scissor[4]; int program, object; vec3_t tdir, lightDir; shaderpass_t *pass = r_back.accumPasses[0]; if( r_shadows_pcf->integer ) programFeatures |= GLSL_SHADOWMAP_APPLY_PCF; if( r_shadows_dither->integer ) programFeatures |= GLSL_SHADOWMAP_APPLY_DITHER; // update uniforms program = R_RegisterGLSLProgram( pass->program_type, pass->program, NULL, NULL, NULL, 0, programFeatures ); object = R_GetProgramObject( program ); if( !object ) return; Vector4Copy( ri.scissor, old_scissor ); for( i = 0, r_back.currentCastGroup = r_shadowGroups; i < r_numShadowGroups; i++, r_back.currentCastGroup++ ) { if( !( r_back.currentShadowBits & r_back.currentCastGroup->bit ) ) continue; // project the bounding box on to screen then use scissor test // so that fragment shader isn't run for unshadowed regions if( !R_ScissorForBounds( r_back.currentCastGroup->visCorners, &scissor[0], &scissor[1], &scissor[2], &scissor[3] ) ) continue; GL_Scissor( ri.refdef.x + scissor[0], ri.refdef.y + scissor[1], scissor[2], scissor[3] ); R_BindShaderpass( pass, r_back.currentCastGroup->depthTexture, 0, NULL ); GL_TexEnv( GL_MODULATE ); qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB ); qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); // calculate the fragment color R_ModifyColor( pass, qfalse, qfalse ); // set shaderpass state (blending, depthwrite, etc) state = r_back.currentShaderState | ( pass->flags & r_back.currentShaderPassMask ) | GLSTATE_BLEND_MTEX; GL_SetState( state ); qglUseProgramObjectARB( object ); VectorCopy( r_back.currentCastGroup->direction, tdir ); Matrix_TransformVector( ri.currententity->axis, tdir, lightDir ); R_UpdateProgramUniforms( program, ri.viewOrigin, vec3_origin, lightDir, r_back.currentCastGroup->lightAmbient, NULL, NULL, qtrue, r_back.currentCastGroup->depthTexture->upload_width, r_back.currentCastGroup->depthTexture->upload_height, r_back.currentCastGroup->projDist, 0, 0, colorArrayCopy[0], r_back.overBrightBits, r_back.currentShaderTime, r_back.entityColor ); R_FlushArrays(); qglUseProgramObjectARB( 0 ); qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); } GL_Scissor( old_scissor[0], old_scissor[1], old_scissor[2], old_scissor[3] ); }
/* * R_BloomBlend */ void R_BloomBlend( const refdef_t *fd ) { if( !( fd->rdflags & RDF_BLOOM ) || !r_bloom->integer ) return; if( !BLOOM_SIZE ) R_Bloom_InitTextures(); if( screen_texture_width < BLOOM_SIZE || screen_texture_height < BLOOM_SIZE ) return; // set up full screen workspace GL_Scissor( 0, 0, glState.width, glState.height ); GL_Viewport( 0, 0, glState.width, glState.height ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity(); qglOrtho( 0, glState.width, glState.height, 0, -10, 100 ); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity(); GL_Cull( 0 ); GL_SetState( GLSTATE_NO_DEPTH_TEST ); qglColor4f( 1, 1, 1, 1 ); // set up current sizes curView_x = fd->x; curView_y = fd->y; curView_width = fd->width; curView_height = fd->height; screenTex_tcw = ( (float)curView_width / (float)screen_texture_width ); screenTex_tch = ( (float)curView_height / (float)screen_texture_height ); if( curView_height > curView_width ) { sampleText_tcw = ( (float)curView_width / (float)curView_height ); sampleText_tch = 1.0f; } else { sampleText_tcw = 1.0f; sampleText_tch = ( (float)curView_height / (float)curView_width ); } sample_width = ( BLOOM_SIZE * sampleText_tcw ); sample_height = ( BLOOM_SIZE * sampleText_tch ); // copy the screen space we'll use to work into the backup texture GL_Bind( 0, r_bloombackuptexture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, r_screenbackuptexture_width, r_screenbackuptexture_height ); // create the bloom image R_Bloom_DownsampleView(); R_Bloom_GeneratexDiamonds(); // restore the screen-backup to the screen GL_SetState( GLSTATE_NO_DEPTH_TEST ); GL_Bind( 0, r_bloombackuptexture ); qglColor4f( 1, 1, 1, 1 ); R_Bloom_Quad( 0, 0, r_screenbackuptexture_width, r_screenbackuptexture_height, 1.0f, 1.0f ); GL_Scissor( ri.scissor[0], ri.scissor[1], ri.scissor[2], ri.scissor[3] ); R_Bloom_DrawEffect(); GL_Viewport( ri.viewport[0], ri.viewport[1], ri.viewport[2], ri.viewport[3] ); }
/* * R_Bloom_GeneratexDiamonds */ static void R_Bloom_GeneratexDiamonds( void ) { int i, j, k; float intensity, scale, *diamond; // set up sample size workspace GL_Scissor( 0, glState.height - sample_height, sample_width, sample_height ); GL_Viewport( 0, glState.height - sample_height, sample_width, sample_height ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity(); qglOrtho( 0, sample_width, sample_height, 0, -10, 100 ); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity(); // copy small scene into r_bloomeffecttexture GL_Bind( 0, r_bloomeffecttexture ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); // start modifying the small scene corner qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); // darkening passes if( r_bloom_darken->integer ) { GL_TexEnv( GL_MODULATE ); GL_SetState( GLSTATE_NO_DEPTH_TEST|GLSTATE_SRCBLEND_DST_COLOR|GLSTATE_DSTBLEND_ZERO ); for( i = 0; i < r_bloom_darken->integer; i++ ) R_Bloom_SamplePass( 0, 0 ); qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); } // bluring passes GL_SetState( GLSTATE_NO_DEPTH_TEST|GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ONE_MINUS_SRC_COLOR ); if( r_bloom_diamond_size->integer > 7 || r_bloom_diamond_size->integer <= 3 ) { if( r_bloom_diamond_size->integer != 8 ) Cvar_ForceSet( "r_bloom_diamond_size", "8" ); } else if( r_bloom_diamond_size->integer > 5 ) { if( r_bloom_diamond_size->integer != 6 ) Cvar_ForceSet( "r_bloom_diamond_size", "6" ); } else if( r_bloom_diamond_size->integer > 3 ) { if( r_bloom_diamond_size->integer != 4 ) Cvar_ForceSet( "r_bloom_diamond_size", "4" ); } switch( r_bloom_diamond_size->integer ) { case 4: k = 2; diamond = &Diamond4x[0][0]; scale = r_bloom_intensity->value * 0.8f; break; case 6: k = 3; diamond = &Diamond6x[0][0]; scale = r_bloom_intensity->value * 0.5f; break; default: // case 8: k = 4; diamond = &Diamond8x[0][0]; scale = r_bloom_intensity->value * 0.3f; break; } for( i = 0; i < r_bloom_diamond_size->integer; i++ ) { for( j = 0; j < r_bloom_diamond_size->integer; j++, diamond++ ) { intensity = *diamond * scale; if( intensity < 0.01f ) continue; qglColor4f( intensity, intensity, intensity, 1.0 ); R_Bloom_SamplePass( i - k, j - k ); } } qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); // restore full screen workspace GL_Scissor( 0, 0, glState.width, glState.height ); GL_Viewport( 0, 0, glState.width, glState.height ); qglMatrixMode( GL_PROJECTION ); qglLoadIdentity(); qglOrtho( 0, glState.width, glState.height, 0, -10, 100 ); qglMatrixMode( GL_MODELVIEW ); qglLoadIdentity(); }
/* ================== GL_Setup3D TODO: time is messed up ================== */ void GL_Setup3D (int time){ double clipPlane[4]; QGL_LogPrintf("---------- RB_Setup3D ----------\n"); backEnd.projection2D = false; backEnd.time = time; backEnd.floatTime = MS2SEC(Sys_Milliseconds()); backEnd.viewport.x = backEnd.viewParms.viewport.x; backEnd.viewport.y = backEnd.viewParms.viewport.y; backEnd.viewport.width = backEnd.viewParms.viewport.width; backEnd.viewport.height = backEnd.viewParms.viewport.height; backEnd.scissor.x = backEnd.viewParms.scissor.x; backEnd.scissor.y = backEnd.viewParms.scissor.y; backEnd.scissor.width = backEnd.viewParms.scissor.width; backEnd.scissor.height = backEnd.viewParms.scissor.height; backEnd.coordScale[0] = 1.0f / backEnd.viewport.width; backEnd.coordScale[1] = 1.0f / backEnd.viewport.height; backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0]; backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1]; backEnd.depthFilling = false; backEnd.debugRendering = false; backEnd.currentColorCaptured = SORT_BAD; backEnd.currentDepthCaptured = false; // Set up the viewport GL_Viewport(backEnd.viewport); // Set up the scissor GL_Scissor(backEnd.viewport); // Set up the depth bounds if (glConfig.depthBoundsTestAvailable) GL_DepthBounds(0.0f, 1.0f); // Set the projection matrix GL_LoadMatrix(GL_PROJECTION, backEnd.viewParms.projectionMatrix); // Set the modelview matrix GL_LoadIdentity(GL_MODELVIEW); // Set the GL state GL_PolygonMode(GL_FILL); GL_Disable(GL_CULL_FACE); GL_Disable(GL_POLYGON_OFFSET_FILL); GL_Disable(GL_BLEND); GL_Disable(GL_ALPHA_TEST); GL_Disable(GL_DEPTH_TEST); GL_Disable(GL_STENCIL_TEST); GL_DepthRange(0.0f, 1.0f); GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); GL_DepthMask(GL_TRUE); GL_StencilMask(255); // Enable the clip plane if needed if (backEnd.viewParms.viewType != VIEW_MIRROR) qglDisable(GL_CLIP_PLANE0); else { clipPlane[0] = -DotProduct(backEnd.viewParms.axis[1], backEnd.viewParms.clipPlane.normal); clipPlane[1] = DotProduct(backEnd.viewParms.axis[2], backEnd.viewParms.clipPlane.normal); clipPlane[2] = -DotProduct(backEnd.viewParms.axis[0], backEnd.viewParms.clipPlane.normal); clipPlane[3] = DotProduct(backEnd.viewParms.origin, backEnd.viewParms.clipPlane.normal) - backEnd.viewParms.clipPlane.dist; qglEnable(GL_CLIP_PLANE0); qglClipPlane(GL_CLIP_PLANE0, clipPlane); } // Enable multisampling if available if (glConfig.multiSamples > 1) qglEnable(GL_MULTISAMPLE); // Clear the buffers qglClearColor(0.0f, 0.0f, 0.0f, 1.0f); qglClearDepth(1.0f); qglClearStencil(0); if (backEnd.viewParms.primaryView) qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); else qglClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Check for errors if (!r_ignoreGLErrors->integerValue) GL_CheckForErrors(); QGL_LogPrintf("--------------------\n"); }
/* ================== GL_Setup2D TODO: time is messed up ================== */ void GL_Setup2D (int time){ mat4_t projectionMatrix = {2.0f / backEnd.cropWidth, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / backEnd.cropHeight, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f}; QGL_LogPrintf("---------- RB_Setup2D ----------\n"); backEnd.projection2D = true; backEnd.time = time; backEnd.floatTime = MS2SEC(Sys_Milliseconds()); backEnd.viewport.x = 0; backEnd.viewport.y = 0; backEnd.viewport.width = backEnd.cropWidth; backEnd.viewport.height = backEnd.cropHeight; backEnd.scissor.x = 0; backEnd.scissor.y = 0; backEnd.scissor.width = backEnd.cropWidth; backEnd.scissor.height = backEnd.cropHeight; backEnd.coordScale[0] = 1.0f / backEnd.viewport.width; backEnd.coordScale[1] = 1.0f / backEnd.viewport.height; backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0]; backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1]; backEnd.depthFilling = false; backEnd.debugRendering = false; backEnd.currentColorCaptured = SORT_BAD; backEnd.currentDepthCaptured = false; // Set up the viewport GL_Viewport(backEnd.viewport); // Set up the scissor GL_Scissor(backEnd.viewport); // Set up the depth bounds if (glConfig.depthBoundsTestAvailable) GL_DepthBounds(0.0f, 1.0f); // Set the projection matrix GL_LoadMatrix(GL_PROJECTION, projectionMatrix); // Set the modelview matrix GL_LoadIdentity(GL_MODELVIEW); // Set the GL state GL_PolygonMode(GL_FILL); GL_Disable(GL_CULL_FACE); GL_Disable(GL_POLYGON_OFFSET_FILL); GL_Disable(GL_BLEND); GL_Disable(GL_ALPHA_TEST); GL_Disable(GL_DEPTH_TEST); GL_Disable(GL_STENCIL_TEST); GL_DepthRange(0.0f, 1.0f); GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); GL_DepthMask(GL_FALSE); GL_StencilMask(255); // Disable the clip plane qglDisable(GL_CLIP_PLANE0); // Disable multisampling if available if (glConfig.multiSamples > 1) qglDisable(GL_MULTISAMPLE); // Check for errors if (!r_ignoreGLErrors->integerValue) GL_CheckForErrors(); QGL_LogPrintf("--------------------\n"); }
void idGLDrawableModel::draw( int x, int y, int w, int h ) { if( !worldModel ) { return; } if( worldModel->IsDynamicModel() != DM_STATIC ) { //return; } rect.Set( x, y, w, h ); GL_Viewport( x, y, w, h ); GL_Scissor( x, y, w, h ); glMatrixMode( GL_PROJECTION ); glClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); if( worldDirty ) { //InitWorld(); world->InitFromMap( NULL ); renderLight_t parms; idDict spawnArgs; spawnArgs.Set( "classname", "light" ); spawnArgs.Set( "name", "light_1" ); spawnArgs.Set( "origin", "-128 0 0" ); idStr str; sprintf( str, "%f %f %f", light, light, light ); spawnArgs.Set( "_color", str ); gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms ); lightDef = world->AddLightDef( &parms ); renderEntity_t worldEntity; memset( &worldEntity, 0, sizeof( worldEntity ) ); spawnArgs.Clear(); spawnArgs.Set( "classname", "func_static" ); spawnArgs.Set( "name", spawnArgs.GetString( "model" ) ); spawnArgs.Set( "origin", "0 0 0" ); if( skinStr.Length() ) { spawnArgs.Set( "skin", skinStr ); } gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &worldEntity ); worldEntity.hModel = worldModel; worldEntity.axis = rotation.ToMat3(); worldEntity.shaderParms[0] = 1; worldEntity.shaderParms[1] = 1; worldEntity.shaderParms[2] = 1; worldEntity.shaderParms[3] = 1; modelDef = world->AddEntityDef( &worldEntity ); worldDirty = false; } renderView_t refdef; // render it renderSystem->BeginFrame( w, h ); memset( &refdef, 0, sizeof( refdef ) ); refdef.vieworg.Set( zOffset, xOffset, -yOffset ); refdef.viewaxis = idAngles( 0, 0, 0 ).ToMat3(); refdef.shaderParms[0] = 1; refdef.shaderParms[1] = 1; refdef.shaderParms[2] = 1; refdef.shaderParms[3] = 1; refdef.width = SCREEN_WIDTH; refdef.height = SCREEN_HEIGHT; refdef.fov_x = 90; refdef.fov_y = 2 * atan( ( float )h / w ) * idMath::M_RAD2DEG; refdef.time = eventLoop->Milliseconds(); world->RenderScene( &refdef ); int frontEnd, backEnd; renderSystem->EndFrame( &frontEnd, &backEnd ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); }
void idGLDrawableMaterial::draw( int x, int y, int w, int h ) { const idMaterial *mat = material; if( mat ) { GL_Viewport( x, y, w, h ); GL_Scissor( x, y, w, h ); glMatrixMode( GL_PROJECTION ); glClearColor( 0.1f, 0.1f, 0.1f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); if( worldDirty ) { InitWorld(); renderLight_t parms; idDict spawnArgs; spawnArgs.Set( "classname", "light" ); spawnArgs.Set( "name", "light_1" ); spawnArgs.Set( "origin", "0 0 0" ); idStr str; sprintf( str, "%f %f %f", light, light, light ); spawnArgs.Set( "_color", str ); gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms ); lightDef = world->AddLightDef( &parms ); idImage *img = ( mat->GetNumStages() > 0 ) ? mat->GetStage( 0 )->texture.image : mat->GetEditorImage(); if( img == NULL ) { common->Warning( "Unable to load image for preview for %s", mat->GetName() ); return; } int width = img->uploadWidth; int height = img->uploadHeight; width *= scale; height *= scale; srfTriangles_t *tris = worldModel->AllocSurfaceTriangles( 4, 6 ); tris->numVerts = 4; tris->numIndexes = 6; tris->indexes[0] = 0; tris->indexes[1] = 1; tris->indexes[2] = 2; tris->indexes[3] = 3; tris->indexes[4] = 1; tris->indexes[5] = 0; tris->verts[0].xyz.x = 64; tris->verts[0].xyz.y = -xOffset + 0 - width / 2; tris->verts[0].xyz.z = yOffset + 0 - height / 2; tris->verts[0].st.x = 1; tris->verts[0].st.y = 1; tris->verts[1].xyz.x = 64; tris->verts[1].xyz.y = -xOffset + width / 2; tris->verts[1].xyz.z = yOffset + height / 2; tris->verts[1].st.x = 0; tris->verts[1].st.y = 0; tris->verts[2].xyz.x = 64; tris->verts[2].xyz.y = -xOffset + 0 - width / 2; tris->verts[2].xyz.z = yOffset + height / 2; tris->verts[2].st.x = 1; tris->verts[2].st.y = 0; tris->verts[3].xyz.x = 64; tris->verts[3].xyz.y = -xOffset + width / 2; tris->verts[3].xyz.z = yOffset + 0 - height / 2; tris->verts[3].st.x = 0; tris->verts[3].st.y = 1; tris->verts[0].normal = tris->verts[1].xyz.Cross( tris->verts[3].xyz ); tris->verts[1].normal = tris->verts[2].normal = tris->verts[3].normal = tris->verts[0].normal; AddTris( tris, mat ); worldModel->FinishSurfaces(); renderEntity_t worldEntity; memset( &worldEntity, 0, sizeof( worldEntity ) ); if( mat->HasGui() ) { worldEntity.gui[ 0 ] = mat->GlobalGui(); } worldEntity.hModel = worldModel; worldEntity.axis = mat3_default; worldEntity.shaderParms[0] = 1; worldEntity.shaderParms[1] = 1; worldEntity.shaderParms[2] = 1; worldEntity.shaderParms[3] = 1; modelDef = world->AddEntityDef( &worldEntity ); worldDirty = false; } renderView_t refdef; // render it renderSystem->BeginFrame( w, h ); memset( &refdef, 0, sizeof( refdef ) ); refdef.vieworg.Set( viewAngle, 0, 0 ); refdef.viewaxis = idAngles( 0, 0, 0 ).ToMat3(); refdef.shaderParms[0] = 1; refdef.shaderParms[1] = 1; refdef.shaderParms[2] = 1; refdef.shaderParms[3] = 1; refdef.width = SCREEN_WIDTH; refdef.height = SCREEN_HEIGHT; refdef.fov_x = 90; refdef.fov_y = 2 * atan( ( float )h / w ) * idMath::M_RAD2DEG; refdef.time = eventLoop->Milliseconds(); world->RenderScene( &refdef ); int frontEnd, backEnd; renderSystem->EndFrame( &frontEnd, &backEnd ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } }