void GR_CocoaImage::cairoSetSource(cairo_t *cr) { UT_return_if_fail(m_surface); double scaleX = (double)getDisplayWidth() / (double)cairo_image_surface_get_width(m_surface); double scaleY = (double)getDisplayHeight() / (double)cairo_image_surface_get_height(m_surface); cairo_scale(cr, scaleX, scaleY); cairo_set_source_surface(cr, m_surface, 0, 0); }
void relocate_targets(){ for (int i=0; i<max_targets; i++) { targets[i].x=rand_range(100,getDisplayWidth()-100); targets[i].y=rand_range(100,getDisplayHeight()-100); } reassign_flares(); }
/** * Resize the buffer size (either normal or fullscreen) */ void ChameleonMScreen::setBufferSize(BufferSize newSize) { if (newSize == fullScreenSize) { qpixmap.resize(getDisplayFullWidth(), getDisplayFullHeight()); } else { qpixmap.resize(getDisplayWidth(), getDisplayHeight()); } }
/*! * Scale our image to rectangle given by rec. The dimensions of rec * are calculated in logical units. */ void GR_UnixImage::scaleImageTo(GR_Graphics * pG, const UT_Rect & rec) { UT_sint32 width = pG->tdu(rec.width); UT_sint32 height = pG->tdu(rec.height); if((width == getDisplayWidth()) && (height == getDisplayHeight())) { return; } scale(width,height); // UT_ASSERT(G_OBJECT(m_image)->ref_count == 1); }
/** * Resize the buffer size (either normal or fullscreen) */ void ChameleonMScreen::setBufferSize(BufferSize newSize) { if (newSize == fullScreenSize) { if (gc->isActive()) { gc->end(); } qpixmap.resize(getDisplayFullWidth(), getDisplayFullHeight()); } else { qpixmap.resize(getDisplayWidth(), getDisplayHeight()); } // Whether current Displayable won't repaint the entire screen on // resize event, the artefacts from the old screen content can appear. // That's why the buffer content is not preserved. qpixmap.fill(Qt::black); }
/*! * Generate an outline of an image with transparency. This is a collection * of (x,y) points marking the first non-transparent point from the left * and right side of the image. * This outline is used by GetOffsetFromLeft and facitates "tight" * text wrapping * around objects. */ void GR_Image::GenerateOutline(void) { DestroyOutline(); UT_sint32 width = getDisplayWidth(); UT_sint32 height = getDisplayHeight(); UT_sint32 i,j=0; // // Generate from left // for(i=0; i< height;i++) { for(j =0; j< width;j++) { if(!isTransparentAt(j,i)) { break; } } if( j < width) { GR_Image_Point * pXY = new GR_Image_Point(); pXY->m_iX = j; pXY->m_iY = i; m_vecOutLine.addItem(pXY); } } // // Generate from Right // for(i=0; i< height;i++) { for(j =width-1; j>= 0;j--) { if(!isTransparentAt(j,i)) { break; } } if( j >= 0) { GR_Image_Point * pXY = new GR_Image_Point(); pXY->m_iX = j; pXY->m_iY = i; m_vecOutLine.addItem(pXY); } } }
void Platform::setMouseCaptured(bool captured) { if (captured != __mouseCaptured) { if (captured) { // Hide the cursor and warp it to the center of the screen __mouseCapturePoint.x = getDisplayWidth() / 2; __mouseCapturePoint.y = getDisplayHeight() / 2; ShowCursor(FALSE); WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y); } else { // Restore cursor WarpMouse(__mouseCapturePoint.x, __mouseCapturePoint.y); ShowCursor(TRUE); } __mouseCaptured = captured; } }
void init_graphic() { memset(&ctx, 0, sizeof(DrawCtx)); // alloc VSH Menu graphic buffers, generic based on canvas constants buf[0].addr = mem_alloc(CANVAS_W * CANVAS_H * sizeof(uint32_t)); // canvas buffer buf[1].addr = mem_alloc(CANVAS_W * CANVAS_H * sizeof(uint32_t)); // background buffer #ifdef HAVE_PNG_FONT // load font png Buffer font = load_png(PNG_FONT_PATH); ctx.font = font.addr; #endif // set drawing context ctx.canvas = buf[0].addr; ctx.bg = buf[1].addr; ctx.bg_color = 0xFF000000; // black, opaque ctx.fg_color = 0xFFFFFFFF; // white, opaque // get current display values offset = *(uint32_t*)0x60201104; // start offset of current framebuffer getDisplayPitch(&pitch, &unk1); // framebuffer pitch size h = getDisplayHeight(); // display height w = getDisplayWidth(); // display width // get x/y start coordinates for our canvas, always center canvas_x = (w - CANVAS_W) /2; canvas_y = (h - CANVAS_H) /2; // dump background, for alpha blending dump_bg(); // init first frame with background dump memcpy((uint8_t *)ctx.canvas, (uint8_t *)ctx.bg, CANVAS_W * CANVAS_H * sizeof(uint32_t)); }
// -------------------------------------------------- // This changes your app's window size to the correct output size void ofxProjectorBlend::setWindowToDisplaySize() { ofSetWindowShape(getDisplayWidth(), getDisplayHeight()); }
bool PageView::paintPage(cairo_t * cr, GdkRectangle * rect) { XOJ_CHECK_TYPE(PageView); double zoom = xournal->getZoom(); g_mutex_lock(this->drawingMutex); int dispWidth = getDisplayWidth(); int dispHeight = getDisplayHeight(); if (this->crBuffer == NULL) { this->crBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dispWidth, dispHeight); cairo_t * cr2 = cairo_create(this->crBuffer); cairo_set_source_rgb(cr2, 1, 1, 1); cairo_rectangle(cr2, 0, 0, dispWidth, dispHeight); cairo_fill(cr2); cairo_scale(cr2, zoom, zoom); const char * txtLoading = _("Loading..."); cairo_text_extents_t ex; cairo_set_source_rgb(cr2, 0.5, 0.5, 0.5); cairo_select_font_face(cr2, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr2, 32.0); cairo_text_extents(cr2, txtLoading, &ex); cairo_move_to(cr2, (page.getWidth() - ex.width) / 2 - ex.x_bearing, (page.getHeight() - ex.height) / 2 - ex.y_bearing); cairo_show_text(cr2, txtLoading); cairo_destroy(cr2); rerenderPage(); } cairo_save(cr); double width = cairo_image_surface_get_width(this->crBuffer); if (width != dispWidth) { double scale = ((double) dispWidth) / ((double) width); // Scale current image to fit the zoom level cairo_scale(cr, scale, scale); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_set_source_surface(cr, this->crBuffer, 0, 0); rerenderPage(); rect = NULL; } else { cairo_set_source_surface(cr, this->crBuffer, 0, 0); } if (rect) { cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); cairo_fill(cr); #ifdef SHOW_PAINT_BOUNDS cairo_set_source_rgb(cr, 1.0, 0.5, 1.0); cairo_set_line_width(cr, 1. / zoom); cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height); cairo_stroke(cr); #endif } else { cairo_paint(cr); } cairo_restore(cr); // don't paint this with scale, because it needs a 1:1 zoom if (this->verticalSpace) { this->verticalSpace->paint(cr, rect, zoom); } cairo_scale(cr, zoom, zoom); if (this->textEditor) { this->textEditor->paint(cr, rect, zoom); } if (this->selection) { this->selection->paint(cr, rect, zoom); } if (this->search) { this->search->paint(cr, rect, zoom, getSelectionColor()); } this->inputHandler->draw(cr, zoom); g_mutex_unlock(this->drawingMutex); return true; }
/*! * The idea is to create a * new image from the rectangular segment in device units defined by * UT_Rect rec. The Image should be deleted by the calling routine. */ GR_Image * GR_Win32Image::createImageSegment(GR_Graphics * pG,const UT_Rect & rec) { // this code assumes 24 bit RGB bitmaps ... UT_return_val_if_fail(pG && m_pDIB && m_pDIB->bmiHeader.biBitCount == 24, NULL); // the ration of x and y coords for the graphics class double fXYRatio = ((GR_Win32Graphics *)pG)->getXYRatio(); // We have three different coordinate systems here: // // rec: the requested segment size, in layout units // // m_pDIB->bmiHeader.biHeight/Width(): physical size of the bitmap // // getDisplayWidth()/Height() : size in device units for which this image was to be // rendered // // From these we need to work out the size/offset of the segment in the DIB // coordinaces // these are the DIB physical dimensions of the original UT_sint32 dH = m_pDIB->bmiHeader.biHeight; UT_sint32 dW = m_pDIB->bmiHeader.biWidth; // this is the internal scaling of the orginal DIB, which we need to workout // relationship between display units and DIB units; we need to use separate factors // for x and y axis, since the proportions of the DIB have no formal relationship to // the dimensions of the displayed rectangle (e.g., the display image could be // cropped). double fDibScaleFactorX = (double) dW / (double)getDisplayWidth(); double fDibScaleFactorY = (double) dH / (double)getDisplayHeight(); // these are the requested dimensions in device units UT_sint32 widthDU = (UT_sint32)((double)pG->tdu(rec.width) * fXYRatio); UT_sint32 heightDU = pG->tdu(rec.height); UT_sint32 xDU = (UT_sint32)((double)pG->tdu(rec.left) * fXYRatio); UT_sint32 yDU = pG->tdu(rec.top); // now convert the DUs into DIB units -- these are the values we need to work with // when copying the image segment UT_sint32 widthDIB = (UT_sint32)((double)widthDU * fDibScaleFactorX); UT_sint32 heightDIB = (UT_sint32)((double)heightDU * fDibScaleFactorY); UT_sint32 xDIB = (UT_sint32)((double)xDU * fDibScaleFactorX); UT_sint32 yDIB = (UT_sint32)((double)yDU * fDibScaleFactorY); if(xDIB < 0) { xDIB = 0; } if(yDIB < 0) { yDIB = 0; } if(heightDIB > dH) { heightDIB = dH; } if(widthDIB > dW) { widthDIB = dW; } if(xDIB + widthDIB > dW) { widthDIB = dW - xDIB; } if(yDIB + heightDIB > dH) { heightDIB = dH - yDIB; } if(widthDIB < 0) { xDIB = dW -1; widthDIB = 1; } if(heightDIB < 0) { yDIB = dH -1; heightDIB = 1; } UT_String sName(""); getName(sName); UT_String sSub(""); UT_String_sprintf(sSub,"_segment_%d_%d_%d_%d",xDIB,yDIB,widthDIB,heightDIB); sName += sSub; GR_Win32Image * pImage = new GR_Win32Image(sName.c_str()); UT_return_val_if_fail( pImage, NULL ); // now allocate memory -- mostly copied from convertFromBuffer() UT_uint32 iBytesInRow = widthDIB * 3; if (iBytesInRow % 4) { iBytesInRow += (4 - (iBytesInRow % 4)); } pImage->m_pDIB = (BITMAPINFO*) g_try_malloc(sizeof(BITMAPINFOHEADER) + heightDIB * iBytesInRow); UT_return_val_if_fail( pImage->m_pDIB, NULL ); // simply copy the whole header memcpy(pImage->m_pDIB, m_pDIB, sizeof(BITMAPINFOHEADER)); // now set the image size ... pImage->setDisplaySize(widthDU, heightDU); pImage->m_pDIB->bmiHeader.biWidth = widthDIB; pImage->m_pDIB->bmiHeader.biHeight = heightDIB; pImage->m_pDIB->bmiHeader.biSizeImage = 0; // now copy the bitmap bits // the rows in both maps are/need to be padded to 4-bytes // NB: in the DIB lines are numbered from bottom up, while in our coord system y goes // from top to bottom // how wide is a row in the orignal ? UT_uint32 iOrigRowBytes = m_pDIB->bmiHeader.biWidth*3; if(iOrigRowBytes%4) iOrigRowBytes += (4 - iOrigRowBytes%4); // what are the coords in the orginal we want? UT_uint32 iByteWidth = widthDIB*3; UT_uint32 iLeft = xDIB*3; UT_uint32 iRight = iLeft + iByteWidth; UT_uint32 iTop = m_pDIB->bmiHeader.biHeight - yDIB; UT_uint32 iBottom = iTop - heightDIB; UT_uint32 iRightPadded = iRight + (iBytesInRow - iByteWidth); UT_Byte * pBits1 = ((UT_Byte*)m_pDIB) + sizeof(BITMAPINFOHEADER); UT_Byte * pBits2 = ((UT_Byte*)pImage->m_pDIB) + sizeof(BITMAPINFOHEADER); UT_uint32 iRow; for(iRow = iBottom; iRow < iTop; iRow++) { memcpy(pBits2, pBits1 + iRow * iOrigRowBytes + iLeft, iByteWidth); pBits2 += iByteWidth; // now the padding ... for(UT_uint32 iPad = iRight; iPad < iRightPadded; iPad++, pBits2++) { *pBits2 = 0; } } return static_cast<GR_Image *>(pImage); }
int main() { // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); flareTex = loadPNG("resources/textures/cloud.png"); width = getDisplayWidth(); height = getDisplayHeight(); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // initialises glprint's matrix, shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); initSprite(getDisplayWidth(), getDisplayHeight()); fileid = 0; loadfile(); for (int i=0; i<max_flares; i++) { flares[i].x=rand_range(0,getDisplayWidth()); flares[i].y=rand_range(0,getDisplayHeight()); flares[i].vx=rand_range(0,10)-5; flares[i].vy=rand_range(0,10)-5; } /*for (int i=0; i<max_targets; i++) { targets[i].x=rand_range(0,getDisplayWidth()); targets[i].y=rand_range(0,getDisplayHeight()); targets[i].flares = 0; }*/ /*for (int i=0; i<max_flares; i++) { flares[i].x=rand_range(0,getDisplayWidth()); flares[i].y=rand_range(0,getDisplayHeight()); flares[i].vx=rand_range(0,10)-5; flares[i].vy=rand_range(0,10)-5; flares[i].target = (int)rand_range(0,max_targets); targets[flares[i].target].flares ++; }*/ // we don't want to draw the back of triangles // the blending is set up for glprint but disabled // while not in use glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glClearColor(0, 0.5, 1, 1); // count each frame int num_frames = 0; // set to true to leave main loop bool quit = false; // get a pointer to the key down array keys = getKeys(); int* mouse = getMouse(); while (!quit) { // the main loop doEvents(); // update mouse and key arrays if (keys[KEY_ESC]) quit = true; // exit if escape key pressed if (keys[KEY_SPACE]) relocate_targets(); // exit if escape key pressed if (keys[KEY_RETURN]) reassign_flares(); // exit if escape key pressed if (keys[KEY_S] && !lastkeys[KEY_S]) save(); // exit if escape key pressed if (keys[KEY_CURSL] && !lastkeys[KEY_CURSL]){ fileid--; if (fileid <0) fileid = 0; loadfile(); // exit if escape key pressed } if (keys[KEY_CURSR] && !lastkeys[KEY_CURSR]){ fileid++; loadfile(); // exit if escape key pressed } if (keys[KEY_C]){ max_targets = 1; // exit if escape key pressed reassign_flares(); } lastkeys[KEY_S] = keys[KEY_S]; lastkeys[KEY_CURSL] = keys[KEY_CURSL]; lastkeys[KEY_CURSR] = keys[KEY_CURSR]; mx = mouse[0]; my = mouse[1]; if(mouse[2] != 0){ spawn_target(mx,my); } for (int i=0; i<RE_MULTIPLY; i++){ random_events(); } think(); render(); // the render loop usleep(1600); // no need to run cpu/gpu full tilt } closeContext(); // tidy up return 0; }
DisplayConfigPtr DisplayConfigFactory::create(OSVR_ClientContext ctx) { DisplayConfigPtr cfg(new DisplayConfig); try { auto const descriptorString = ctx->getStringParameter("/display"); auto desc = display_schema_1::DisplayDescriptor(descriptorString); cfg->m_viewers.container().emplace_back(Viewer(ctx, HEAD_PATH)); auto &viewer = cfg->m_viewers.container().front(); auto eyesDesc = desc.getEyes(); /// Set up stereo vs mono std::vector<uint8_t> eyeIndices; Eigen::Vector3d offset; if (eyesDesc.size() == 2) { // stereo offset = desc.getIPDMeters() / 2. * Eigen::Vector3d::UnitX(); eyeIndices = {0, 1}; } else { // if (eyesDesc.size() == 1) // mono offset = Eigen::Vector3d::Zero(); eyeIndices = {0}; } /// Handle radial distortion parameters boost::optional<OSVR_RadialDistortionParameters> distort; auto k1 = desc.getDistortion(); if (k1.k1_red != 0 || k1.k1_green != 0 || k1.k1_blue != 0) { OSVR_RadialDistortionParameters params; params.k1.data[0] = k1.k1_red; params.k1.data[1] = k1.k1_green; params.k1.data[2] = k1.k1_blue; distort = params; } /// Compute angular offset about Y of the optical (view) axis util::Angle axisOffset = 0. * util::radians; { auto overlapPct = desc.getOverlapPercent(); if (overlapPct < 1.) { const auto hfov = desc.getHorizontalFOV(); const auto angularOverlap = hfov * overlapPct; axisOffset = (hfov - angularOverlap) / 2.; } } /// Infer the number of display inputs and their association with /// eyes (actually surfaces) based on the descriptor. std::vector<OSVR_DisplayInputCount> displayInputIndices; if (eyesDesc.size() == 2 && display_schema_1::DisplayDescriptor::FULL_SCREEN == desc.getDisplayMode()) { // two eyes, full screen - that means two screens. displayInputIndices = {0, 1}; cfg->m_displayInputs.push_back(DisplayInput( desc.getDisplayWidth(), desc.getDisplayHeight())); cfg->m_displayInputs.push_back(DisplayInput( desc.getDisplayWidth(), desc.getDisplayHeight())); } else { // everything else, assume 1 screen. // Note that it's OK that displayInputIndices.size() >= // eyesDesc.size(), we'll just not end up using the second // entry. displayInputIndices = {0, 0}; cfg->m_displayInputs.push_back(DisplayInput( desc.getDisplayWidth(), desc.getDisplayHeight())); } BOOST_ASSERT_MSG(displayInputIndices.size() >= eyesDesc.size(), "Must have at least as many indices as eyes"); /// Create the actual eye (with implied surface) objects for (auto eye : eyeIndices) { // This little computation turns 0 into -1 and 1 into 1, used as // a coefficient to make the two eyes do opposite things. // Doesn't affect mono, which has a zero offset vector. double offsetFactor = (2. * eye) - 1.; // Set up per-eye distortion parameters, if needed boost::optional<OSVR_RadialDistortionParameters> distortEye( distort); if (distortEye) { distortEye->centerOfProjection.data[0] = eyesDesc[eye].m_CenterProjX; distortEye->centerOfProjection.data[1] = eyesDesc[eye].m_CenterProjY; } // precompute translation offset for this eye auto xlateOffset = (offsetFactor * offset).eval(); // precompute the optical axis rotation for this eye // here, the left eye should get a positive offset since it's a // positive rotation about y, hence the -1 factor. auto eyeAxisOffset = axisOffset * -1. * offsetFactor; // Look up the display index for this eye. auto displayInputIdx = displayInputIndices[eye]; /// Create the ViewerEye[Surface] and add it to the container. viewer.container().emplace_back(ViewerEye( ctx, xlateOffset, HEAD_PATH, computeViewport(eye, desc), computeRect(desc), eyesDesc[eye].m_rotate180, desc.getPitchTilt().value(), distortEye, displayInputIdx, eyeAxisOffset)); } OSVR_DEV_VERBOSE("Display: " << desc.getHumanReadableDescription()); return cfg; } catch (std::exception const &e) { OSVR_DEV_VERBOSE( "Couldn't create a display config internally! Exception: " << e.what()); return DisplayConfigPtr{}; } catch (...) { OSVR_DEV_VERBOSE("Couldn't create a display config internally! " "Unknown exception!"); return DisplayConfigPtr{}; } }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)getDisplayWidth() / getDisplayHeight(), 0.1, 100); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); struct timeval t, ta, t1, t2; // fps stuff gettimeofday(&t1, NULL); int num_frames = 0; bool quit = false; mouse = getMouse(); keys = getKeys(); resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)getDisplayWidth()/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } while (!quit) { // the main loop doEvents(); // update mouse and key arrays // mask of 4 is right mouse if (keys[KEY_ESC]) quit = true; glClearColor(0, .5, 1, 1); // render between two gettimeofday calls so // we can sleep long enough to roughly sync // to ~60fps but not on the pi! // TODO find something a tad more elegent long i; gettimeofday(&t, NULL); i = t.tv_sec * 1e6 + t.tv_usec; // render(); float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i fps=%3.2f", frame, lfps); kmVec3 tmp; playerFireCount--; if (keys[KEY_LCTRL] && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); kmMat4RotationPitchYawRoll(&model, rad * 4, 0, -rad * 4); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (keys[KEY_CURSL] && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (keys[KEY_CURSR] && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 320, font1,"mouse %i,%i %i ", mouse[0], mouse[1], mouse[2]); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); swapBuffers(); gettimeofday(&ta, NULL); long j = (ta.tv_sec * 1e6 + ta.tv_usec); i = j - i; if (i < 0) i = 1000000; // pass through - slower that 60fps if (i < 16000) usleep(16000 - i); // every 10 frames average the time taken and store // fps value for later printing with glprintf if (++num_frames % 10 == 0) { gettimeofday(&t2, NULL); float dtf = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; lfps = num_frames / dtf; num_frames = 0; t1 = t2; } } closeContext(); return 0; }