int main(int argc, char** argv) #endif { tCreationFlags creationFlags; creationFlags.sWindowTitle = "Displacement-mapped sphere"; int32 width = 640; int32 height = 480; #ifdef __amigaos4__ if ( argc == 3 ) { width = iClamp( atoi( argv[1] ), 160, 1600 ); height = iClamp( atoi( argv[2] ), 160, 1280 ); } #endif #ifdef WIN32 creationFlags.hIcon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE( IDI_ICON1 ) ); #endif creationFlags.iWindowWidth = width; creationFlags.iWindowHeight = height; creationFlags.bWindowed = true; CDisplacedSphere theApp; if( !theApp.bInitialize( creationFlags ) ) return 1; return theApp.iRun(); }
// Get's the color at a certain value ofColor ImgTexture::getColor(int inX, int inY) { iClamp(1, mResizedImage.width-1, inX); iClamp(1, mResizedImage.height-1, inY); return mResizedImage.getColor(inX, inY);; }
int main(int argc, char** argv) #endif { tCreationFlags creationFlags; creationFlags.sWindowTitle = "Raytracer"; int32 iWidth = 320; int32 iHeight = 240; #ifdef __amigaos4__ if ( argc == 3 ) { iWidth = iClamp( atoi( argv[1] ), 160, 1600 ); iHeight = iClamp( atoi( argv[2] ), 160, 1280 ); } #endif #ifdef WIN32 creationFlags.hIcon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE( IDI_ICON1 ) ); #endif creationFlags.iWindowWidth = iWidth; creationFlags.iWindowHeight = iHeight; creationFlags.bWindowed = true; CApp theApp; if( !theApp.bInitialize( creationFlags ) ) return 1; return theApp.iRun(); }
/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */ static uint8 applyFilter( const uint8* I, int x, int y, int w, int h, const float filter[5][5]) { debugAssert(isEven(w)); debugAssert(isEven(h)); float sum = 0.0f; float denom = 0.0f; for (int dy = 0; dy < 5; ++dy) { int offset = ((y + dy + h - 2) % h) * w; for (int dx = 0; dx < 5; ++dx) { float f = filter[dy][dx]; sum += f * I[((x + dx + w - 2) % w) + offset]; denom += f; } } return (uint8)iClamp(iRound(sum / denom), 0, 255); }
/** @param brighten Most Quake II textures are dark; this argument is a factor to make them brighter by. Default = 1.0, normal intensity. It is safe to call load multiple times-- the previously loaded model will be freed correctly. */ TextureRef loadBrightTexture(const std::string& filename, double brighten) { alwaysAssertM(fileExists(filename), std::string("Can't find \"") + filename + "\""); TextureRef texture; if (brighten == 1.0) { texture = Texture::fromFile(filename, TextureFormat::RGBA8, Texture::CLAMP); } else { // Brighten the image GImage im(filename); if (im.channels == 3) { for (int i = im.width * im.height - 1; i >= 0; --i) { Color3uint8& color = im.pixel3()[i]; for (int c = 0; c < 3; ++c) { color[c] = iClamp(color[c] * brighten, 0, 255); } } const uint8* array[1]; array[0] = im.byte(); texture = Texture::fromMemory(filename, array, TextureFormat::RGB8, im.width, im.height, 1, TextureFormat::RGB8, Texture::CLAMP); } else { for (int i = im.width * im.height - 1; i >= 0; --i) { Color4uint8& color = im.pixel4()[i]; for (int c = 0; c < 3; ++c) { color[c] = iClamp(color[c] * brighten, 0, 255); } } const uint8* array[1]; array[0] = im.byte(); texture = Texture::fromMemory(filename, array, TextureFormat::RGBA8, im.width, im.height, 1, TextureFormat::RGBA8, Texture::CLAMP); } } return texture; }
void TextOutput::setIndentLevel(int i) { indentLevel = i; // If there were more pops than pushes, don't let that take us below 0 indent. // Don't ever indent more than the number of columns. indentSpaces = iClamp(option.spacesPerIndent * indentLevel, 0, option.numColumns - 1); }
void Texture::Preprocess::modulateImage(ImageFormat::Code fmt, void* _byte, int n) const { debugAssertM( (fmt == ImageFormat::CODE_RGB8) || (fmt == ImageFormat::CODE_RGBA8) || (fmt == ImageFormat::CODE_R8) || (fmt == ImageFormat::CODE_L8), "Texture preprocessing only implemented for 1, 3, 4 8-bit channels."); uint8* byte = static_cast<uint8*>(_byte); // Make a lookup table uint8 adjust[4][256]; for (int c = 0; c < 4; ++c) { for (int i = 0; i < 256; ++i) { float s = float(pow((i * modulate[c]) / 255, gammaAdjust) * 255); adjust[c][i] = iClamp(iRound(s), 0, 255); } } switch (fmt) { case ImageFormat::CODE_RGBA8: for (int i = 0; i < n; ++i) { for (int c = 0; c < 3; ++c, ++i) { byte[i] = adjust[c][byte[i]]; } } if (convertToPremultipliedAlpha) { for (int i = 0; i < n; i += 4) { int a = byte[i + 3]; for (int c = 0; c < 3; ++c) { byte[i + c] = (int(byte[i + c]) * a) / 255; } } } break; case ImageFormat::CODE_RGB8: for (int i = 0; i < n; ) { for (int c = 0; c < 3; ++c, ++i) { byte[i] = adjust[c][byte[i]]; } } break; case ImageFormat::CODE_R8: case ImageFormat::CODE_L8: for (int i = 0; i < n; ++i) { byte[i] = adjust[0][byte[i]]; } break; default:; } }
void SDLWindow::setDimensions(const Rect2D& dims) { #ifdef G3D_WIN32 int W = screenWidth(); int H = screenHeight(); int x = iClamp((int)dims.x0(), 0, W); int y = iClamp((int)dims.y0(), 0, H); int w = iClamp((int)dims.width(), 1, W); int h = iClamp((int)dims.height(), 1, H); SetWindowPos(_Win32HWND, NULL, x, y, w, h, SWP_NOZORDER); // Do not update settings-- wait for an event to notify us #endif #ifdef G3D_LINUX //TODO: Linux #endif // TODO: OS X }
void PhysicsFrameSplineEditor::setSpline(const PhysicsFrameSpline& s) { m_spline = s; // Ensure that there is at least one node if (m_spline.control.size() == 0) { m_spline.control.append(PFrame()); } m_selectedControlPointIndex = iClamp(m_selectedControlPointIndex, 0, m_spline.control.size() - 1); m_nodeManipulator->setFrame(m_spline.control[m_selectedControlPointIndex]); }
void ToneMap::makeGammaCorrectionTextures() { if (RG.notNull() || (profile == NO_TONE)) { return; } // The inverse gamma ramp function G3D::uint8 ramp[256]; for (int i = 0; i < 256; ++i) { // Linear //ramp[i] = i; // Inverse power const double A = 1.9; // Brighten the screen image by 1.0 / 0.75 = 1.34, since we darkened the // scene when rendering to avoid saturation. ramp[i] = iClamp(iRound((1.0 - pow(1.0 - i/255.0, A)) * 255.0 / 0.75), 0, 255); // Log // const double A = 10, B = 1; // ramp[i] = iRound(((log(A*i/255.0 + B) - log(B)) / // (log(A+B) - log(B))) * 255.0); } GImage data(256, 256, 3); for (int g = 0; g < 256; ++g) { for (int r = 0; r < 256; ++r) { Color3uint8& p = data.pixel3(r, g); p.r = ramp[r]; p.g = ramp[g]; p.b = 0; } } // MIP-mapping causes bad interpolation for some reason RG = Texture::fromGImage("RG Gamma", data, TextureFormat::RGB8, Texture::DIM_2D, Texture::Settings::video()); if (profile != PS20) { // On PS20 we can re-use the original RG texture data.resize(256, 1, 3); for (int b = 0; b < 256; ++b) { Color3uint8& p = data.pixel3(b, 0); p.r = 0; p.g = 0; p.b = ramp[b]; } B = Texture::fromGImage("B Gamma", data, TextureFormat::RGB8, Texture::DIM_2D, Texture::Settings::video()); } }
void SDLWindow::setPosition(int x, int y) { #ifdef G3D_WIN32 int W = screenWidth(); int H = screenHeight(); x = iClamp(x, 0, W); y = iClamp(y, 0, H); SetWindowPos(_Win32HWND, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); // Do not update settings-- wait for an event to notify us #endif #ifdef G3D_LINUX const int W = screenWidth(_X11Display); const int H = screenHeight(_X11Display); x = iClamp(x, 0, W); y = iClamp(y, 0, H); XMoveWindow(_X11Display, _X11WMWindow, x, y); #endif // TODO: OS X }
bool cTileRasterizer::setup(const cVertex &v0,const cVertex &v1,const cVertex &v2) { bool setup_ok=cRasterizer::setup(v0,v1,v2); // add cTileRasterizer-specific setup code here mZMin = mZMax = (uint32)iClamp( int(0xffffff*mVertices[0].mAttributes[ATTRIBUTE_POSITION].z), 0, 0xffffff ); for (int i = 1; i < 3; i++) { // convert float z to 24 bit fixed z uint32 z = (uint32)iClamp( int(0xffffff*mVertices[i].mAttributes[ATTRIBUTE_POSITION].z), 0, 0xffffff ); mZMin = MIN2(mZMin,z); mZMax = MAX2(mZMax,z); } // compute tile coordinates mTileCoordsMin.x=(mBBox2DMin.x/mTileWidth); // floor mTileCoordsMin.y=(mBBox2DMin.y/mTileHeight); // floor mTileCoordsMax.x=((mBBox2DMax.x+mTileWidth-1)/mTileWidth); // ceil mTileCoordsMax.y=((mBBox2DMax.y+mTileHeight-1)/mTileHeight); // ceil return setup_ok; }
void BinaryOutput::compress(int level) { if (m_alreadyWritten > 0) { throw "Cannot compress huge files (part of this file has already been written to disk)."; } debugAssertM(! m_committed, "Cannot compress after committing."); alwaysAssertM(m_bufferLen < 0xFFFFFFFF, "Compress only works for 32-bit files."); // This is the worst-case size, as mandated by zlib unsigned long compressedSize = iCeil(m_bufferLen * 1.001) + 12; // Save the old buffer and reallocate to the worst-case size const uint8* src = m_buffer; const uint32 srcSize = (uint32)m_bufferLen; // add space for the 4-byte header m_maxBufferLen = compressedSize + 4; m_buffer = (uint8*)System::malloc(m_maxBufferLen); // Write the header containing the old buffer size, which is needed for decompression { const uint8* convert = (const uint8*)&srcSize; if (m_swapBytes) { m_buffer[0] = convert[3]; m_buffer[1] = convert[2]; m_buffer[2] = convert[1]; m_buffer[3] = convert[0]; } else { m_buffer[0] = convert[0]; m_buffer[1] = convert[1]; m_buffer[2] = convert[2]; m_buffer[3] = convert[3]; } } // Compress and write after the header int result = compress2(m_buffer + 4, &compressedSize, src, srcSize, iClamp(level, 0, 9)); debugAssert(result == Z_OK); (void)result; m_bufferLen = compressedSize + 4; m_pos = m_bufferLen; // Free the old data System::free((void*)src); }
result CMuli3DPresentTargetLinuxX11::Present( const float32 *i_pSource, uint32 i_iFloats ) { m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters(); // Copy pixels to the ximage-buffer --------------------------------------- fpuTruncate(); if( m_iPixelBytes == 2 ) { // 16-bit uint16 *pDestination = (uint16 *)m_pXImage->data; uint32 iPixels = DeviceParameters.iBackbufferWidth * DeviceParameters.iBackbufferHeight; while( iPixels-- ) { const int32 iR = iClamp( ftol( i_pSource[0] * m_i16bitMaxVal[0] ), 0, m_i16bitMaxVal[0] ); const int32 iG = iClamp( ftol( i_pSource[1] * m_i16bitMaxVal[1] ), 0, m_i16bitMaxVal[1] ); const int32 iB = iClamp( ftol( i_pSource[2] * m_i16bitMaxVal[2] ), 0, m_i16bitMaxVal[2] ); i_pSource += i_iFloats; *pDestination++ = ( iR << m_i16bitShift[0] ) | ( iG << m_i16bitShift[1] ) | ( iB << m_i16bitShift[2] ); } } else { // 24- or 32-bit uint8 *pDestination = (uint8 *)m_pXImage->data; uint32 iPixels = DeviceParameters.iBackbufferWidth * DeviceParameters.iBackbufferHeight; while( iPixels-- ) { pDestination[0] = iClamp( ftol( i_pSource[2] * 255.0f ), 0, 255 ); // b pDestination[1] = iClamp( ftol( i_pSource[1] * 255.0f ), 0, 255 ); // g pDestination[2] = iClamp( ftol( i_pSource[0] * 255.0f ), 0, 255 ); // r i_pSource += i_iFloats; pDestination += m_iPixelBytes; } } fpuReset(); // Present to window/screen XPutImage( m_pDisplay, DeviceParameters.hDeviceWindow, m_WindowGC, m_pXImage, 0, 0, 0, 0, DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight ); return s_ok; }
void MD2Model::Part::load(const std::string& filename, float resize) { resize *= 0.55f; // If models are being reloaded it is dangerous to trust the interpolation cache. interpolatedModel = NULL; alwaysAssertM(FileSystem::exists(filename), std::string("Can't find \"") + filename + "\""); setNormalTable(); // Clear out reset(); BinaryInput b(filename, G3D_LITTLE_ENDIAN); MD2ModelHeader header; header.deserialize(b); debugAssert(header.version == 8); debugAssert(header.numVertices <= 4096); keyFrame.resize(header.numFrames); Array<Vector3> frameMin; frameMin.resize(header.numFrames); Array<Vector3> frameMax; frameMax.resize(header.numFrames); Array<double> frameRad; frameRad.resize(header.numFrames); texCoordScale.x = 1.0f / header.skinWidth; texCoordScale.y = 1.0f / header.skinHeight; Vector3 min = Vector3::inf(); Vector3 max = -Vector3::inf(); double rad = 0; if (header.numVertices < 3) { Log::common()->printf("\n*****************\nWarning: \"%s\" is corrupted and is not being loaded.\n", filename.c_str()); return; } loadTextureFilenames(b, header.numSkins, header.offsetSkins); for (int f = 0; f < keyFrame.size(); ++f) { MD2Frame md2Frame; b.setPosition(header.offsetFrames + f * header.frameSize); md2Frame.deserialize(b); // Read the vertices for the frame keyFrame[f].vertexArray.resize(header.numVertices); keyFrame[f].normalArray.resize(header.numVertices); // Per-pose bounds Vector3 min_1 = Vector3::inf(); Vector3 max_1 = -Vector3::inf(); double rad_1 = 0; // Quake's axes are permuted and scaled double scale[3] = {-.07, .07, -.07}; int permute[3] = {2, 0, 1}; int v, i; for (v = 0; v < header.numVertices; ++v) { Vector3& vertex = keyFrame[f].vertexArray[v]; for (i = 0; i < 3; ++i) { vertex[permute[i]] = (b.readUInt8() * md2Frame.scale[i] + md2Frame.translate[i]) * float(scale[permute[i]]); } vertex *= resize; uint8 normalIndex = b.readUInt8(); debugAssertM(normalIndex < 162, "Illegal canonical normal index in file"); keyFrame[f].normalArray[v] = iClamp(normalIndex, 0, 161); min_1 = min_1.min(vertex); max_1 = max_1.max(vertex); if (vertex.squaredMagnitude() > rad_1) { rad_1 = vertex.squaredMagnitude(); } } frameMin[f] = min_1; frameMax[f] = max_1; frameRad[f] = sqrt(rad_1); min = min.min(min_1); max = max.max(max_1); if (rad_1 > rad) { rad = rad_1; } } // Compute per-animation bounds based on frame bounds for (int a = 0; a < JUMP; ++a) { const int first = animationTable[a].first; const int last = animationTable[a].last; if ((first < header.numFrames) && (last < header.numFrames)) { Vector3 min = frameMin[first]; Vector3 max = frameMax[first]; double rad = frameRad[first]; for (int i = first + 1; i <= last; ++i) { min = min.min(frameMin[i]); max = max.max(frameMax[i]); rad = G3D::max(rad, frameRad[i]); } animationBoundingBox[a] = AABox(min, max); // Sometimes the sphere bounding the box is tighter than the one we calculated. const float boxRadSq = (max-min).squaredMagnitude() * 0.25f; if (boxRadSq >= square(rad)) { animationBoundingSphere[a] = Sphere(Vector3::zero(), (float)rad); } else { animationBoundingSphere[a] = Sphere((max + min) * 0.5f, sqrt(boxRadSq)); } } else { // This animation is not supported by this model animationBoundingBox[a] = AABox(Vector3::zero(), Vector3::zero()); animationBoundingSphere[a] = Sphere(Vector3::zero(), 0); } } animationBoundingBox[JUMP] = animationBoundingBox[JUMP_DOWN]; animationBoundingSphere[JUMP] = animationBoundingSphere[JUMP_DOWN]; boundingBox = AABox(min, max); boundingSphere = Sphere(Vector3::zero(), (float)sqrt(rad)); // Load the texture coords Array<Vector2int16> fileTexCoords; fileTexCoords.resize(header.numTexCoords); b.setPosition(header.offsetTexCoords); for (int t = 0; t < fileTexCoords.size(); ++t) { fileTexCoords[t].x = b.readUInt16(); fileTexCoords[t].y = b.readUInt16(); } // The indices for the texture coords (which don't match the // vertex indices originally). indexArray.resize(header.numTriangles * 3); Array<Vector2int16> index_texCoordArray; index_texCoordArray.resize(indexArray.size()); // Read the triangles, reversing them to get triangle list order b.setPosition(header.offsetTriangles); for (int t = header.numTriangles - 1; t >= 0; --t) { for (int i = 2; i >= 0; --i) { indexArray[t * 3 + i] = b.readUInt16(); } for (int i = 2; i >= 0; --i) { index_texCoordArray[t * 3 + i] = fileTexCoords[b.readUInt16()]; } } computeTexCoords(index_texCoordArray); // Read the primitives { primitiveArray.clear(); b.setPosition(header.offsetGlCommands); int n = b.readInt32(); while (n != 0) { Primitive& primitive = primitiveArray.next(); if (n > 0) { primitive.type = PrimitiveType::TRIANGLE_STRIP; } else { primitive.type = PrimitiveType::TRIANGLE_FAN; n = -n; } primitive.pvertexArray.resize(n); Array<Primitive::PVertex>& pvertex = primitive.pvertexArray; for (int i = 0; i < pvertex.size(); ++i) { pvertex[i].texCoord.x = b.readFloat32(); pvertex[i].texCoord.y = b.readFloat32(); pvertex[i].index = b.readInt32(); } n = b.readInt32(); } } MeshAlg::computeAdjacency(keyFrame[0].vertexArray, indexArray, faceArray, edgeArray, vertexArray); weldedFaceArray = faceArray; weldedEdgeArray = edgeArray; weldedVertexArray = vertexArray; MeshAlg::weldAdjacency(keyFrame[0].vertexArray, weldedFaceArray, weldedEdgeArray, weldedVertexArray); numBoundaryEdges = MeshAlg::countBoundaryEdges(edgeArray); numWeldedBoundaryEdges = MeshAlg::countBoundaryEdges(weldedEdgeArray); shared_ptr<VertexBuffer> indexBuffer = VertexBuffer::create(indexArray.size() * sizeof(int), VertexBuffer::WRITE_ONCE); indexVAR = IndexStream(indexArray, indexBuffer); }
void GuiDropDownList::setList(const Array<GuiText>& c) { m_listValue = c; *m_indexValue = iClamp(*m_indexValue, 0, m_listValue.size() - 1); m_menu.reset(); }
Vector2int16 Vector2int16::clamp(const Vector2int16& lo, const Vector2int16& hi) { return Vector2int16(iClamp(x, lo.x, hi.x), iClamp(y, lo.y, hi.y)); }
Vector4int8::Vector4int8(const Vector3& source, int8 w) : w(w) { x = iClamp(iRound(source.x), -128, 127); y = iClamp(iRound(source.y), -128, 127); z = iClamp(iRound(source.z), -128, 127); }
Color1uint8::Color1uint8(const class Color1& c) : value(iClamp(iFloor(c.value * 256), 0, 255)) { }
/** Converts a bug count into a quality rating*/ const char* quality(int bugCount) { static const char* q[] = {"A+", "A-", "B+", "B-", "C+", "C-", "D+", "D-", "F"}; return q[iClamp(bugCount, 0, 8)]; }
void App::onGraphics (RenderDevice *rd, Array< SurfaceRef > &posed3D, Array< Surface2DRef > &posed2D) { rd->setColorClearValue(Color3::white()); rd->clear(); doFunStuff(); rd->push2D(); int w = rd->width(); int h = rd->height(); /////////////////////////////////////// // Left panel # define LABEL(str) p.y += titleFont->draw2D(rd, str, p - Vector2((float)w * 0.0075f, 0), s * 2, Color3::white() * 0.4f).y # define PRINT(str) p.y += reportFont->draw2D(rd, str, p, s, Color3::black()).y int x0 = int(w * 0.015f); // Cursor position Vector2 p(x0, h * 0.02f); // Font size float s = w * 0.013; LABEL("Shaders"); PRINT(std::string("Combiners: ") + combineShader); PRINT(std::string("Assembly: ") + asmShader); PRINT(std::string("GLSL: ") + glslShader); p.y += s * 2; LABEL("Extensions"); PRINT(std::string("FSAA: ") + ((GLCaps::supports("WGL_ARB_multisample") || GLCaps::supports("GL_ARB_multisample")) ? "Yes" : "No")); PRINT(std::string("Two-sided Stencil: ") + ((GLCaps::supports_two_sided_stencil() ? "Yes" : "No"))); PRINT(std::string("Stencil Wrap: ") + (GLCaps::supports("GL_EXT_stencil_wrap") ? "Yes" : "No")); PRINT(std::string("Texture Compression: ") + (GLCaps::supports("GL_EXT_texture_compression_s3tc") ? "Yes" : "No")); PRINT(std::string("Shadow Maps: ") + (GLCaps::supports("GL_ARB_shadow") ? "Yes" : "No")); PRINT(std::string("Frame Buffer Object: ") + (GLCaps::supports("GL_EXT_framebuffer_object") ? "Yes" : "No")); PRINT(std::string("Vertex Arrays: ") + (GLCaps::supports_GL_ARB_vertex_buffer_object() ? "Yes" : "No")); /////////////////////////////////////// // Right Panel x0 = int(w * 0.6f); // Cursor position p = Vector2(x0, h * 0.02f); // Graphics Card LABEL("Graphics Card"); rd->setTexture(0, cardLogo); Draw::rect2D(Rect2D::xywh(p.x - s * 6, p.y, s * 5, s * 5), rd); rd->setTexture(0, NULL); PRINT(GLCaps::vendor().c_str()); PRINT(GLCaps::renderer().c_str()); PRINT(format("Driver Version %s", GLCaps::driverVersion().c_str())); # ifdef G3D_WIN32 PRINT(format("%d MB Video RAM", DXCaps::videoMemorySize() / (1024 * 1024))); { uint32 ver = DXCaps::version(); PRINT(format("DirectX %d.%d", ver/100, ver%100)); } # endif p.y += s * 2; // Processor LABEL("Processor"); rd->setTexture(0, chipLogo); Draw::rect2D(Rect2D::xywh(p.x - s * 6, p.y, s * 5, s * 5), rd); rd->setTexture(0, NULL); PRINT(System::cpuVendor().c_str()); PRINT(System::cpuArchitecture().c_str()); Array<std::string> features; if (System::has3DNow()) { features.append("3DNow"); } if (System::hasMMX()) { features.append("MMX"); } if (System::hasSSE()) { features.append("SSE"); } if (System::hasSSE2()) { features.append("SSE2"); } if (chipSpeed != "") { PRINT(chipSpeed + " " + stringJoin(features, '/')); } else { PRINT(stringJoin(features, '/')); } p.y += s * 2; // Operating System LABEL("OS"); rd->setTexture(0, osLogo); Draw::rect2D(Rect2D::xywh(p.x - s * 6, p.y - s * 2, s * 5, s * 5), rd); rd->setTexture(0, NULL); if (beginsWith(System::operatingSystem(), "Windows 5.0")) { PRINT("Windows 2000"); } else if (beginsWith(System::operatingSystem(), "Windows 5.1")) { PRINT("Windows XP"); } PRINT(System::operatingSystem().c_str()); p.y += s * 3; x0 = int(w - s * 10); titleFont->draw2D(rd, "Features", p - Vector2(w * 0.0075f, 0), s * 2, Color3::white() * 0.4f); p.y += reportFont->draw2D(rd, format("f%d", featureRating), Vector2(x0, p.y), s*2, Color3::red() * 0.5).y; drawBar(rd, featureRating, p); // Designed to put NV40 at 50 performanceRating = log(rd->stats().frameRate) * 15.0f; p.y += s * 4; performanceButton = Rect2D::xywh(p, titleFont->draw2D(rd, "Speed", p - Vector2(w * 0.0075f, 0), s * 2, Color3::white() * 0.4f)); { float spd = iRound(performanceRating * 10) / 10.0f; p.y += reportFont->draw2D(rd, format("%5.1f", spd), Vector2(x0 - s*2, p.y), s*2, Color3::red() * 0.5).y; } drawBar(rd, (int)min(performanceRating, 100.0f), p); p.y += s * 4; titleFont->draw2D(rd, "Quality", p - Vector2(w * 0.0075f, 0), s * 2, Color3::white() * 0.4f); p.y += reportFont->draw2D(rd, quality(bugCount), Vector2(x0, p.y), s*2, Color3::red() * 0.5f).y; drawBar(rd, iClamp(100 - bugCount * 10, 0, 100), p); # undef PRINT p.y = h - 50; # define PRINT(str) p.y += reportFont->draw2D(rd, str, p, 8, Color3::black()).y; PRINT("These ratings are based on the performance of G3D apps."); PRINT("They may not be representative of overall 3D performance."); PRINT("Speed is based on both processor and graphics card. Upgrading"); PRINT("your graphics driver may improve Quality and Features."); # undef PRINT # undef LABEL switch (popup) { case NONE: break; case PERFORMANCE: { // Draw the popup box Rect2D box = drawPopup("Performance Details"); p.x = box.x0() + 10; p.y = box.y0() + 30; Vector2 spacing(box.width() / 6.5, 0); std::string str; float factor = 3 * vertexPerformance.numTris / 1e6; # define PRINT(cap, val) \ reportFont->draw2D(rd, cap, p, s, Color3::black());\ reportFont->draw2D(rd, (vertexPerformance.val[0] > 0) ? \ format("%5.1f", vertexPerformance.val[0]) : \ std::string("X"), p + spacing * 3, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT);\ reportFont->draw2D(rd, (vertexPerformance.val[0] > 0) ? \ format("%5.1f", factor * vertexPerformance.val[0]) : \ std::string("X"), p + spacing * 4, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT);\ reportFont->draw2D(rd, (vertexPerformance.val[1] > 0) ? \ format("%5.1f", vertexPerformance.val[1]) : \ std::string("X"), p + spacing * 5, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT);\ p.y += reportFont->draw2D(rd, (vertexPerformance.val[1] > 0) ? \ format("%5.1f", factor * vertexPerformance.val[1]) : \ std::string("X"), p + spacing * 6, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT).y; reportFont->draw2D(rd, "Incoherent", p + spacing * 3.5, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT); p.y += reportFont->draw2D(rd, "Coherent", p + spacing * 5.5, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT).y; reportFont->draw2D(rd, "FPS*", p + spacing * 3, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT); reportFont->draw2D(rd, "MVerts/s", p + spacing * 4, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT); reportFont->draw2D(rd, "FPS*", p + spacing * 5, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT).y; p.y += reportFont->draw2D(rd, "MVerts/s", p + spacing * 6, s, Color3::black(), Color4::clear(), GFont::XALIGN_RIGHT).y; PRINT("glBegin/glEnd", beginEndFPS); PRINT("glDrawElements", drawElementsRAMFPS); PRINT(" + VBO", drawElementsVBOFPS); PRINT(" + uint16", drawElementsVBO16FPS); PRINT(" + gl interleave", drawElementsVBOIFPS); PRINT(" + manual interleave", drawElementsVBOIMFPS); PRINT(" (without shading)", drawElementsVBOPeakFPS); reportFont->draw2D(rd, "glDrawArrays", p, s, Color3::black()); reportFont->draw2D(rd, (vertexPerformance.drawArraysVBOPeakFPS > 0) ? \ format("%5.1f", vertexPerformance.drawArraysVBOPeakFPS) : \ std::string("X"), p + spacing * 5, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT);\ p.y += reportFont->draw2D(rd, (vertexPerformance.drawArraysVBOPeakFPS > 0) ? \ format("%5.1f", factor * vertexPerformance.drawArraysVBOPeakFPS) : \ std::string("X"), p + spacing * 6, s, Color3::red() * 0.5, Color4::clear(), GFont::XALIGN_RIGHT).y; # undef PRINT p.y += s; p.y += reportFont->draw2D(rd, format("* FPS at %d k polys/frame.", iRound(vertexPerformance.numTris / 1000.0)), p + Vector2(20, 0), s, Color3::black()).y; } } rd->pop2D(); }
result CMuli3DPresentTargetAmigaOS4::Present( const float32 *i_pSource, uint32 i_iFloats ) { m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters(); // Copy pixels to the image-buffer --------------------------------------- // Doesn't currently do anything... fpuTruncate(); // Picasso96 RenderInfo for locking the bitmap struct RenderInfo ri; // Lock bitmap for drawing ULONG lock = IP96->p96LockBitMap( m_pBitMap, (UBYTE*)&ri, sizeof(struct RenderInfo) ); if ( lock ) { // Pointer to allocated buffer uint8 *pDestination = (uint8 *)ri.Memory; // Help pointer to a row in bitmap uint8 *_pDestination; for ( uint32 y = 0; y < DeviceParameters.iBackbufferHeight; y++ ) { // Next row _pDestination = pDestination + y * ri.BytesPerRow; for ( uint32 x = 0; x < DeviceParameters.iBackbufferWidth; x++ ) { //*_pDestination++ = iClamp( (int32)( *i_pSource++ * 255.0f ), 0, 255 ); // r //*_pDestination++ = iClamp( (int32)( *i_pSource++ * 255.0f ), 0, 255 ); // g //*_pDestination++ = iClamp( (int32)( *i_pSource++ * 255.0f ), 0, 255 ); // b // Set r, g and b bytes in our buffer _pDestination[0] = iClamp( ftol( i_pSource[0] * 255.0f ), 0, 255 ); // r _pDestination[1] = iClamp( ftol( i_pSource[1] * 255.0f ), 0, 255 ); // g _pDestination[2] = iClamp( ftol( i_pSource[2] * 255.0f ), 0, 255 ); // b //*_pDestination++ = (iClamp( ftol( i_pSource[0] * 255.0f ), 0, 255 ) << 16) | // (iClamp( ftol( i_pSource[1] * 255.0f ), 0, 255 ) << 8) | // iClamp( ftol( i_pSource[2] * 255.0f ), 0, 255 ); i_pSource += i_iFloats; _pDestination += 3; } } IP96->p96UnlockBitMap( m_pBitMap, lock ); // Blit bitmap to window IGraphics->BltBitMapRastPort( m_pBitMap, 0, 0, DeviceParameters.hDeviceWindow->RPort, DeviceParameters.hDeviceWindow->BorderLeft, DeviceParameters.hDeviceWindow->BorderTop, DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight, 0xC0); IGraphics->WaitTOF(); } // lock // Doesn't currently do anything... fpuReset(); return s_ok; }
result CMuli3DPresentTargetWin32::Present( const float32 *i_pSource, uint32 i_iFloats ) { m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters(); // Check for lost DirectDraw surfaces ------------------------------------- if( m_bDDSurfaceLost ) { m_pDirectDrawSurfaces[0]->Restore(); if( DeviceParameters.bWindowed ) m_pDirectDrawSurfaces[1]->Restore(); m_bDDSurfaceLost = false; } // Lock backbuffer-surface------------------------------------------------- DDSURFACEDESC2 descSurface; descSurface.dwSize = sizeof( DDSURFACEDESC2 ); if( FAILED( m_pDirectDrawSurfaces[1]->Lock( 0, &descSurface, DDLOCK_WAIT|DDLOCK_NOSYSLOCK|DDLOCK_WRITEONLY, 0 ) ) ) { FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: couldn't lock secondary surface.\n" ); return e_unknown; } const uint32 iDestBytes = descSurface.ddpfPixelFormat.dwRGBBitCount / 8; // Copy pixels to the backbuffer-surface ---------------------------------- const uint32 iDestRowJump = descSurface.lPitch - iDestBytes * DeviceParameters.iBackbufferWidth; uint8 *pDestination = (uint8 *)descSurface.lpSurface; fpuTruncate(); if( iDestBytes == 2 ) { // 16-bit uint32 iHeight = DeviceParameters.iBackbufferHeight; while( iHeight-- ) { uint32 iWidth = DeviceParameters.iBackbufferWidth; while( iWidth-- ) { const int32 iR = iClamp( ftol( i_pSource[0] * m_i16bitMaxVal[0] ), 0, m_i16bitMaxVal[0] ); const int32 iG = iClamp( ftol( i_pSource[1] * m_i16bitMaxVal[1] ), 0, m_i16bitMaxVal[1] ); const int32 iB = iClamp( ftol( i_pSource[2] * m_i16bitMaxVal[2] ), 0, m_i16bitMaxVal[2] ); i_pSource += i_iFloats; *((uint16 *)pDestination) = ( iR << m_i16bitShift[0] ) | ( iG << m_i16bitShift[1] ) | ( iB << m_i16bitShift[2] ); pDestination += 2; } pDestination += iDestRowJump; } } else { // 24- or 32-bit uint32 iHeight = DeviceParameters.iBackbufferHeight; while( iHeight-- ) { uint32 iWidth = DeviceParameters.iBackbufferWidth; while( iWidth-- ) { pDestination[0] = iClamp( ftol( i_pSource[2] * 255.0f ), 0, 255 ); // b pDestination[1] = iClamp( ftol( i_pSource[1] * 255.0f ), 0, 255 ); // g pDestination[2] = iClamp( ftol( i_pSource[0] * 255.0f ), 0, 255 ); // r i_pSource += i_iFloats; pDestination += iDestBytes; } pDestination += iDestRowJump; } } fpuReset(); // Unlock backbuffer-surface and surface m_pDirectDrawSurfaces[1]->Unlock( 0 ); // Present the image to the screen ---------------------------------------- if( DeviceParameters.bWindowed ) { POINT pntTopLeft = { 0, 0 }; ClientToScreen( DeviceParameters.hDeviceWindow, &pntTopLeft ); RECT rctDestination; GetClientRect( DeviceParameters.hDeviceWindow, &rctDestination ); OffsetRect( &rctDestination, pntTopLeft.x, pntTopLeft.y ); RECT rctSource; SetRect( &rctSource, 0, 0, DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight ); // Blt secondary to primary surface if( FAILED( m_pDirectDrawSurfaces[0]->Blt( &rctDestination, m_pDirectDrawSurfaces[1], &rctSource, DDBLT_WAIT, 0 ) ) ) { m_bDDSurfaceLost = true; FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: primary surfaces have been lost!\n" ); return e_unknown; } } else { if( FAILED( m_pDirectDrawSurfaces[0]->Flip( 0, DDFLIP_WAIT ) ) ) { m_bDDSurfaceLost = true; FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: surfaces have been lost!\n" ); return e_unknown; } } return s_ok; }
Vector4int8::Vector4int8(const Vector4& source) { x = iClamp(iRound(source.x), -128, 127); y = iClamp(iRound(source.y), -128, 127); z = iClamp(iRound(source.z), -128, 127); w = iClamp(iRound(source.w), -128, 127); }
void PhysicsFrameSplineEditor::setSelectedControlPointIndex(int i) { m_selectedControlPointIndex = iClamp(i, 0, m_spline.control.size() - 1); // Move the manipulator to the new control point m_nodeManipulator->setFrame(m_spline.control[m_selectedControlPointIndex]); }
void Welder::toGridCoords(Vector3 v, int& x, int& y, int& z) const { v = (v - offset) * scale; x = iClamp(iFloor(v.x * GRID_RES), 0, GRID_RES - 1); y = iClamp(iFloor(v.y * GRID_RES), 0, GRID_RES - 1); z = iClamp(iFloor(v.z * GRID_RES), 0, GRID_RES - 1); }
Vector2int32 Vector2int32::clamp(const Vector2int32& lo, const Vector2int32& hi) { return Vector2int32(iClamp(x, lo.x, hi.x), iClamp(y, lo.y, hi.y)); }
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 }