예제 #1
0
파일: App.cpp 프로젝트: luaman/g3d-cvs
void App::onGraphics(RenderDevice* rd, Array<Surface::Ref>& posed3D, Array<Surface2D::Ref>& posed2D) {

    Lighting::Ref localLighting = lighting;
    rd->setProjectionAndCameraMatrix(defaultCamera);

    rd->setColorClearValue(colorClear);
    rd->clear(true, true, true);

    rd->enableLighting();
        rd->setAmbientLightColor(localLighting->ambientTop);
        if (localLighting->ambientBottom != localLighting->ambientTop) {
            rd->setLight(iMin(7, localLighting->lightArray.size()) + 1, GLight::directional(-Vector3::unitY(), 
                localLighting->ambientBottom - localLighting->ambientTop, false)); 
        }
            
        // Lights
        for (int L = 0; L < iMin(7, localLighting->lightArray.size()); ++L) {
            rd->setLight(L, localLighting->lightArray[L]);
        }

        // Render the file that is currently being viewed
        if (viewer != NULL) {
            viewer->onGraphics(rd, this, localLighting);
        }
        
        for (int i = 0; i < posed3D.size(); ++i) {
            posed3D[i]->render(rd);
        }
	rd->disableLighting();

    Surface2D::sortAndRender(rd, posed2D);
}
예제 #2
0
/************************************************************
Step

This is where knowledge of physical systems comes in handy.
For every vertex the surface tension is computed as the
cumulative sum of the difference between the vertex height and its
neighbors.  This data is fed into the change in velocity.  The
other values added are for damped oscillation (one is a proportional
control and the other is differential) and so the three physical
quantities accounted for are elasticity, viscosity, and surface tension.

Height is just incremented by time*velocity.
************************************************************/
void WaterField::Step(float time)
{
	int i, j, k, l, mi, ni, mj, nj;
	float cumulativeTension = 0;
	int calRadius = 1;

  for(i=0; i<myXdivs; i++)
		for(j=0; j<myYdivs; j++)
		{
			cumulativeTension = 0;
      myPoints[i][j].avecolor = 0;
      ni = i-calRadius > 0 ? i-calRadius : 0;//
      ni = iMax(0,i-calRadius);
      mi = iMin(myXdivs-1, i+calRadius);
      nj = iMax(0,j-calRadius);
      mj = iMin(myYdivs-1, j+calRadius);
      /*int numCount = ((mi-ni+1)*(mj-nj+1));
      //numCount = 1.0f;
      int rcum = (numCount/2) << 16, gcum = (numCount/2) << 8, bcum = numCount/2;*/
			for(k=ni; k<=mi; k++)
        for(l=nj; l<=mj; l++)
				{
					cumulativeTension += myPoints[k][l].height- myPoints[i][j].height;
          /*rcum += myPoints[k][l].color & 0xFF0000;
          gcum += myPoints[k][l].color & 0x00FF00;
          bcum += myPoints[k][l].color & 0x0000FF;*/
        //  myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[k][l].color, numCount);//1.0f/numCount++);
				}
      /*myPoints[i][j].avecolor = (rcum/numCount) && 0xFF0000 + (gcum/numCount) && 0xFF00 + (bcum/numCount) && 0xFF;
      //myPoints[i][j].avecolor = *((DWORD*)&(LerpColor2(*((Color*)&(myPoints[i][j].avecolor)), black, 0.75f)));//1.0f/numCount++);
      //myPoints[i][j].avecolor = LerpColor(myPoints[i][j].avecolor, black, 0.75f);//1.0f/numCount++);
      for(k=ni; k<=mi; k++)
      {
				cumulativeTension += myPoints[k][j].height- myPoints[i][j].height;
        myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[k][j].color, numCount +0.5f);//1.0f/numCount++);
        //AddColor2(*((Color*)&(myPoints[i][j].avecolor)), *((Color*)&(myPoints[k][j].color)), numCount);//1.0f/numCount++);
			}
      for(l=nj; l<=mj; l++)
			{
				cumulativeTension += myPoints[i][l].height- myPoints[i][j].height;
        myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[i][l].color, numCount+0.5f);//1.0f/numCount++);
        //AddColor2(*((Color*)&(myPoints[i][j].avecolor)), *((Color*)&(myPoints[i][l].color)), numCount);//1.0f/numCount++);
			}*/

			myPoints[i][j].velocity +=m_elasticity*(myHeight-myPoints[i][j].height)
				- m_viscosity * myPoints[i][j].velocity
				+ m_tension*cumulativeTension;
		}

    for(i=0; i<myXdivs; i++)
    for(j=0; j<myYdivs; j++)
    {
      myPoints[i][j].height += myPoints[i][j].velocity*time;
      //myPoints[i][j].color = LerpColor3(myPoints[i][j].color, myPoints[i][j].color, m_blendability);
      SetNormalForPoint(i,j);
    }

}
예제 #3
0
wxGWindow::wxGWindow(
    const GWindowSettings&  _settings,
    wxWindow*               parent,
    wxWindowID              id)  : invisible(wxCURSOR_BLANK), arrow(wxCURSOR_ARROW) {

    // For now a crude check to initialize once per process.
    if (sdlKeyMap.size() == 0) {
        initWXKeys();
    }

    Array<int> attribList;
    makeAttribList(_settings, attribList);
    settings = _settings;

    wxPoint pos(_settings.x, _settings.y);
    wxSize size(_settings.width, _settings.height);

    clientX = _settings.x;
    clientY = _settings.y;
    relativeX = 0;
    relativeY = 0;

    window = new wxG3DCanvas( this,
        parent, id, pos, size, 0, 
        "WxWindow", attribList.getCArray(), 
        wxNullPalette);

    glGetIntegerv(GL_DEPTH_BITS, &settings.depthBits);
    glGetIntegerv(GL_STENCIL_BITS, &settings.stencilBits);

    int redBits, greenBits, blueBits;
    glGetIntegerv(GL_RED_BITS,   &redBits);
    glGetIntegerv(GL_GREEN_BITS, &greenBits);
    glGetIntegerv(GL_BLUE_BITS,  &blueBits);

    settings.rgbBits = iMin(redBits, iMin(greenBits, blueBits));
    glGetIntegerv(GL_ALPHA_BITS, &settings.alphaBits);

    if (window->IsTopLevel()) {
        window->SetClientSize(_settings.width, _settings.height);
    }

    if (settings.center) {
        window->Center();
    }

    if (! settings.visible) {
        window->Hide();
    }

    window->GetPosition(&settings.x, &settings.y);
    window->GetClientSize(&settings.width, &settings.height);
}
예제 #4
0
int EffectBullet::timeToHit(Bullet * bul)
{
	int ta, tb;
	ta = (int)(((minx + (bul->dx>0?scalex:0))- bul->x)/(bul->dx*bul->speed));
	tb = (int)(((miny + (bul->dy>0?scaley:0))- bul->y)/(bul->dy*bul->speed));
	return iMin(ta,tb);
	//return 100;
}
예제 #5
0
void CameraControlWindow::updateTrackFiles() {
    trackFileArray.fastClear();
    trackFileArray.append(noSpline);
    getFiles("*.trk", trackFileArray);
    for (int i = 1; i < trackFileArray.size(); ++i) {
        trackFileArray[i] = trackFileArray[i].substr(0, trackFileArray[i].length() - 4);
    }
    trackFileIndex = iMin(trackFileArray.size() - 1, trackFileIndex);
}
예제 #6
0
파일: abs_ssp.cpp 프로젝트: bhugueney/Punk
std::vector<Int> ABS(std::vector<Int> U, Int t, nInt log) {
    std::vector<Int> S(U);
    std::sort(U.begin(), U.end());
    t = iMin(t, Sigma(U) - t);
    if (!t) return U;
    if (std::binary_search(U.begin(), U.end(), t)) return std::vector<Int>({t});
    for (nInt k = 0; k < U.size(); k++) {
        if (U.at(k) > t) {
            U.erase(U.begin() + k, U.end());
        }
    }
    if (U.size() == 1) return U;
    Int L = iMin(iPow(U.size(), 4), iPow(2, U.size() - 1));
    Int i, j, s, d, n, e = 0;
    Int k = 0;
    Int l = iPow(2, U.size() - 1);
    while (k < L) {
        i = k;
        j = l;
        e = (i + j) / 2;
        while (i < j) {
            cycles++;
            n = (i + j) / 2;
            S = Phi(U, n + e);
            s = Sigma(S);
            d = s - t;
            if (log) {
                std::cout << "(<" << Sigma(S) << ", " << Sigma(U) - Sigma(S) << ">, [ ";
                for (auto u : S) std::cout << u << " ";
                std::cout << "])" << std::endl;
            }
            if (d == 0) return S;
            if (d < 0) i = n + 1;
            if (d > 0) j = n;
            e++;
        }
        k++;
        l++;
    }

    return std::vector<Int>();
}
예제 #7
0
void GuiDropDownList::render(RenderDevice* rd, const GuiSkinRef& skin) const {
    if (m_visible) {

        if (m_useStringList) {
            // If there are no elements in the list, display the empty string
            const std::string& str = (m_stringListValue->size() > 0) ? 
                    (*m_stringListValue)[iMax(0, iMin(m_stringListValue->size() - 1, *m_indexValue))] : 
                    "";

            skin->renderDropDownList(m_rect, m_enabled, focused() || mouseOver(), m_selecting, str, m_caption);
        } else {
            // If there are no elements in the list, display the empty string
            const GuiCaption& str = (m_captionListValue->size() > 0) ? 
                    (*m_captionListValue)[iMax(0, iMin(m_captionListValue->size() - 1, *m_indexValue))] : 
                    "";

            skin->renderDropDownList(m_rect, m_enabled, focused() || mouseOver(), m_selecting, str, m_caption);
        }
    }
}
예제 #8
0
// Best face normal aligned with N
vec2 OBB::GetSupportNormal(vec2 N) const {
	uint32_t iMin(0);
	float dMin(-FLT_MAX);

	for (uint32_t i = 0; i<4; i++) {
		float d = glm::dot(N, GetNormal(i));
		if (d > dMin) {
			dMin = d;
			iMin = i;
		}
	}

	return GetNormal(iMin);
}
예제 #9
0
파일: abs_mcp.cpp 프로젝트: bhugueney/Punk
std::vector<Int> ABS(std::vector<Int> U, Int t, nInt log) {
    Int z = iPow(t, U.size() / 2);
    std::vector<Int> S(U);
    std::sort(U.begin(), U.end());
    Int L = iMin(iPow(U.size(), 4), iPow(2, U.size() - 1));
    Int i, j, s, d, n, e = 0;
    Int k = 0;
    Int l = iPow(2, U.size() - 1);
    while (k < L) {
        i = k;
        j = l;
        e = (i + j) / 2;
        while (i < j) {
            cycles++;
            n = (i + j) / 2;
            S = Phi(U, n + e);
            s = iPow(Sigma(S), S.size());
            d = s - z;
            if (log) {
                std::vector<Int> C;
                std::set_difference(U.begin(), U.end(), S.begin(), S.end(), std::back_inserter(C));
                std::cout << "(<" << Sigma(S) << ", " << Sigma(U) - Sigma(S) << ">, [ ";
                for (auto u : S) std::cout << u << " ";
                std::cout << "]  [";
                for (auto u : C) std::cout << u << " ";
                std::cout << "])" << std::endl;
            }
            if (d == 0) return S;
            if (d < 0) i = n + 1;
            if (d > 0) j = n;
            e++;
        }
        k++;
        l++;
    }

    return std::vector<Int>();
}
예제 #10
0
Color4uint8::Color4uint8(const class Color4& c) {
    r = iMin(255, iFloor(c.r * 256));
    g = iMin(255, iFloor(c.g * 256));
    b = iMin(255, iFloor(c.b * 256));
    a = iMin(255, iFloor(c.a * 256));
}
예제 #11
0
Color1uint8::Color1uint8(const class Color1& c) : value(iMin(255, iRound(c.value * 256))) {
}
예제 #12
0
void UIGeom::render(RenderDevice* rd, float lineScale) {
    if (! visible) {
        return;
    }

    if (m_twoSidedPolys) {
        rd->setCullFace(RenderDevice::CULL_NONE);
        rd->enableTwoSidedLighting();
    }

    for (int i = 0; i < poly3D.size(); ++i) {
        const ConvexPolygon& poly = poly3D[i];
        rd->beginPrimitive(RenderDevice::TRIANGLE_FAN);
            rd->setNormal(poly.normal());
            for (int v = 0; v < poly.numVertices(); ++v) {
                rd->sendVertex(poly.vertex(v));
            }
        rd->endPrimitive();
    }

    // Per segment normals
    Array<Vector3> normal;
    const Vector3 eye = computeEye(rd);
    for (int i = 0; i < line3D.size(); ++i) {
        const PolyLine& line = line3D[i];

        // Compute one normal for each segement
        normal.resize(line.numSegments(), false);
        for (int s = 0; s < line.numSegments(); ++s) {
            normal[s] = segmentNormal(line.segment(s), eye);
        }

        bool closed = line.closed();

        // Compute line width
        {
            Vector4 v = rd->project(line.vertex(0));
            float L = 2;
            if (v.w > 0) {
                L = min(15.0f * v.w, 10.0f);
            } else {
                 L = 10.0f;
            }
            rd->setLineWidth(L * lineScale);
        }

        bool colorWrite = rd->colorWrite();
        bool depthWrite = rd->depthWrite();

        // Draw lines twice.  The first time we draw color information
        // but do not set the depth buffer.  The second time we write
        // to the depth buffer; this prevents line strips from
        // corrupting their own antialiasing with depth conflicts at
        // the line joint points.
        if (colorWrite) {
            rd->setDepthWrite(false);
            rd->beginPrimitive(RenderDevice::LINE_STRIP);
                for (int v = 0; v < line.numVertices(); ++v) {
                    // Compute the smooth normal.  If we have a non-closed
                    // polyline, the ends are special cases.
                    Vector3 N;
                    if (! closed && (v == 0)) {
                        N = normal[0];
                    } else if (! closed && (v == line.numVertices())) {
                        N = normal.last();
                    } else {
                        // Average two adjacent normals
                        N = normal[v % normal.size()] + normal[(v - 1) % 
                                                               normal.size()];
                    }

                    if (N.squaredLength() < 0.05) {
                        // Too small to normalize; revert to the
                        // nearest segment normal
                        rd->setNormal(normal[iMin(v, normal.size() - 1)]);
                    } else {
                        rd->setNormal(N.direction());
                    }

                    rd->sendVertex(line.vertex(v));
                }                
            rd->endPrimitive();
        }

        if (depthWrite) {
            rd->setColorWrite(false);
            rd->setDepthWrite(true);
            rd->beginPrimitive(RenderDevice::LINE_STRIP);
                for (int v = 0; v < line.numVertices(); ++v) {
                    rd->sendVertex(line.vertex(v));
                }
            rd->endPrimitive();
        }

        rd->setColorWrite(colorWrite);
        rd->setDepthWrite(depthWrite);
    }
}    
void MeshAlg::weldBoundaryEdges(
    Array<Face>&       faceArray,
    Array<Edge>&       edgeArray,
    Array<Vertex>&     vertexArray) {

    // Copy over the original edge array
    Array<Edge> oldEdgeArray = edgeArray;

    // newEdgeIndex[e] is the new index of the old edge with index e
    // Note that newEdgeIndex[e] might be negative, indicating that
    // the edge switched direction between the arrays.
    Array<int> newEdgeIndex;
    newEdgeIndex.resize(edgeArray.size());
    edgeArray.resize(0);

    // boundaryEdgeIndices[v_low] is an array of the indices of 
    // all boundary edges whose lower vertex is v_low.
    Table<int, Array<int> > boundaryEdgeIndices;

    // Copy over non-boundary edges to the new array
    for (int e = 0; e < oldEdgeArray.size(); ++e) {
        if (oldEdgeArray[e].boundary()) {

            // Add to the boundary table
            const int v_low = iMin(oldEdgeArray[e].vertexIndex[0], oldEdgeArray[e].vertexIndex[1]);
            if (! boundaryEdgeIndices.containsKey(v_low)) {
                boundaryEdgeIndices.set(v_low, Array<int>());
            }
            boundaryEdgeIndices[v_low].append(e);

            // We'll fill out newEdgeIndex[e] later, when we find pairs

        } else {

            // Copy the edge to the new array
            newEdgeIndex[e] = edgeArray.size();
            edgeArray.append(oldEdgeArray[e]);

        }
    }


    // Remove all edges from the table that have pairs.
    Table<int, Array<int> >::Iterator cur = boundaryEdgeIndices.begin();
    Table<int, Array<int> >::Iterator end = boundaryEdgeIndices.end();
    while (cur != end) {
        Array<int>&     boundaryEdge = cur->value;

        for (int i = 0; i < boundaryEdge.size(); ++i) {
            int ei = boundaryEdge[i];
            const Edge& edgei = oldEdgeArray[ei];

            for (int j = i + 1; j < boundaryEdge.size(); ++j) {
                int ej = boundaryEdge[j];
                const Edge& edgej = oldEdgeArray[ej];

                // See if edge ei is the reverse (match) of edge ej.

                // True if the edges match
                bool match = false;

                // True if edgej's vertex indices are reversed from
                // edgei's (usually true).
                bool reversej = false;
                
                int u = edgei.vertexIndex[0];
                int v = edgei.vertexIndex[1];

                if (edgei.faceIndex[0] != Face::NONE) {
                    //        verts|faces
                    // edgei = [u v A /]

                    if (edgej.faceIndex[0] != Face::NONE) {
                        if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
                            // This is the most common of the four cases

                            // edgej = [v u B /]
                            match = true;
                            reversej = true;
                        }
                    } else {
                        if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
                            // edgej = [u v / B]
                            match = true;
                        }
                    }
                } else {
                    // edgei = [u v / A]
                    if (edgej.faceIndex[0] != Face::NONE) {
                        if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
                            // edgej = [u v B /]
                            match = true;
                        }
                    } else {
                        if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
                            // edgej = [v u / B]
                            match = true;
                            reversej = true;
                        }
                    }
                }

                if (match) {
                    // ei and ej can be paired as a single edge
                    int e = edgeArray.size();
                    Edge& edge = edgeArray.next();

                    // Follow the direction of edgei.
                    edge = edgei;
                    newEdgeIndex[ei] = e;

                    // Insert the face index for edgej.
                    int fj = edgej.faceIndex[0];
                    if (fj == Face::NONE) {
                        fj = edgej.faceIndex[1];
                    }
                    
                    if (edge.faceIndex[0] == Face::NONE) {
                        edge.faceIndex[0] = fj;
                    } else {
                        edge.faceIndex[1] = fj;
                    }
                    
                    if (reversej) {
                        // The new edge is backwards of the old edge for ej
                        newEdgeIndex[ej] = ~e;
                    } else {
                        newEdgeIndex[ej] = e;
                    }

                    // Remove both ei and ej from being candidates for future pairing.
                    // Remove ej first since it comes later in the list (removing
                    // ei would decrease the index of ej to j - 1).
                    boundaryEdge.fastRemove(j);
                    boundaryEdge.fastRemove(i);

                    // Re-process element i, which is now a new edge index
                    --i;

                    // Jump out of the j for-loop
                    break;
                }
            }
        }
        ++cur;
    }

    // Anything remaining in the table is a real boundary edge; just copy it to
    // the end of the array.
    cur = boundaryEdgeIndices.begin();
    end = boundaryEdgeIndices.end();
    while (cur != end) {
        Array<int>&     boundaryEdge = cur->value;

        for (int b = 0; b < boundaryEdge.size(); ++b) {
            const int e = boundaryEdge[b];

            newEdgeIndex[e] = edgeArray.size();
            edgeArray.append(oldEdgeArray[e]);
        }

        ++cur;
    }

    // Finally, fix up edge indices in the face and vertex arrays
    for (int f = 0; f < faceArray.size(); ++f) {
        Face& face = faceArray[f];
        for (int i = 0; i < 3; ++i) {
            int e = face.edgeIndex[i];

            if (e < 0) {
                face.edgeIndex[i] = ~newEdgeIndex[~e];
            } else {
                face.edgeIndex[i] = newEdgeIndex[e];
            }
        }
    }

    for (int v = 0; v < vertexArray.size(); ++v) {
        Vertex& vertex = vertexArray[v];
        for (int i = 0; i < vertex.edgeIndex.size(); ++i) {
            int e = vertex.edgeIndex[i];

            if (e < 0) {
                vertex.edgeIndex[i] = ~newEdgeIndex[~e];
            } else {
                vertex.edgeIndex[i] = newEdgeIndex[e];
            }
        }
    }
}
예제 #14
0
int BufferTexture::size() const {
    return iMin(m_buffer->pixelCount(), GLCaps::maxTextureBufferSize());
}
예제 #15
0
SDLWindow::SDLWindow(const GWindow::Settings& settings) {

#if defined(G3D_OSX)
	NSApplicationWrapper wrapper;

	// Hack to get our window/process to the front...
	ProcessSerialNumber psn = { 0, kCurrentProcess};    
	TransformProcessType (&psn, kProcessTransformToForegroundApplication);
	SetFrontProcess (&psn);

	_pool = new NSAutoreleasePoolWrapper();
#endif

	if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO | 
                 SDL_INIT_JOYSTICK) < 0 ) {

        fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
		debugPrintf("Unable to initialize SDL: %s\n", SDL_GetError());
        Log::common()->printf("Unable to initialize SDL: %s\n", SDL_GetError());
		exit(1);
	}

    // Set default icon if available
    if (settings.defaultIconFilename != "nodefault") {

        try {

            GImage defaultIcon;
            defaultIcon.load(settings.defaultIconFilename);

            setIcon(defaultIcon);
        } catch (const GImage::Error& e) {
            // Throw away default icon
            fprintf(stderr, "GWindow's default icon failed to load: %s (%s)", e.filename.c_str(), e.reason.c_str());
		    debugPrintf("GWindow's default icon failed to load: %s (%s)", e.filename.c_str(), e.reason.c_str());
            Log::common()->printf("GWindow's default icon failed to load: %s (%s)", e.filename.c_str(), e.reason.c_str());            
        }
    }

    if (! settings.fullScreen) {
        // This doesn't really work very well due to SDL bugs so we fix up 
        // the position after the window is created.
        if (settings.center) {
            System::setEnv("SDL_VIDEO_CENTERED", "");
        } else {
            System::setEnv("SDL_VIDEO_WINDOW_POS", format("%d,%d", settings.x, settings.y));
        }
    }

    _mouseVisible = true;
    _inputCapture = false;

	// Request various OpenGL parameters
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,      settings.depthBits);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,    1);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,    settings.stencilBits);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE,        settings.rgbBits);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,      settings.rgbBits);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,       settings.rgbBits);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,      settings.alphaBits);
	SDL_GL_SetAttribute(SDL_GL_STEREO,          settings.stereo);

    #if SDL_FSAA
        if (settings.fsaaSamples > 1) {
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 
                                settings.fsaaSamples);
        }
    #endif

	// Create a width x height OpenGL screen 
    int flags = 
        SDL_HWSURFACE |
        SDL_OPENGL |
        (settings.fullScreen ? SDL_FULLSCREEN : 0) |
        (settings.resizable ? SDL_RESIZABLE : 0) |
        (settings.framed ? 0 : SDL_NOFRAME);

	if (SDL_SetVideoMode(settings.width, settings.height, 0, flags) == NULL) {
        debugAssert(false);
        Log::common()->printf("Unable to create OpenGL screen: %s\n", 
                              SDL_GetError());
		error("Critical Error", 
              format("Unable to create OpenGL screen: %s\n", 
                     SDL_GetError()).c_str(), true);
		SDL_Quit();
		exit(2);
	}

    // See what video mode we really got
    _settings = settings;
    int depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits;
    glGetIntegerv(GL_DEPTH_BITS, &depthBits);
    glGetIntegerv(GL_STENCIL_BITS, &stencilBits);

    glGetIntegerv(GL_RED_BITS,   &redBits);
    glGetIntegerv(GL_GREEN_BITS, &greenBits);
    glGetIntegerv(GL_BLUE_BITS,  &blueBits);
    glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
    int actualFSAABuffers = 0, actualFSAASamples = 0;

    #if SDL_FSAA
        SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &actualFSAABuffers);
        SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &actualFSAASamples);
    #else
        (void)actualFSAABuffers;
        (void)actualFSAASamples;
    #endif
    _settings.rgbBits     = iMin(iMin(redBits, greenBits), blueBits);
    _settings.alphaBits   = alphaBits;
    _settings.stencilBits = stencilBits;
    _settings.depthBits   = depthBits;
    _settings.fsaaSamples = actualFSAASamples;

    SDL_version ver;
    SDL_VERSION(&ver);
    _version = format("%d,%0d.%0d", ver.major, ver.minor, ver.patch);

    SDL_EnableUNICODE(1);
    setCaption("G3D");

    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);
    SDL_GetWMInfo(&info);

    _glContext = glGetCurrentContext();

    #if defined(G3D_WIN32)
        // Extract SDL HDC/HWND on Win32
        _Win32HWND  = info.window;
        _Win32HDC   = wglGetCurrentDC();
    #elif defined(G3D_LINUX)
        // Extract SDL's internal Display pointer on Linux        
        _X11Display = info.info.x11.display;
        _X11Window  = info.info.x11.window;
        _X11WMWindow  = info.info.x11.wmwindow;

        if (glXGetCurrentDisplay != NULL) {
            G3D::_internal::x11Display = glXGetCurrentDisplay();
        } else {
            G3D::_internal::x11Display = info.info.x11.display;
        }

        if (glXGetCurrentDrawable != NULL) {
            // A Drawable appears to be either a Window or a Pixmap
            G3D::_internal::x11Window  = glXGetCurrentDrawable();
        } else {
            G3D::_internal::x11Window  = info.info.x11.window;
        }
    #endif

    // Adjust window position
    #ifdef G3D_WIN32
        if (! settings.fullScreen) {
            int W = screenWidth();
            int H = screenHeight();
            int x = iClamp(settings.x, 0, W);
            int y = iClamp(settings.y, 0, H);

            if (settings.center) {
                x = (W - settings.width) / 2;
                y = (H - settings.height) / 2;
            }

            SetWindowPos(_Win32HWND, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
        }
    #endif

	#ifdef G3D_LINUX
		 if (! settings.fullScreen) {
            int W = screenWidth(_X11Display);
            int H = screenHeight(_X11Display);
            int x = iClamp(settings.x, 0, W);
            int y = iClamp(settings.y, 0, H);

            if (settings.center) {
                x = (W  - settings.width) / 2;
                y = (H - settings.height) / 2;
            }
			XMoveWindow(_X11Display, _X11WMWindow, x, y);
        }
	#endif


	// Check for joysticks
    int j = SDL_NumJoysticks();
    if ((j < 0) || (j > 10)) {
        // If there is no joystick adapter on Win32,
        // SDL returns ridiculous numbers.
        j = 0;
    }

	if (j > 0) {
        SDL_JoystickEventState(SDL_ENABLE);
        // Turn on the joysticks

        joy.resize(j);
        for (int i = 0; i < j; ++i) {
            joy[i] = SDL_JoystickOpen(i);
            debugAssert(joy[i]);
        }
	}

    GLCaps::init();

	// Register this window as the current window
	makeCurrent();

#	if defined(G3D_LINUX)
		// If G3D is using the default assertion hooks, replace them with our own that use
		// SDL functions to release the mouse, since we've been unable to implement
		// a non-SDL way of releasing the mouse using the X11 handle directly.
		if (assertionHook() == _internal::_handleDebugAssert_) {
			setFailureHook(SDL_handleDebugAssert_);
		}

		if (failureHook() == _internal::_handleErrorCheck_) {
			setFailureHook(SDL_handleErrorCheck_);
		}
#	endif
}
예제 #16
0
void
TrackDClient::pollForInput(Array<EventRef> &events) 
{
  // Update trackers
  for (int i=0;i<iMin(_numSensors, _tEventNames.size());i++) {
    float tracker[6];
    trackdGetPosition(_trackerMemory, i, &(tracker[0]));
    trackdGetEulerAngles(_trackerMemory, i, &(tracker[3]));
  
    Vector3 trans(tracker[0], tracker[1], tracker[2]);
    Matrix3 rotY = Matrix3::fromAxisAngle(Vector3(0,1,0), toRadians(tracker[4]));
    Matrix3 rotX = Matrix3::fromAxisAngle(Vector3(1,0,0), toRadians(tracker[3]));
    Matrix3 rotZ = Matrix3::fromAxisAngle(Vector3(0,0,1), toRadians(tracker[5]));
    
    CoordinateFrame trackerToDevice = CoordinateFrame(trans) * 
		CoordinateFrame(rotY) *
		CoordinateFrame(rotX) * 
		CoordinateFrame(rotZ);
    trackerToDevice.translation *= _trackerUnitsToRoomUnitsScale;

    /** This is probably more direct, but can't test it right now..
    float mat[4][4];
    trackdGetMatrix(_trackerMemory, i, mat);
    CoordinateFrame trackerToDevice = CoordinateFrame(Matrix3(mat[0][0], mat[1][1], mat[2][2],
                                                              mat[0][1], mat[1][1], mat[2][1],
                                                              mat[0][2], mat[1][2], mat[2][2]),
                                                      Vector3(mat[0][3], mat[1][3], mat[2][3]));
    **/
    
    CoordinateFrame eventRoom = _finalOffset[i] * _deviceToRoom * 
      trackerToDevice * _propToTracker[i];

    events.append(new Event(getTrackerName(i), eventRoom));  
  }

  // Update buttons
  for (int i=0;i<iMin(_numButtons, _bEventNames.size());i++) {
    int b = trackdGetButton(_wandMemory, i);
    if (b != _buttonStates[i]) {
      _buttonStates[i] = b;
      std::string name = getButtonName(i);
      if (b) {
        name = name + "_down";
      }
      else {
        name = name + "_up";
      }
      events.append(new Event(name));
    }
  }

  /**
  // Update valuators
  for (int i=0;i<_numValuators;i++) {
    float v = trackdGetValuator(_wandMemory, i);
    if (v != _valuatorStates[i]) {
      _valuatorStates[i] = v;
      events.append(new Event(getValuatorName(i), v));
    }
  }
  **/
}