void MGuiSlide::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(! isPressed()) updateFromVariable(); if(isPressed()) // pressed { render->setColor4(getPressedColor()); if(hasPressedTexture()) { render->enableTexture(); m_button.drawTexturedQuad(getPressedTexture()); } else { render->disableTexture(); m_button.drawQuad(); } } else if(isHighLight()) // highLight { render->setColor4(getHighLightColor()); if(hasHighLightTexture()){ render->enableTexture(); m_button.drawTexturedQuad(getHighLightTexture()); } else { render->disableTexture(); m_button.drawQuad(); } } else // normal { render->setColor4(getNormalColor()); if(hasNormalTexture()) { render->enableTexture(); m_button.drawTexturedQuad(getNormalTexture()); } else { render->disableTexture(); m_button.drawQuad(); } } MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; if(m_pointerEvent) m_pointerEvent(this, &guiEvent); }
void MaratisPlayer::graphicLoop(void) { MWindow * window = MWindow::getInstance(); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); // game MGame * game = engine->getGame(); if(game) { if(game->isRunning()) { render->disableScissorTest(); render->setViewport(0, 0, window->getWidth(), window->getHeight()); game->draw(); } else { render->clear(M_BUFFER_COLOR); } } else { render->clear(M_BUFFER_COLOR); } }
void Atlas::Generate(bool clear) { m_Atlas.create(M_UBYTE, m_Width, m_Height, m_BPP); unsigned char col[]= {255, 255, 255, 0}; for(uint32 x = 0; x < m_Width; ++x) for(uint32 y = 0; y < m_Height; ++y) m_Atlas.writePixel(x, y, col); for(imageMapIter iImage = m_Images.begin(); iImage != m_Images.end(); iImage++) WriteImage(iImage->second); MEngine* engine = MEngine::getInstance(); MRenderingContext* render = engine->getRenderingContext(); if(m_TextureID == 0) render->createTexture(&m_TextureID); render->bindTexture(m_TextureID); render->sendTextureImage(&m_Atlas, false, 1, 0); if(clear) { // remove images delete [] m_Layout; m_Layout = NULL; } }
void MGui2d::drawTexturedQuad(unsigned int textureId) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[8]; MVector2 g_texCoords[8]; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); g_vertices[0] = MVector2(m_position.x, m_position.y); g_vertices[1] = MVector2(m_position.x, m_position.y + m_scale.y); g_vertices[3] = MVector2(m_position.x + m_scale.x, m_position.y + m_scale.y); g_vertices[2] = MVector2(m_position.x + m_scale.x, m_position.y); g_texCoords[0] = MVector2(0, 0); g_texCoords[1] = MVector2(0, 1); g_texCoords[3] = MVector2(1, 1); g_texCoords[2] = MVector2(1, 0); render->setTexCoordPointer(M_FLOAT, 2, g_texCoords); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->bindTexture(textureId); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); }
void MGuiTextureFont::draw(const char * text, const MVector2 & position, float size) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[4]; MVector2 g_texCoords[4]; float xc=position.x, yc=position.y, u=0, v=0; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->setTexCoordPointer(M_FLOAT, 2, g_texCoords); render->bindTexture(m_texture); unsigned int i; unsigned int textLength = strlen(text); for(i=0; i<textLength; i++) { if(text[i] == '\n') // return { yc += size; xc = position.x; } else if(text[i] == ' ') // tab { xc += size * getTabSpace(); } else { u=float((unsigned char)text[i]%16)/16.0f; //u position of character v=float((unsigned char)text[i]/16)/16.0f; //v position of character g_texCoords[0] = MVector2(u, v+0.0625f); g_vertices[0] = MVector2(xc, yc+size); g_texCoords[1] = MVector2(u+0.0625f, v+0.0625f); g_vertices[1] = MVector2(xc+size, yc+size); g_texCoords[3] = MVector2(u+0.0625f, v+0.001f); g_vertices[3] = MVector2(xc+size, yc); g_texCoords[2] = MVector2(u, v+0.001f); g_vertices[2] = MVector2(xc, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); xc += size * getSpace(); //move to next character } } }
void MLevel::createFX(MShaderRef * vertexShaderRef, MShaderRef * pixelShaderRef, unsigned int * FXId) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); unsigned int i; unsigned int size = m_FXManager.getFXRefsNumber(); for(i=0; i<size; i++) { MFXRef * FXRef = (MFXRef *)m_FXManager.getFXRef(i); if((FXRef->getVertexShaderRef() == vertexShaderRef) && (FXRef->getPixelShaderRef() == pixelShaderRef)) { *FXId = FXRef->getFXId(); return; } } render->createFX(FXId, vertexShaderRef->getShaderId(), pixelShaderRef->getShaderId()); m_FXManager.addFXRef(*FXId, vertexShaderRef, pixelShaderRef); }
void MFixedRenderer::enableFog(MOCamera * camera) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); float fogMin = camera->getClippingFar()*0.9999f; if(camera->hasFog()) { render->enableFog(); float camFogMin = camera->getClippingFar() - camera->getFogDistance(); if(camFogMin < fogMin) fogMin = camFogMin; } else { render->disableFog(); } render->setFogColor(camera->getClearColor()); render->setFogDistance(fogMin, camera->getClippingFar()); }
void MGuiImage::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(hasNormalTexture()) { render->setColor4(getNormalColor()); render->enableTexture(); drawTexturedQuad(getNormalTexture()); return; } render->setColor4(getNormalColor()); render->disableTexture(); drawQuad(); }
void MShaderRef::update(void) { MEngine * engine = MEngine::getInstance(); MLevel * level = engine->getLevel(); MRenderingContext * render = engine->getRenderingContext(); char * text = readTextFile(getFilename()); if(text) { // gen shader if null if(m_shaderId == 0) { switch(m_type) { case M_SHADER_VERTEX: render->createVertexShader(&m_shaderId); break; case M_SHADER_PIXEL: render->createPixelShader(&m_shaderId); break; } } // send shader source render->sendShaderSource(m_shaderId, text); SAFE_FREE(text); MFXManager * FXManager = level->getFXManager(); unsigned int i; unsigned int size = FXManager->getFXRefsNumber(); for(i=0; i<size; i++) { MFXRef * FXRef = FXManager->getFXRef(i); if((FXRef->getPixelShaderRef() == this) || (FXRef->getVertexShaderRef() == this)) { unsigned int FXId = FXRef->getFXId(); render->updateFX(FXId); } } } }
// draw void draw(void) { MMouse * mouse = MMouse::getInstance(); MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); Maratis::getInstance()->graphicLoop(); if(logo) { set2dMode(render); render->setBlendingMode(M_BLENDING_ALPHA); render->enableTexture(); render->setColor4(MVector4(1.0f)); drawLogo(); } if(mouse->isLeftButtonPushed() || mouse->isMiddleButtonPushed() || (mouse->getWheelDirection() != 0)) logo = false; MWindow::getInstance()->swapBuffer(); }
void Atlas::Select() { if(g_Selected == this) return; MEngine* engine = MEngine::getInstance(); MRenderingContext* render = engine->getRenderingContext(); Renderer::Flush(); render->enableTexture(); render->setBlendingMode(M_BLENDING_ALPHA); render->enableBlending(); if(m_TextureID != 0) { render->bindTexture(m_TextureID); //render->sendTextureImage(&m_Atlas, false, 1, 0); } g_Selected = this; }
void MTextureRef::update(void) { M_PROFILE_SCOPE(MTextureRef::update); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); MImage image; if(engine->getImageLoader()->loadData(getFilename(), &image)) { if(m_textureId == 0) render->createTexture(&m_textureId); m_components = image.getComponents(); m_width = image.getWidth(); m_height = image.getHeight(); // send texture image render->bindTexture(m_textureId); render->sendTextureImage(&image, isMipmapEnabled(), 1, 0); } }
void draw(void) { MWindow * window = MWindow::getInstance(); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); MGame * game = engine->getGame(); // set basic viewport render->disableScissorTest(); render->setViewport(0, 0, window->getWidth(), window->getHeight()); if(game) { if(game->isRunning()) { game->draw(); } } window->swapBuffer(); }
void MOCamera::updateProjMatrix(void) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); render->getViewport(m_currentViewport); float ratio = (m_currentViewport[2] / (float)m_currentViewport[3]); // perspective view if(! isOrtho()) { // normal perspective projection createPerspectiveView(&m_currentProjMatrix, m_fov, ratio, m_clippingNear, m_clippingFar); return; } // ortho view float height = m_fov * 0.5f; float width = height * ratio; createOrthoView(&m_currentProjMatrix, -width, width, -height, height, m_clippingNear, m_clippingFar); }
void endDraw(void) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); render->disableTexCoordArray(); render->disableColorArray(); render->disableNormalArray(); render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, g_vertices); render->drawArray(g_primitiveType, 0, g_verticesNumber); }
void MOCamera::enableViewProjMatrix(void) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); // projection render->setMatrixMode(M_MATRIX_PROJECTION); render->loadIdentity(); render->multMatrix(&m_currentProjMatrix); // model view mode render->setMatrixMode(M_MATRIX_MODELVIEW); render->loadIdentity(); render->multMatrix(&m_currentViewMatrix); }
void MGame::draw(void) { MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); // get level MLevel * level = MEngine::getInstance()->getLevel(); if(! level) return; // get current scene MScene * scene = level->getCurrentScene(); if(! scene) return; // clear buffer render->enableDepthTest(); if(scene->getCamerasNumber() == 0) { // draw scene with default camera MOCamera camera; render->setClearColor(*camera.getClearColor()); render->clear(M_BUFFER_COLOR | M_BUFFER_DEPTH); camera.enable(); camera.updateListener(); scene->draw(&camera); } else { MOCamera * camera = NULL; unsigned int currentCamera = scene->getCurrentCamera(); if(currentCamera < scene->getCamerasNumber()) camera = scene->getCameraByIndex(currentCamera); else camera = scene->getCameraByIndex(0); render->setClearColor(*camera->getClearColor()); render->clear(M_BUFFER_COLOR | M_BUFFER_DEPTH); camera->enable(); camera->updateListener(); scene->draw(camera); } }
// main int main(int argc, char **argv) { setlocale(LC_NUMERIC, "C"); unsigned int width = 800; unsigned int height = 400; bool fullscreen = false; // get engine MEngine* engine = MEngine::getInstance(); // get window MWindow* window = MWindow::getInstance(); window->setPointerEvent(windowEvents); // window events // create window if(! window->create("Maratis - ManualUse example", width, height, 32, fullscreen)) { MLOG(4, "window create failed"); return 0; } if(fullscreen) window->hideCursor(); // set current directory { char rep[256]; getRepertory(rep, argv[0]); window->setCurrentDirectory(rep); } // create virtual contexts MSoundContext * soundContext = new MALContext(); MRenderingContext * render = new MGLContext(); MPhysicsContext * physics = new MBulletContext(); MScriptContext * script = new MScript(); MInputContext * input = new MInput(); MSystemContext * system = new MWinContext(); MLOG(5, "Render version: " << render->getRendererVersion()); // create default Level and Game MLevel * level = new MLevel(); MGame * game = new MyGame(); // MyGame // init MEngine (you can replace all contexts by others and add or use different data loaders) engine->setSoundContext(soundContext); // sound context engine->setRenderingContext(render); // rendering context engine->setPhysicsContext(physics); // physics context engine->setScriptContext(script); // script context engine->setInputContext(input); // input context engine->setSystemContext(system); // system context engine->getImageLoader()->addLoader(M_loadImage); // image loader engine->getSoundLoader()->addLoader(M_loadSound); // sound loader // engine->getLevelLoader()->addLoader(xmlLevelLoad); // level loader : uncomment if wanted engine->getFontLoader()->addLoader(M_loadFont); // font loader // engine->getFontLoader()->addLoader(M_loadBinFont); // bin font loader : uncomment if wanted // add some default "Maratis" behaviors : uncomment if wanted or add custom // engine->getBehaviorManager()->addBehavior(MBLookAt::getStaticName(), M_OBJECT3D_CAMERA, MBLookAt::getNew); // engine->getBehaviorManager()->addBehavior(MBFollow::getStaticName(), M_OBJECT3D, MBFollow::getNew); // add renderers engine->getRendererManager()->addRenderer(MStandardRenderer::getStaticName(), MStandardRenderer::getNew); engine->getRendererManager()->addRenderer(MFixedRenderer::getStaticName(), MFixedRenderer::getNew); // mesh loader engine->getMeshLoader()->addLoader(xmlMeshLoad); engine->getArmatureAnimLoader()->addLoader(xmlArmatureAnimLoad); engine->getTexturesAnimLoader()->addLoader(xmlTextureAnimLoad); engine->getMaterialsAnimLoader()->addLoader(xmlMaterialAnimLoad); // set level engine->setLevel(level); // set game engine->setGame(game); // set renderer (standard) MRenderer * renderer = engine->getRendererManager()->getRendererByName("StandardRenderer")->getNewRenderer(); engine->setRenderer(renderer); // begin game game->begin(); // time unsigned int frequency = 60; unsigned long previousFrame = 0; unsigned long startTick = window->getSystemTick(); // on events while(window->isActive()) { // on events if(window->onEvents()) { // compute target tick unsigned long currentTick = window->getSystemTick(); unsigned long tick = currentTick - startTick; unsigned long frame = (unsigned long)(tick * (frequency * 0.001f)); // update elapsed time unsigned int i; unsigned int steps = (unsigned int)(frame - previousFrame); if(window->getFocus()) { // don't wait too much if(steps >= (frequency/2)) { update(); draw(); previousFrame += steps; continue; } // update for(i=0; i<steps; i++) { update(); previousFrame++; } // draw if(steps > 0){ draw(); } } else { previousFrame = frame; window->swapBuffer(); } } } MLOG(5, "ending game..."); game->end(); MLOG(5, "destroying renderer..."); renderer->destroy(); SAFE_DELETE(game); SAFE_DELETE(level); SAFE_DELETE(render); SAFE_DELETE(soundContext); SAFE_DELETE(physics); SAFE_DELETE(script); SAFE_DELETE(input); SAFE_DELETE(system); return 0; }
void MFixedRenderer::drawDisplayTriangles(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplayTriangles); MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // display properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_CULL_MODES cullMode = display->getCullMode(); // cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // indices M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); // FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else render->drawArray(primitiveType, begin, size); // disable vertex array render->disableVertexArray(); // restore FX render->bindFX(0); }
void MGuiWindow::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; MWindow * window = MWindow::getInstance(); rescaleScrollingBar(); render->enableScissorTest(); render->setScissor((int)getPosition().x, window->getHeight() - (int)getPosition().y - (unsigned int)getScale().y, (unsigned int)getScale().x, (unsigned int)getScale().y); // normal clear if((getNormalColor().w >= 1.0f) && (! hasNormalTexture())) { render->setClearColor(getNormalColor()); render->clear(M_BUFFER_COLOR); MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; if(m_pointerEvent) m_pointerEvent(this, &guiEvent); // 2d mode set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); render->enableTexture(); } else { // background set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); if(hasNormalTexture()) // texture clear { render->enableTexture(); render->setColor4(getNormalColor()); drawTexturedQuad(getNormalTexture()); } else if(getNormalColor().w < 1.0f) { render->disableTexture(); render->setColor4(getNormalColor()); drawQuad(); } if(m_pointerEvent) { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; m_pointerEvent(this, &guiEvent); // 2d mode set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); render->enableTexture(); } } // gui render->pushMatrix(); render->translate(MVector3(getPosition().x, getPosition().y, 0)); render->pushMatrix(); render->translate(MVector3(getScroll().x, getScroll().y, 0)); // drawing unsigned int i; unsigned int oSize = m_objects.size(); for(i=0; i<oSize; i++) m_objects[i]->draw(); render->popMatrix(); // draw shadows if(hasShadow()) { render->disableScissorTest(); drawShadow(); render->enableScissorTest(); } // scolling slides if(isHorizontalScroll()) m_hScrollSlide.draw(); if(isVerticalScroll()) m_vScrollSlide.draw(); render->popMatrix(); }
bool M_loadFont(const char * filename, void * data, void * arg) { MFont * font = (MFont *)data; int pen_x, pen_y, max_y; unsigned int n, max_code = 4096; unsigned int size = font->getFontSize(); unsigned int space = 2; unsigned int width = 1024; unsigned int height = 0; MImage image; FT_GlyphSlot slot; FT_Library library; FT_Face face; FT_Byte * file_base; FT_Long file_size; // init FT_Error error = FT_Init_FreeType(&library); if(error){ printf("ERROR Load Font : unable to init FreeType\n"); return false; } // open file MFile * file = M_fopen(filename, "rb"); if(! file) { FT_Done_FreeType(library); printf("ERROR Load Font : can't read file %s\n", filename); return false; } M_fseek(file, 0, SEEK_END); file_size = M_ftell(file); M_rewind(file); file_base = new FT_Byte[file_size]; if(file_size != M_fread(file_base, sizeof(FT_Byte), file_size, file)) { M_fclose(file); FT_Done_FreeType(library); delete [] file_base; return false; } // read font error = FT_New_Memory_Face(library, file_base, file_size, 0, &face); M_fclose(file); if(error) { printf("ERROR Load Font : unable to read data %s\n", filename); FT_Done_FreeType(library); delete [] file_base; return false; } // set font size error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { printf("ERROR Load Font : unable to size font\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // parse characters max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > width) { pen_x = space; pen_y += max_y + space; height += max_y + space; max_y = 0; } // increment pen position pen_x += slot->bitmap.width + space; } if(height == 0) { printf("ERROR Load Font : unable to create font texture\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // create image height = getNextPowerOfTwo(height); image.create(M_UBYTE, width, height, 4); memset(image.getData(), 0, image.getSize()*sizeof(char)); // init font font->setTextureWidth(width); font->setTextureHeight(height); // create font texture max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > (int)image.getWidth()){ pen_x = space; pen_y += max_y + space; } // get character properties float xAdvance = (slot->advance.x >> 6) / ((float)size); MVector2 offset = MVector2((float)slot->bitmap_left - 1, - (float)slot->bitmap_top - 1) / ((float)size); MVector2 pos = MVector2((float)(pen_x-1) / (float)width, (float)(pen_y-1) / (float)height); MVector2 scale = MVector2((float)(slot->bitmap.width+2) / (float)width, (float)(slot->bitmap.rows+2) / (float)height); // set character font->setCharacter(n, MCharacter(xAdvance, offset, pos, scale)); // draw to image drawBitmap(&image, &slot->bitmap, pen_x, pen_y); // increment pen position pen_x += slot->bitmap.width + space; } // send texture MEngine * engine = MEngine().getInstance(); MRenderingContext * render = engine->getRenderingContext(); // gen texture id unsigned int textureId = font->getTextureId(); if(textureId == 0) { render->createTexture(&textureId); font->setTextureId(textureId); } // send texture image render->bindTexture(textureId); render->setTextureUWrapMode(M_WRAP_REPEAT); render->setTextureVWrapMode(M_WRAP_REPEAT); render->sendTextureImage(&image, 0, 1, 0); // finish FT_Done_FreeType(library); delete [] file_base; return true; }
bool exportFontBin(const char * filename, MFont * font) { if(! font) return false; MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); // read image MImage image; render->bindTexture(font->getTextureId()); render->getTexImage(0, &image); unsigned int width = image.getWidth(); unsigned int height = image.getHeight(); if(width == 0 && height == 0) { printf("Error : unable to create image font for %s\n", filename); return false; } // create file FILE * file = fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // bin fwrite(M_FONT_HEADER, sizeof(char), 8, file); // version int version = 1; fwrite(&version, sizeof(int), 1, file); // font size unsigned int fontSize = font->getFontSize(); fwrite(&fontSize, sizeof(int), 1, file); // write image { fwrite(&width, sizeof(int), 1, file); fwrite(&height, sizeof(int), 1, file); unsigned char color[4]; unsigned int x, y; for(y=0; y<height; y++) { for(x=0; x<width; x++) { image.readPixel(x, y, color); fwrite(&color[3], sizeof(char), 1, file); } } } // write characters infos { map <unsigned int, MCharacter> * characters = font->getCharacters(); // size unsigned int size = font->getCharactersNumber(); fwrite(&size, sizeof(int), 1, file); // characters map <unsigned int, MCharacter>::iterator mit (characters->begin()), mend(characters->end()); for(;mit!=mend;++mit) { unsigned int charCode = mit->first; MCharacter * character = &mit->second; MVector2 pos = character->getPos(); MVector2 offset = character->getOffset(); MVector2 scale = character->getScale(); float xadvance = character->getXAdvance(); fwrite(&charCode, sizeof(int), 1, file); fwrite(&pos, sizeof(float), 2, file); fwrite(&offset, sizeof(float), 2, file); fwrite(&scale, sizeof(float), 2, file); fwrite(&xadvance, sizeof(float), 1, file); } } fclose(file); return true; }
void MGuiTextureFont::drawSelection(const char * text, const MVector2 & position, float size, unsigned int startId, unsigned int endId) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(startId == endId) return; MVector2 g_vertices[4]; render->disableNormalArray(); render->disableColorArray(); render->disableTexCoordArray(); render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); unsigned int start; unsigned int end; if(endId > startId) { start = startId; end = endId; } else { start = endId; end = startId; } render->disableTexture(); MVector2 startPosition = getCharacterPosition(text, position, size, start); float xc = startPosition.x; float yc = startPosition.y; float offset = (size - (size*getSpace()))*0.5f; // left quad g_vertices[0] = MVector2(xc+offset, yc); g_vertices[1] = MVector2(xc+offset, yc+size); unsigned int i; unsigned int textLength = strlen(text); for(i=start; i<end && i<textLength; i++) { if(text[i] == '\n') // return { // right quad { g_vertices[3] = MVector2(xc+size*0.5f, yc+size); g_vertices[2] = MVector2(xc+size*0.5f, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } yc += size; xc = position.x; // left quad { g_vertices[0] = MVector2(xc+offset, yc); g_vertices[1] = MVector2(xc+offset, yc+size); } } else if(text[i] == ' ') // tab { xc += size * getTabSpace(); if(i+1 == end || i+1 == textLength) { // right quad g_vertices[3] = MVector2(xc+offset, yc+size); g_vertices[2] = MVector2(xc+offset, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } } else { xc += size * getSpace(); //move to next character if(i+1 == end || i+1 == textLength) { // right quad g_vertices[3] = MVector2(xc+offset, yc+size); g_vertices[2] = MVector2(xc+offset, yc); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } } } }
void MGui2d::drawShadow(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); MVector2 g_vertices[8]; MVector4 g_colors[8]; render->disableTexture(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); MVector4 color0 = MVector4(0, 0, 0, 0); MVector4 color1 = MVector4(0, 0, 0, 0.05f); float size = 4; MVector2 dir[4]; dir[0] = MVector2(size, size*0.4f); dir[1] = MVector2(size*0.4f, size); dir[2] = MVector2(size*0.4f, size*0.1f); dir[3] = MVector2(size*0.1f, size*0.4f); render->disableNormalArray(); render->disableTexCoordArray(); render->enableVertexArray(); render->enableColorArray(); render->setVertexPointer(M_FLOAT, 2, g_vertices); render->setColorPointer(M_FLOAT, 4, g_colors); for(int i=0; i<4; i++) { g_colors[0] = color1; g_vertices[0] = MVector2(0, m_scale.y) + MVector2(dir[i].x, 0); g_colors[1] = color0; g_vertices[1] = MVector2(0, m_scale.y) + MVector2(size, size) + dir[i]; g_colors[2] = color1; g_vertices[2] = MVector2(m_scale.x, m_scale.y); g_colors[3] = color0; g_vertices[3] = MVector2(m_scale.x, m_scale.y) + MVector2(size, size) + dir[i]; g_colors[4] = color1; g_vertices[4] = MVector2(m_scale.x, 0) + MVector2(0, dir[i].y); g_colors[5] = color0; g_vertices[5] = MVector2(m_scale.x, 0) + MVector2(size, size) + dir[i]; render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 6); } }
void MGui2d::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(isPressed()) // pressed { render->setColor4(getPressedColor()); if(hasPressedTexture()) { render->enableTexture(); drawTexturedQuad(getPressedTexture()); } else { render->disableTexture(); drawQuad(); } } else if(isHighLight()) // highLight { render->setColor4(getHighLightColor()); if(hasHighLightTexture()){ render->enableTexture(); drawTexturedQuad(getHighLightTexture()); } else { render->disableTexture(); drawQuad(); } } else // normal { render->setColor4(getNormalColor()); if(hasNormalTexture()) { render->enableTexture(); drawTexturedQuad(getNormalTexture()); } else { render->disableTexture(); drawQuad(); } } if(isDrawingText() && (getText() != NULL)) { render->enableTexture(); render->setColor4(getTextColor()); getFont()->draw(getText(), getPosition(), getTextSize()); } // draw shadows if(hasShadow()) { render->pushMatrix(); render->translate(MVector3(getPosition().x, getPosition().y, 0)); drawShadow(); render->popMatrix(); } }
void MGuiEditText::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(! isPressed()) updateFromVariable(); // draw selection if(isPressed()) { render->disableTexture(); render->setColor4(MVector4(1, 0.1f, 0.1f, 0.3f)); getFont()->drawSelection(getText(), getPosition(), getTextSize(), m_startSelectionId, m_endSelectionId); } // set text color if(isPressed()){ render->setColor4(getPressedColor()); } else if(isHighLight()){ render->setColor4(getHighLightColor()); } else{ render->setColor4(getNormalColor()); } // draw text render->enableTexture(); getFont()->draw(getText(), getPosition(), getTextSize()); if(isPressed() && (m_startSelectionId == m_endSelectionId)) // cursor { render->disableTexture(); render->setColor4(MVector4(1, 0, 0, 0.5f)); // position MVector2 position = getFont()->getCharacterPosition( getText(), getPosition(), getTextSize(), getCharId() ); // scale MVector2 scale = MVector2(getTextSize() * 0.1f, getTextSize()); float offset = (getTextSize() - (getTextSize()*getFont()->getSpace()))*0.5f; float px = (float)((int)(position.x + offset)); float py = (float)((int)position.y); // draw render->disableNormalArray(); render->disableTexCoordArray(); render->disableColorArray(); render->enableVertexArray(); MVector2 vertices[4] = { MVector2(px, py), MVector2(px, py + scale.y), MVector2(px + scale.x, py), MVector2(px + scale.x, py + scale.y) }; render->setVertexPointer(M_FLOAT, 2, vertices); render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); } MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; if(m_pointerEvent) m_pointerEvent(this, &guiEvent); }
void MFixedRenderer::drawDisplay(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices, MVector3 * normals, MColor * colors) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplay); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); render->setColor4(MVector4(1, 1, 1, 1)); // get material MMaterial * material = display->getMaterial(); { float opacity = material->getOpacity(); if(opacity <= 0.0f) return; // data M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector2 * texCoords = subMesh->getTexCoords(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // get properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_BLENDING_MODES blendMode = material->getBlendMode(); M_CULL_MODES cullMode = display->getCullMode(); MVector3 * diffuse = material->getDiffuse(); MVector3 * specular = material->getSpecular(); MVector3 * emit = material->getEmit(); float shininess = material->getShininess(); // get current fog color MVector3 currentFogColor; render->getFogColor(¤tFogColor); // set cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // texture passes unsigned int texturesPassNumber = MIN(8, material->getTexturesPassNumber()); // set blending mode render->setBlendingMode(blendMode); // alpha test if(blendMode != M_BLENDING_ALPHA && texturesPassNumber > 0) { MTexturePass * texturePass = material->getTexturePass(0); MTexture * texture = texturePass->getTexture(); if(texture) { if(texture->getTextureRef()->getComponents() > 3) render->setAlphaTest(0.5f); } } // set fog color depending on blending switch(blendMode) { case M_BLENDING_ADD: case M_BLENDING_LIGHT: render->setFogColor(MVector3(0, 0, 0)); break; case M_BLENDING_PRODUCT: render->setFogColor(MVector3(1, 1, 1)); break; } // fixed pipeline { // no FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // Normal if(normals) { render->enableNormalArray(); render->setNormalPointer(M_FLOAT, normals); } // Color if(colors) { render->disableLighting(); render->enableColorArray(); render->setColorPointer(M_UBYTE, 4, colors); } // Material render->setMaterialDiffuse(MVector4(diffuse->x, diffuse->y, diffuse->z, opacity)); render->setMaterialSpecular(MVector4(*specular)); render->setMaterialAmbient(MVector4()); render->setMaterialEmit(MVector4(*emit)); render->setMaterialShininess(shininess); // switch to texture matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_TEXTURE); else render->disableTexture(); // Textures int id = texturesPassNumber; for(unsigned int t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); if((! texture) || (! texCoords)) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); continue; } // texCoords unsigned int offset = 0; if(subMesh->isMapChannelExist(texturePass->getMapChannel())) offset = subMesh->getMapChannelOffset(texturePass->getMapChannel()); // texture id unsigned int textureId = 0; MTextureRef * texRef = texture->getTextureRef(); if(texRef) textureId = texRef->getTextureId(); // bind texture render->bindTexture(textureId, t); render->enableTexture(); render->setTextureCombineMode(texturePass->getCombineMode()); render->setTextureUWrapMode(texture->getUWrapMode()); render->setTextureVWrapMode(texture->getVWrapMode()); // texture matrix render->loadIdentity(); render->translate(MVector2(0.5f, 0.5f)); render->scale(*texture->getTexScale()); render->rotate(MVector3(0, 0, -1), texture->getTexRotate()); render->translate(MVector2(-0.5f, -0.5f)); render->translate(*texture->getTexTranslate()); // texture coords render->enableTexCoordArray(); render->setTexCoordPointer(M_FLOAT, 2, texCoords + offset); } // switch back to modelview matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_MODELVIEW); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else{ render->drawArray(primitiveType, begin, size); } // disable arrays render->disableVertexArray(); if(normals) render->disableNormalArray(); if(colors) render->disableColorArray(); // restore textures for(int t=(int)(id-1); t>=0; t--) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); render->setTextureCombineMode(M_TEX_COMBINE_MODULATE); render->setMatrixMode(M_MATRIX_TEXTURE); render->loadIdentity(); render->setMatrixMode(M_MATRIX_MODELVIEW); } } // restore fog and alpha test render->setFogColor(currentFogColor); if(blendMode != M_BLENDING_ALPHA) render->setAlphaTest(0.0f); // restore lighting if(colors) render->enableLighting(); } }
void MFixedRenderer::drawTransparents(MSubMesh * subMesh, MArmature * armature) { M_PROFILE_SCOPE(MFixedRenderer::drawTransparents); MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); // data MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MColor * colors = subMesh->getColors(); if(! vertices) return; MSkinData * skinData = subMesh->getSkinData(); if(armature && skinData) { unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); MVector3 * skinVertices = getVertices(verticesSize); MVector3 * skinNormals = getNormals(normalsSize); computeSkinning(armature, skinData, vertices, normals, NULL, skinVertices, skinNormals, NULL); subMesh->getBoundingBox()->initFromPoints(skinVertices, verticesSize); vertices = skinVertices; normals = skinNormals; } render->setColorMask(0, 0, 0, 0); unsigned int i; unsigned int displayNumber = subMesh->getDisplaysNumber(); for(i=0; i<displayNumber; i++) { MDisplay * display = subMesh->getDisplay(i); if((! display->isVisible()) || (! display->getMaterial())) continue; if(display->getMaterial()->getBlendMode() == M_BLENDING_ALPHA) drawDisplayTriangles(subMesh, display, vertices); } render->setColorMask(1, 1, 1, 1); render->setDepthMask(0); for(i=0; i<displayNumber; i++) { MDisplay * display = subMesh->getDisplay(i); if(! display->isVisible()) continue; MMaterial * material = display->getMaterial(); if(material) { if(material->getBlendMode() != M_BLENDING_NONE) drawDisplay(subMesh, display, vertices, normals, colors); } } render->setDepthMask(1); }
void MFixedRenderer::drawScene(MScene * scene, MOCamera * camera) { M_PROFILE_SCOPE(MFixedRenderer::drawScene); struct MEntityLight { MBox3d lightBox; MOLight * light; }; struct MSubMeshPass { unsigned int subMeshId; unsigned int lightsNumber; MObject3d * object; MOLight * lights[4]; }; // sub objects #define MAX_TRANSP_SUBOBJ 4096 static int transpList[MAX_TRANSP_SUBOBJ]; static float transpZList[MAX_TRANSP_SUBOBJ]; static MSubMeshPass transpSubObjs[MAX_TRANSP_SUBOBJ]; // lights list #define MAX_ENTITY_LIGHTS 256 static int entityLightsList[MAX_ENTITY_LIGHTS]; static float entityLightsZList[MAX_ENTITY_LIGHTS]; static MEntityLight entityLights[MAX_ENTITY_LIGHTS]; // get render MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); render->enableLighting(); render->enableBlending(); // make frustum MFrustum * frustum = camera->getFrustum(); frustum->makeVolume(camera); // update visibility updateVisibility(scene, camera); // fog enableFog(camera); // camera MVector3 cameraPos = camera->getTransformedPosition(); // transp sub obj number unsigned int transpSubObsNumber = 0; // lights unsigned int l; unsigned int lSize = scene->getLightsNumber(); // entities unsigned int i; unsigned int eSize = scene->getEntitiesNumber(); for(i=0; i<eSize; i++) { // get entity MOEntity * entity = scene->getEntityByIndex(i); MMesh * mesh = entity->getMesh(); if(! entity->isActive()) continue; if(! entity->isVisible()) { if(mesh) { MArmature * armature = mesh->getArmature(); MArmatureAnim * armatureAnim = mesh->getArmatureAnim(); if(armature) { // animate armature if(armatureAnim) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // TODO : optimize and add a tag to desactivate it updateSkinning(mesh, armature); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } } continue; } // draw mesh if(mesh) { MVector3 scale = entity->getTransformedScale(); MBox3d * entityBox = entity->getBoundingBox(); float minScale = scale.x; minScale = MIN(minScale, scale.y); minScale = MIN(minScale, scale.z); minScale = 1.0f / minScale; unsigned int entityLightsNumber = 0; for(l=0; l<lSize; l++) { // get entity MOLight * light = scene->getLightByIndex(l); if(! light->isActive()) continue; if(! light->isVisible()) continue; // light box MVector3 lightPos = light->getTransformedPosition(); MVector3 localPos = entity->getInversePosition(lightPos); float localRadius = light->getRadius() * minScale; MBox3d lightBox( MVector3(localPos - localRadius), MVector3(localPos + localRadius) ); if(! entityBox->isInCollisionWith(&lightBox)) continue; MEntityLight * entityLight = &entityLights[entityLightsNumber]; entityLight->lightBox = lightBox; entityLight->light = light; entityLightsNumber++; if(entityLightsNumber == MAX_ENTITY_LIGHTS) break; } // animate armature if(mesh->getArmature() && mesh->getArmatureAnim()) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // animate textures if(mesh->getTexturesAnim()) animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame()); // animate materials if(mesh->getMaterialsAnim()) animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame()); unsigned int s; unsigned int sSize = mesh->getSubMeshsNumber(); for(s=0; s<sSize; s++) { MSubMesh * subMesh = &mesh->getSubMeshs()[s]; MBox3d * box = subMesh->getBoundingBox(); // check if submesh visible if(sSize > 1) { MVector3 * min = box->getMin(); MVector3 * max = box->getMax(); MVector3 points[8] = { entity->getTransformedVector(MVector3(min->x, min->y, min->z)), entity->getTransformedVector(MVector3(min->x, max->y, min->z)), entity->getTransformedVector(MVector3(max->x, max->y, min->z)), entity->getTransformedVector(MVector3(max->x, min->y, min->z)), entity->getTransformedVector(MVector3(min->x, min->y, max->z)), entity->getTransformedVector(MVector3(min->x, max->y, max->z)), entity->getTransformedVector(MVector3(max->x, max->y, max->z)), entity->getTransformedVector(MVector3(max->x, min->y, max->z)) }; if(! frustum->isVolumePointsVisible(points, 8)) continue; } // subMesh center MVector3 center = (*box->getMin()) + ((*box->getMax()) - (*box->getMin()))*0.5f; center = entity->getTransformedVector(center); // sort entity lights unsigned int lightsNumber = 0; for(l=0; l<entityLightsNumber; l++) { MEntityLight * entityLight = &entityLights[l]; if(! box->isInCollisionWith(&entityLight->lightBox)) continue; MOLight * light = entityLight->light; float z = (center - light->getTransformedPosition()).getLength(); entityLightsList[lightsNumber] = l; entityLightsZList[l] = (1.0f/z)*light->getRadius(); lightsNumber++; } if(lightsNumber > 1) sortFloatList(entityLightsList, entityLightsZList, 0, (int)lightsNumber-1); // local lights if(lightsNumber > 4) lightsNumber = 4; for(l=0; l<lightsNumber; l++) { MEntityLight * entityLight = &entityLights[entityLightsList[l]]; MOLight * light = entityLight->light; // attenuation float quadraticAttenuation = (8.0f / light->getRadius()); quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity(); // color MVector3 color = light->getFinalColor(); // set light render->enableLight(l); render->setLightPosition(l, light->getTransformedPosition()); render->setLightDiffuse(l, MVector4(color)); render->setLightSpecular(l, MVector4(color)); render->setLightAmbient(l, MVector3(0, 0, 0)); render->setLightAttenuation(l, 1, 0, quadraticAttenuation); // spot render->setLightSpotAngle(l, light->getSpotAngle()); if(light->getSpotAngle() < 90){ render->setLightSpotDirection(l, light->getRotatedVector(MVector3(0, 0, -1)).getNormalized()); render->setLightSpotExponent(l, light->getSpotExponent()); } else { render->setLightSpotExponent(l, 0.0f); } } for(l=lightsNumber; l<4; l++){ render->disableLight(l); } render->pushMatrix(); render->multMatrix(entity->getMatrix()); // draw opaques drawOpaques(subMesh, mesh->getArmature()); if(subMesh->hasTransparency()) { if(transpSubObsNumber < MAX_TRANSP_SUBOBJ) { // transparent subMesh pass MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber]; // lights subMeshPass->lightsNumber = lightsNumber; for(l=0; l<lightsNumber; l++) subMeshPass->lights[l] = entityLights[entityLightsList[l]].light; // z distance to camera float z = getDistanceToCam(camera, center); // set values transpList[transpSubObsNumber] = transpSubObsNumber; transpZList[transpSubObsNumber] = z; subMeshPass->subMeshId = s; subMeshPass->object = entity; transpSubObsNumber++; } } render->popMatrix(); } mesh->updateBoundingBox(); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } } // texts unsigned int tSize = scene->getTextsNumber(); for(i=0; i<tSize; i++) { MOText * text = scene->getTextByIndex(i); if(text->isActive() && text->isVisible()) { // transparent pass MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber]; // center MBox3d * box = text->getBoundingBox(); MVector3 center = (*box->getMin()) + ((*box->getMax()) - (*box->getMin()))*0.5f; center = text->getTransformedVector(center); // z distance to camera float z = getDistanceToCam(camera, center); // set values transpList[transpSubObsNumber] = transpSubObsNumber; transpZList[transpSubObsNumber] = z; subMeshPass->object = text; transpSubObsNumber++; } } // sort transparent list if(transpSubObsNumber > 1) sortFloatList(transpList, transpZList, 0, (int)transpSubObsNumber-1); // draw transparents for(i=0; i<transpSubObsNumber; i++) { MSubMeshPass * subMeshPass = &transpSubObjs[transpList[i]]; MObject3d * object = subMeshPass->object; // objects switch(object->getType()) { case M_OBJECT3D_ENTITY: { MOEntity * entity = (MOEntity *)object; unsigned int subMeshId = subMeshPass->subMeshId; MMesh * mesh = entity->getMesh(); MSubMesh * subMesh = &mesh->getSubMeshs()[subMeshId]; // animate armature if(mesh->getArmature() && mesh->getArmatureAnim()) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // animate textures if(mesh->getTexturesAnim()) animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame()); // animate materials if(mesh->getMaterialsAnim()) animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame()); // lights for(l=0; l<subMeshPass->lightsNumber; l++) { MOLight * light = subMeshPass->lights[l]; // attenuation float quadraticAttenuation = (8.0f / light->getRadius()); quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity(); // color MVector3 color = light->getFinalColor(); // set light render->enableLight(l); render->setLightPosition(l, light->getTransformedPosition()); render->setLightDiffuse(l, MVector4(color)); render->setLightSpecular(l, MVector4(color)); render->setLightAmbient(l, MVector3(0, 0, 0)); render->setLightAttenuation(l, 1, 0, quadraticAttenuation); // spot render->setLightSpotAngle(l, light->getSpotAngle()); if(light->getSpotAngle() < 90){ render->setLightSpotDirection(l, light->getRotatedVector(MVector3(0, 0, -1)).getNormalized()); render->setLightSpotExponent(l, light->getSpotExponent()); } else { render->setLightSpotExponent(l, 0.0f); } } for(l=subMeshPass->lightsNumber; l<4; l++){ render->disableLight(l); } render->pushMatrix(); render->multMatrix(entity->getMatrix()); drawTransparents(subMesh, mesh->getArmature()); render->popMatrix(); mesh->updateBoundingBox(); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } break; case M_OBJECT3D_TEXT: { MOText * text = (MOText *)object; render->pushMatrix(); render->multMatrix(text->getMatrix()); drawText(text); render->popMatrix(); } break; } } render->disableLighting(); render->disableFog(); }
void MFixedRenderer::drawText(MOText * textObj) { M_PROFILE_SCOPE(MFixedRenderer::drawText); MFont * font = textObj->getFont(); const char * text = textObj->getText(); vector <float> * linesOffset = textObj->getLinesOffset(); if(! (strlen(text) > 0 && font)) return; if(linesOffset->size() == 0) return; MRenderingContext * render = MEngine().getInstance()->getRenderingContext(); render->enableBlending(); render->enableTexture(); render->disableLighting(); render->setColor4(*textObj->getColor()); render->setBlendingMode(M_BLENDING_ALPHA); static MVector2 vertices[4]; static MVector2 texCoords[4]; render->disableNormalArray(); render->disableColorArray(); render->enableVertexArray(); render->enableTexCoordArray(); render->setVertexPointer(M_FLOAT, 2, vertices); render->setTexCoordPointer(M_FLOAT, 2, texCoords); render->bindTexture(font->getTextureId()); unsigned int lineId = 0; float lineOffset = (*linesOffset)[0]; float size = textObj->getSize(); float tabSize = size*2; float fontSize = (float)font->getFontSize(); float widthFactor = font->getTextureWith() / fontSize; float heightFactor = font->getTextureHeight() / fontSize; float xc = 0, yc = 0; unsigned int i; unsigned int textLen = strlen(text); for(i=0; i<textLen; i++) { if(text[i] == '\n') // return { if(((i+1) < textLen)) { lineId++; lineOffset = (*linesOffset)[lineId]; yc += size; xc = 0; } continue; } if(text[i] == '\t') // tab { int tab = (int)(xc / tabSize) + 1; xc = tab*tabSize; continue; } // get character unsigned int charCode = (unsigned int)((unsigned char)text[i]); MCharacter * character = font->getCharacter(charCode); if(! character) continue; MVector2 pos = character->getPos(); MVector2 scale = character->getScale(); MVector2 offset = character->getOffset() * size + MVector2(lineOffset, 0); float width = scale.x * widthFactor * size; float height = scale.y * heightFactor * size; // construct quad texCoords[0] = MVector2(pos.x, (pos.y + scale.y)); vertices[0] = MVector2(xc, (yc + height)) + offset; texCoords[1] = MVector2((pos.x + scale.x), (pos.y + scale.y)); vertices[1] = MVector2((xc + width), (yc + height)) + offset; texCoords[3] = MVector2((pos.x + scale.x), pos.y); vertices[3] = MVector2((xc + width), yc) + offset; texCoords[2] = MVector2(pos.x, pos.y); vertices[2] = MVector2(xc, yc) + offset; // draw quad render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4); //move to next character xc += character->getXAdvance() * size; } }