Exemple #1
0
bool GuiButton::onEvent(const GEvent& event) {
    switch (event.type) {
    case GEventType::MOUSE_BUTTON_DOWN:
        m_down = true;
        // invoke the pre-event handler
        m_callback.execute();
        debugAssertGLOk();
        fireEvent(GEventType::GUI_DOWN);
        debugAssertGLOk();
        return true;
    
    case GEventType::MOUSE_BUTTON_UP:
        fireEvent(GEventType::GUI_UP);

        // Only trigger an action if the mouse was still over the control
        if (m_down && m_rect.contains(Vector2(event.button.x, event.button.y))) {
            fireEvent(GEventType::GUI_ACTION);
        }

        m_down = false;
        return true;
    }

    return false;
}
void Shader::ShaderProgram::link() {
    glProgramObject = glCreateProgram();
    debugAssertGLOk();
    // Attach
    for (int s = 0; s < STAGE_COUNT; ++s) {
        if (glShaderObject[s]) {
            glAttachShader(glProgramObject, glShaderObject[s]);
        }
        debugAssertGLOk();
    }

    // Link
    glLinkProgram(glProgramObject);
    debugAssertGLOk();

    // Read back messages
    GLint linked;
    glGetProgramiv(glProgramObject, GL_LINK_STATUS, &linked);
    debugAssertGLOk();

    GLint maxLength = 0, length = 0;
    glGetProgramiv(glProgramObject, GL_INFO_LOG_LENGTH, &maxLength);
    GLchar* pInfoLog = (GLchar *)malloc((maxLength + 1) * sizeof(GLcharARB));
    glGetProgramInfoLog(glProgramObject, maxLength, &length, pInfoLog);
    debugAssertGLOk();

    messages += String(pInfoLog);
    ok = ok && (linked == GL_TRUE);

    free(pInfoLog);
    pInfoLog = nullptr;
}
Exemple #3
0
RenderbufferRef Renderbuffer::createEmpty(
    const std::string&      _name, 
    const int               _width, 
    const int               _height,
    const G3D::ImageFormat* _format) { 
    // New Renderbuffer ID
    GLuint _imageID;

    // Save old renderbuffer state
    GLint origBuffer;
    glGetIntegerv(GL_RENDERBUFFER_BINDING, &origBuffer);

    // Generate buffer
    glGenRenderbuffers(1, &_imageID);
    debugAssertGLOk();

    // Bind the buffer
    glBindRenderbuffer(GL_RENDERBUFFER, _imageID);
    debugAssertGLOk();

    // Allocate storage for it
    glRenderbufferStorage(GL_RENDERBUFFER, _format->openGLFormat, _width, _height);

    // Check for successful generation (ie, no INVALID_OPERATION)
    debugAssertGLOk();

    // Restore renderbuffer state
    glBindRenderbuffer(GL_RENDERBUFFER, origBuffer);
    debugAssertGLOk();

    // Create new renderbuffer
    return Ref(new Renderbuffer(_name, _imageID, _format, _width, _height));
}
Exemple #4
0
BufferTexture::~BufferTexture() {
    glBindTexture(GL_TEXTURE_BUFFER, m_textureID);
    debugAssertGLOk();
    glTexBuffer(GL_TEXTURE_BUFFER, m_buffer->format()->openGLFormat, 0);
    debugAssertGLOk();
    glBindTexture(GL_TEXTURE_BUFFER, 0);
    debugAssertGLOk();
    glDeleteTextures(1, &m_textureID);
    debugAssertGLOk();
    m_textureID = 0;
}
Exemple #5
0
void Framebuffer::set(AttachmentPoint ap, const TextureRef& texture) {
    if (texture.isNull()) {
        // We're in the wrong overload
        set(ap, (void*)NULL);
        return;
    }

    // Get current framebuffer
    GLint origFB = glGetInteger(GL_FRAMEBUFFER_BINDING_EXT);

    // If we aren't already bound, bind us now
    if (origFB != (GLint)openGLID()) {
        // Bind this framebuffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, openGLID());
        debugAssertGLOk();
    }

    // Check for completeness
    if (numAttachments == 0) {
        // This is the first attachment.
        // Set texture height/width
        m_width  = texture->texelWidth();
        m_height = texture->texelHeight();
    } else {
        // Verify same dimensions
        debugAssertM((texture->texelWidth() != width()) || 
                      (texture->texelHeight() != height()), 
           "All attachments bound to a Framebuffer must "
                     "have identical dimensions!");
    }
    
    if (! attachmentTable.containsKey(ap)) {
        attachmentTable.set(ap, Attachment(texture));
    }

    // Bind texture to framebuffer
    glFramebufferTexture2DEXT(
        GL_FRAMEBUFFER_EXT, 
        ap, 
        texture->openGLTextureTarget(), 
        texture->openGLID(), 0);
    debugAssertGLOk();

    // If we were already bound, don't bother restoring
    if (origFB != (GLint)openGLID()) {
        // Bind original framebuffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, origFB);
    }

    debugAssertGLOk();
}
Exemple #6
0
shared_ptr<BufferTexture> BufferTexture::create(const std::string& name, const shared_ptr<GLPixelTransferBuffer>& buffer) {
    debugAssertM(GLCaps::maxTextureBufferSize() > 0, "Buffer Textures not supported by your driver.");
    alwaysAssertM(isValidBufferTextureImageFormat(buffer->format()), G3D::format("Invalidly formatted buffer passed to BufferTexture::create(), format %s is unsupported.", buffer->format()->name().c_str()) );
    GLuint textureID = Texture::newGLTextureID();

    /** Load the data */
    glBindTexture(GL_TEXTURE_BUFFER, textureID);
    debugAssertGLOk();
    glTexBuffer(GL_TEXTURE_BUFFER, buffer->format()->openGLFormat, buffer->glBufferID());
    debugAssertGLOk();
    glBindTexture(GL_TEXTURE_BUFFER, 0);

    return shared_ptr<BufferTexture>(new BufferTexture(name, buffer, textureID));
}
Exemple #7
0
bool WidgetManager::onEvent(const GEvent& event, WidgetManager::Ref& a, WidgetManager::Ref& b) {
    a->beginLock();
    if (b) {
        b->beginLock();
    }

    int numManagers = isNull(b) ? 1 : 2;

    // Process each
    for (int k = 0; k < numManagers; ++k) {
        Array<Widget::Ref >& array = 
            (k == 0) ?
            a->m_moduleArray :
            b->m_moduleArray;
                
        for (int i = array.size() - 1; i >= 0; --i) {

            if (array[i]->onEvent(event)) {
                debugAssertGLOk();
                if (b) {
                    b->endLock();
                }
                a->endLock();
                return true;
            }
        }
    }
    
    if (b) {
        b->endLock();
    }
    a->endLock();

    return false;
}
Exemple #8
0
Demo::Demo(App* _app) : GApplet(_app), app(_app) {
    // Allocate the two VARAreas used in this demo
    varStatic = VARArea::create(1024 * 640 * 5, VARArea::WRITE_ONCE);
    varStream = VARArea::create(1024 * 1280 * 5, VARArea::WRITE_EVERY_FRAME);
    debugAssertGLOk();    
    debugAssert(varStatic.notNull());
    debugAssert(varStream.notNull());
}
Exemple #9
0
// Called before the application loop begins.  Load data here and
// not in the constructor so that common exceptions will be
// automatically caught.
void App::onInit() {
    GApp::onInit();
	debugAssertGLOk();

    setFrameDuration(1.0f / 120.0f);

    // Call setScene(shared_ptr<Scene>()) or setScene(MyScene::create()) to replace
    // the default scene here.
    
    showRenderingStats      = false;

	SVO::Specification spec;

	spec.encoding[GBuffer::Field::LAMBERTIAN].format = ImageFormat::RGBA16F();
	spec.encoding[GBuffer::Field::WS_NORMAL].format  = ImageFormat::RGBA16F();
	spec.encoding[GBuffer::Field::GLOSSY].format     = ImageFormat::RGBA16F();

	//spec.encoding[GBuffer::Field::WS_FACE_NORMAL].format  = ImageFormat::RG16F();	//Test. 2xFP16 for atomic min

#	if 0 //def G3D_DEBUG
		// Not used, but the program crashes without this
		spec.encoding[GBuffer::Field::WS_POSITION].format = ImageFormat::RGBA16F();
#	endif

	spec.dimension = Texture::DIM_3D;
	
	debugAssertGLOk();


	m_svo = SVO::create(spec, "SVO", true);
	
    makeGUI();
    // For higher-quality screenshots:
    // developerWindow->videoRecordDialog->setScreenShotFormat("PNG");
    // developerWindow->videoRecordDialog->setCaptureGui(false);
    developerWindow->cameraControlWindow->moveTo(Point2(developerWindow->cameraControlWindow->rect().x0(), 0));
    loadScene(
        //"G3D Sponza"
		//"G3D Cornell Box" // Load something simple
		"Test Scene"
        //developerWindow->sceneEditorWindow->selectedSceneName()  // Load the first scene encountered 
        );

    dynamic_pointer_cast<DefaultRenderer>(m_renderer)->setOrderIndependentTransparency(false);
}
Exemple #10
0
void Framebuffer::set(AttachmentPoint ap, const void* n) {
    debugAssert(n == NULL);

    // Get current framebuffer
    GLint origFB = glGetInteger(GL_FRAMEBUFFER_BINDING_EXT);
    debugAssertGLOk();

    // If we aren't already bound, bind us now
    if (origFB != (GLint)openGLID()) {
        // Bind this framebuffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, openGLID());
        debugAssertGLOk();
    }

    if (attachmentTable.containsKey(ap)) { 
        // Detach
        if (attachmentTable[ap].type == Attachment::TEXTURE) {

            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ap, 
                                      GL_TEXTURE_2D, 0, 0);
			debugAssertGLOk();

			if (attachmentTable[ap].hadAutoMipMap) {
				attachmentTable[ap].texture->setAutoMipMap(true);
			}
        } else {
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, ap, 
                                         GL_RENDERBUFFER_EXT, 0);
			debugAssertGLOk();
        }

        --numAttachments;

    } else {
        // Wipe our record for that slot
        attachmentTable.remove(ap);
    }

    // If we were already bound, don't bother restoring
    if (origFB != (GLint)openGLID()) {
        // Bind original framebuffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, origFB);
        debugAssertGLOk();
    }
}
Exemple #11
0
FramebufferRef Framebuffer::create(const std::string& _name) {
    GLuint _framebufferID;
    
    // Generate Framebuffer
    glGenFramebuffersEXT(1, &_framebufferID);
    debugAssertGLOk();

    return new Framebuffer(_name, _framebufferID);
}
Exemple #12
0
void Viewer::onGraphics(RenderDevice* rd) {
    LightingParameters lighting(G3D::toSeconds(11, 00, 00, AM));
    rd->setProjectionAndCameraMatrix(app->debugCamera);

    // Cyan background
    rd->setColorClearValue(Color3(0.1f, 0.5f, 1.0f));

    rd->clear(app->sky.isNull(), true, true);
    if (app->sky.notNull()) {
        app->sky->render(rd, lighting);
    }

    rd->enableLighting();
		rd->setLight(0, GLight::directional(lighting.lightDirection, lighting.lightColor));
		rd->setAmbientLightColor(lighting.ambient);


        CoordinateFrame camera = rd->getCameraToWorldMatrix();
        app->bumpShader->args.set("wsLightPos",      Vector4(lighting.lightDirection, 0));
        app->bumpShader->args.set("wsEyePos",        camera.translation);
        app->bumpShader->args.set("texture",         app->textureMap);
        app->bumpShader->args.set("normalBumpMap",   app->normalBumpMap);
        app->bumpShader->args.set("reflectivity",    0);//0.35);
	    app->bumpShader->args.set("specularity",     0);//0.4);
	    app->bumpShader->args.set("bumpScale",       bumpScale);
        app->bumpShader->args.set("environmentMap",  app->sky->getEnvironmentMap());

        rd->setShader(app->bumpShader);
        debugAssertGLOk();
		for (int e = 0; e < entityArray.size(); ++e) {
			entityArray[e]->render(rd);
            debugAssertGLOk();
		}
        rd->setShader(NULL);

    rd->disableLighting();

    if (app->sky.notNull()) {
        app->sky->renderLensFlare(rd, lighting);
    }
}
void Shader::ShaderProgram::init(const Array<PreprocessedShaderSource>& pss, const String& preambleAndMacroString, const Args& args, const Table<int, String>& indexToNameTable){
    ok = true;
    debugAssertGLOk();
    
    if (! GLCaps::supports_GL_ARB_shader_objects()) {
        messages = "This graphics card does not support GL_ARB_shader_objects.";
        ok = false;
        return;
    }
    
    debugAssertGLOk();
    Array<String> fullCode;
    compile(pss, preambleAndMacroString, args, indexToNameTable, fullCode);
    debugAssertGLOk();
    if (ok) {
       link();
       if ( !ok) {
           debugPrintf("Shader code:\n");
           for (int i = 0; i < STAGE_COUNT; ++i) {
               debugPrintf("Stage %d:\n", i);
               debugPrintf("%s\n\n", fullCode[i].c_str());
           }
       }
    }

    debugAssertGLOk();
    if (ok) {
        addActiveUniformsFromProgram();
        debugAssertGLOk();
        addUniformsFromSource(pss, args);
        debugAssertGLOk();
    }

    if (ok) {
        addActiveAttributesFromProgram();
        debugAssertGLOk();
        addVertexAttributesFromSource(pss);
        debugAssertGLOk();
    }
    debugAssertGLOk();

    logPrintf("%s\n", messages.c_str());
}
Exemple #14
0
RenderbufferRef Renderbuffer::fromGLRenderbuffer(
    const std::string&         _name, 
    const GLuint             _imageID,
    const G3D::ImageFormat*  _format) {

    GLint w, h;

    // Extract the width and height
    glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &w);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &h);
    debugAssertGLOk();

    // Create new renderbuffer
    return RenderBufferRef(new Renderbuffer(_name, _imageID, _format, w, h));
}
Exemple #15
0
void SDLWindow::reallyMakeCurrent() const {
#   ifdef G3D_WIN32
        if (wglMakeCurrent(_Win32HDC, _glContext) == FALSE)	{
            debugAssertM(false, "Failed to set context");
	}
#   elif defined(G3D_LINUX)
        if (! glXMakeCurrent(_X11Display, _X11Window, _glContext)) {
            //debugAssertM(false, "Failed to set context");
            // only check OpenGL as False seems to be returned when
            // context is already current
            debugAssertGLOk();
        }
#   elif defined(G3D_OSX)
        
#   endif
}
Exemple #16
0
void VideoOutput::append(RenderDevice* rd, bool backbuffer) {
    debugAssert(rd->width() == m_settings.width);
    debugAssert(rd->height() == m_settings.height);

    RenderDevice::ReadBuffer old = rd->readBuffer();
    if (backbuffer) {
        rd->setReadBuffer(RenderDevice::READ_BACK);
    } else {
        rd->setReadBuffer(RenderDevice::READ_FRONT);
    }
    debugAssertGLOk();


    // TODO: Optimize using GLPixelTransferBuffer and glReadPixels instead of screenshotPic
    shared_ptr<Image> image = rd->screenshotPic(false, false);
    rd->setReadBuffer(old);
    shared_ptr<CPUPixelTransferBuffer> imageBuffer = image->toPixelTransferBuffer();
    encodeFrame(static_cast<const uint8*>(imageBuffer->buffer()), imageBuffer->format(), true);
}
Exemple #17
0
void Profiler::beginGFX(const std::string& name) {
    if (! m_supportsQuery || ! m_enabled) {
        return;
    }
    alwaysAssertM(m_currentGFX == "", "There is already a GFX task named " + m_currentCPU + " pending.");
    alwaysAssertM(! m_gfxTask.contains(name, m_frameNum), "A GFX task named " + name +
        " was already timed this frame.");

    debugAssertGLOk();
    if (m_queryFreelist.size() == 0) {
        // Allocate some more query objects
        const int N = 10;
        m_queryFreelist.resize(N);
        glGenQueries(N, m_queryFreelist.getCArray());
    }

    m_currentGFX = name;
    GLint query = m_queryFreelist.pop();
    m_pendingQueries.append(Pair(name, query));

    glBeginQuery(GL_TIME_ELAPSED_EXT, query);
}
// glInterleavedArrays with 16-bit indices (should be the fastest indexed version)
float measureDrawElementsVBOIPerformance(Model& model, bool use_glInterleavedArrays) {
    
    bool hasVBO = 
        (strstr((char*)glGetString(GL_EXTENSIONS), "GL_ARB_vertex_buffer_object") != NULL) &&
            (glGenBuffersARB != NULL) && 
            (glBufferDataARB != NULL) &&
            (glDeleteBuffersARB != NULL);

    if (! hasVBO) {
        return 0.0;
    }

    // Load the vertex arrays

    // Number of indices
    const int N = (int)model.cpuIndex.size();
    // Number of vertices
    const int V = (int)model.cpuVertex.size();

    GLuint vbo, indexBuffer;
    glGenBuffersARB(1, &vbo);
    glGenBuffersARB(1, &indexBuffer);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

    size_t vertexSize   = V * sizeof(float) * 3;
    size_t normalSize   = V * sizeof(float) * 3;
    size_t colorSize    = V * sizeof(float) * 4;   
    size_t texCoordSize = V * sizeof(float) * 2;
    size_t totalSize    = vertexSize + normalSize + texCoordSize + colorSize;

    // Pointers relative to the start of the vbo in video memory used
    // for manually interleaving
    GLintptrARB texCoordPtr = 0;
    GLintptrARB colorPtr    = texCoordPtr + 2 * sizeof(float);
    GLintptrARB normalPtr   = colorPtr    + 4 * sizeof(float);
    GLintptrARB vertexPtr   = normalPtr   + 3 * sizeof(float);

    GLintptrARB indexPtr    = 0;

    // Upload data
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexBuffer);
    glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, N * sizeof(unsigned short), &model.cpuIndex16[0], GL_STATIC_DRAW_ARB);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
    float* interleave = (float*)malloc(totalSize);
    // Interleave the buffers in memory
    float* ptr = interleave;
    for (int i = 0; i < V; ++i) {
        ptr[0] = model.cpuTexCoord[i].x;
        ++ptr;
        ptr[0] = model.cpuTexCoord[i].y;
        ++ptr;

        ptr[0] = model.cpuColor[i].x;
        ++ptr;
        ptr[0] = model.cpuColor[i].y;
        ++ptr;
        ptr[0] = model.cpuColor[i].z;
        ++ptr;
        ptr[0] = model.cpuColor[i].w;
        ++ptr;

        ptr[0] = model.cpuNormal[i].x;
        ++ptr;
        ptr[0] = model.cpuNormal[i].y;
        ++ptr;
        ptr[0] = model.cpuNormal[i].z;
        ++ptr;

        ptr[0] = model.cpuVertex[i].x;
        ++ptr;
        ptr[0] = model.cpuVertex[i].y;
        ++ptr;
        ptr[0] = model.cpuVertex[i].z;
        ++ptr;
    }
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, totalSize, interleave, GL_STATIC_DRAW_ARB);
    free(interleave);

    configureCameraAndLights();
    
    float k = 0;

    double t0 = 0, t1 = 0;
    for (int j = 0; j < frames + 1; ++j) {
        if (j == 1) {
            t0 = System::time();
        }
        k += kstep;
        glClearColor(1.0f, 1.0f, 1.0f, 0.04f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, model.textureID);

        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        if (use_glInterleavedArrays) {
            // Use old-style OpenGL interleaving
            glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, (void*)0);
        } else {
            GLsizei stride = (3+3+4+2) * sizeof(float);

            // Manually interleave, which gives more flexibility
            glTexCoordPointer(2, GL_FLOAT, stride, (void*)texCoordPtr);
            glColorPointer   (4, GL_FLOAT, stride, (void*)colorPtr);
            glNormalPointer  (GL_FLOAT,    stride, (void*)normalPtr);
            glVertexPointer  (3, GL_FLOAT, stride, (void*)vertexPtr);
        }

        for (int c = 0; c < count; ++c) {
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glTranslatef(c - (count - 1) / 2.0, 0, -2);
            glRotatef(k * ((c & 1) * 2 - 1) + 90, 0, 1, 0);

            debugAssertGLOk();
            glDrawElements(GL_TRIANGLES, N, GL_UNSIGNED_SHORT, (void*)indexPtr);
            debugAssertGLOk();
        }

        glSwapBuffers();

    }
    glFinish();
    t1 = System::time();


    glPopClientAttrib();
    glPopAttrib();

    glDeleteBuffersARB(1, &indexBuffer);
    glDeleteBuffersARB(1, &vbo);

    return frames / (t1 - t0);
}
Exemple #19
0
VARArea::VARArea(size_t _size, UsageHint hint) : size(_size) {
    renderDevice = NULL;

    // See if we've determined the mode yet.
    if (mode == UNINITIALIZED) {
        if (GLCaps::supports_GL_ARB_vertex_buffer_object() &&
            (glGenBuffersARB != NULL) && 
            (glBufferDataARB != NULL) &&
            (glDeleteBuffersARB != NULL) &&			
			! GLCaps::hasBug_slowVBO()) {
			mode = VBO_MEMORY;
        } else {
            mode = MAIN_MEMORY;
        }
    }

    _sizeOfAllVARAreasInMemory += size;

    switch (mode) {
    case VBO_MEMORY:
        {
            //glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
                glGenBuffersARB(1, &glbuffer);
                glBindBufferARB(GL_ARRAY_BUFFER_ARB, glbuffer);

                GLenum usage;

                switch (hint) {
                case WRITE_EVERY_FRAME:
                    usage = GL_STREAM_DRAW_ARB;
                    break;

                case WRITE_ONCE:
                    usage = GL_STATIC_DRAW_ARB;
                    break;

                case WRITE_EVERY_FEW_FRAMES:
                    usage = GL_DYNAMIC_DRAW_ARB;
                    break;

                default:
                    usage = GL_STREAM_DRAW_ARB;
                    debugAssertM(false, "Fell through switch");
                }

                // Load some (undefined) data to initialize the buffer
                glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, usage);
                debugAssertGLOk();    

                // The basePointer is always NULL for a VBO
                basePointer = NULL;

                glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
            //glPopClientAttrib();
            debugAssertGLOk();
        }
        break;

    case MAIN_MEMORY:
        // Use the base pointer
        glbuffer = 0;
        basePointer = malloc(size);
        debugAssert(basePointer);
        break;

    default:
        alwaysAssertM(false, "Fell through switch.");
        glbuffer = 0;
        basePointer = NULL;
    }

    milestone     = NULL;
    allocated     = 0;
	generation    = 1;
	peakAllocated = 0;
}
Exemple #20
0
Model::Model(const std::string& filename, VARAreaRef varStatic) {
    // This loads an IFS file.  Note that we could have used G3D::IFSModel::load to
    // parse the file for us.

    // file := 
    //    fileheader +
    //    vertexheader +
    //    vertex* +
    //    triheader +
    //    tri*
    //
    //  fileheader   := (string32) "IFS" + (float32)1.0 + (string32)modelname
    //  vertexheader := (string32) "VERTICES" + (uint32)numVertices
    //  vertex       := (float32)x + (float32)y + (float32)z
    //  triheader    := (string32)"TRIANGLES" + (uint32)numFaces
    //  tri          := (uint32)v0 + (uint32)v1 + (uint32)v2

    Log::common()->println(std::string("Loading ") + filename);

    BinaryInput b(filename, G3D_LITTLE_ENDIAN);

    std::string fmt         = b.readString32();
    float       version     = b.readFloat32();
    (void) version;
    std::string name        = b.readString32();

    debugAssert(fmt     == "IFS");
    debugAssert(version == 1.0);

    std::string vertexHeader = b.readString32();

    // Load the vertices
    vertex.resize(b.readUInt32());

    for (int v = 0; v < vertex.size(); ++v) {
        vertex[v] = b.readVector3() * 5;
    }

    // Per-vertex normals
    normal.resize(vertex.size());

    // Load the triangles
    std::string triHeader   = b.readString32();

    int numTris = b.readUInt32();

    for (int t = 0; t < numTris; ++t) {
        int v0 = b.readUInt32();
        int v1 = b.readUInt32();
        int v2 = b.readUInt32();

        // Compute the non-unit face normal
        Vector3 faceNormal = 
          (vertex[v1] - vertex[v0]).cross( 
           (vertex[v2] - vertex[v0]));

        normal[v0] += faceNormal;
        normal[v1] += faceNormal;
        normal[v2] += faceNormal;

        // Record the indices
        index.append(v0, v1, v2);
    }

    // Rescale the normals to unit length
    for (int n = 0; n < normal.size(); ++n) {
        normal[n] = normal[n].direction();
    }

    varVertex = VAR(vertex, varStatic);
    varNormal = VAR(normal, varStatic);
    debugAssertGLOk();    
}
Exemple #21
0
void Demo::onGraphics(RenderDevice* rd) {

    rd->clear(sky == NULL, true, false);
    rd->setProjectionAndCameraMatrix(app->debugCamera);
    LightingParameters lighting(gameTime, false);

    if (sky.notNull()) {
       sky->render(rd, lighting);
    }
                    
    rd->pushState();
        // Setup lighting
        rd->setSpecularCoefficient(1);
        rd->setShininess(64);
        debugAssertGLOk();
        rd->enableLighting();
        rd->setLight(0, GLight::directional(lighting.lightDirection, lighting.lightColor));
        rd->setLight(1, GLight::directional(-lighting.lightDirection, Color3::white() * .25, false));
        rd->setAmbientLightColor(lighting.ambient);

        rd->setShadeMode(RenderDevice::SHADE_SMOOTH);

        static const Color3 color[] = {Color3::black(), Color3::white(), Color3::orange(), Color3::blue()};
        double  t[2];
        Vector3 c[2];

        t[0] = System::time();
        t[1] = t[0] + 0.01;

		// Draw the planes
        for (int x = 0; x < N; ++x) {

            for (int i = 0; i < 2; ++i) {
                double a = x + t[i] + 2; 
                double a2 = t[i] * (x + 1) * .01 + 1005.1;
                c[i] = Vector3(cos(a) * (10 + x / 2.0), sin(a2) * 10, sin(a) * 15);
            }

            CoordinateFrame cframe(c[0]);

            double a = t[0] * (x + 1) * .1; 
            cframe.lookAt(c[1], Vector3(cos(a), 3, sin(a)).direction());


            rd->setColor(color[x % 4]);
            model->render(rd, cframe, lighting, varStream);
        }
    rd->popState();


    if (sky.notNull()) {
        sky->renderLensFlare(rd, lighting);
    }
    
    rd->push2D();
        char* str = NULL;
        switch (renderMethod) {
        case TRIANGLES:
            str = "Using begin/end (SPACE to change)";
            break;

        case VARSTREAM:
            str = "Using streaming vertex array (SPACE to change)";
            break;

        case VARSTATIC:
            str = "Using static vertex array (SPACE to change)";
            break;

        default:;
        }

       app->debugFont->draw2D(rd, str, Vector2(10, rd->height() - 40), 20, Color3::yellow(), Color3::black());

    rd->pop2D();

    debugAssertGLOk();    
    varStream->reset();
}
void Shader::ShaderProgram::compile
   (const Array<PreprocessedShaderSource>&  pss, 
    const String&                           preambleAndMacroArgs, 
    const Args&                             args,
    const Table<int, String>&               indexToNameTable,
    Array<String>&                          codeArray) {
    
    debugAssertGLOk();
    codeArray.fastClear();
    codeArray.resize(STAGE_COUNT);
    for (int s = 0; s < STAGE_COUNT; ++s) {
        const PreprocessedShaderSource& pSource = pss[s];
        if (pSource.preprocessedCode != "") {
            String fullyProcessedCode = pSource.preprocessedCode;

            const bool processSuccess = Shader::expandForPragmas(fullyProcessedCode, args, indexToNameTable, messages);
            ok = ok && processSuccess;

            if (processSuccess) {
				String& code = codeArray[s] = pSource.versionString + pSource.extensionsString + preambleAndMacroArgs + pSource.g3dInsertString + fullyProcessedCode;


                GLint compiled = GL_FALSE;
                GLuint& glShader = glShaderObject[s];
                glShader = glCreateShader(glShaderType(s));

                // Compile the shader
                GLint length = (GLint)code.length();

				// debugPrintf("Compiling a shader of %d kB\n", iRound(length / 1000.0f));
                const GLchar* codePtr = static_cast<const GLchar*>(code.c_str());
                
                int count = 1;
                glShaderSource(glShader, count, &codePtr, &length);
                glCompileShader(glShader);
                glGetShaderiv(glShader, GL_COMPILE_STATUS, &compiled);

                // Read the result of compilation
                GLint maxLength;
                glGetShaderiv(glShader, GL_INFO_LOG_LENGTH, &maxLength);

                debugAssertGLOk();
                if (maxLength > 0) {
                    GLchar* pInfoLog = (GLchar*)System::malloc(maxLength * sizeof(GLchar));
                    glGetShaderInfoLog(glShader, maxLength, &length, pInfoLog);
                    readAndAppendShaderLog(pInfoLog, messages, pSource.filename, indexToNameTable);
                    System::free(pInfoLog);
                }
            
                ok = ok && (compiled == GL_TRUE);

#               ifdef G3D_DEBUG
                if (! ok) {
                    debugPrintf("Shader source:\n%s\n", codePtr);
                }
#               endif
            }

        } else {
            // No code to compile from, so the shader object does not exist
            glShaderObject[s] = 0; 
        }    
    } // for each stage
    
}
Exemple #23
0
std::string getOpenGLState(bool showDisabled) {
    {
        debugAssertGLOk();
        glGetInteger(GL_BLEND);
        debugAssertM(glGetError() != GL_INVALID_OPERATION, 
             "Can't call getOpenGLState between glBegin() and glEnd()");
    }

    // The implementation has to be careful not to disrupt any OpenGL state and
    // to produce output code that sets values that interact (e.g. lighting and modelview matrix) in an order
    // so they produce the same results as currently in memory.

    std::string result;

    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                         Matrices                              //\n\n";
    result += getMatrixState();


    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                         Lighting                              //\n\n";
    result += getLightingState(showDisabled);

    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                         Clipping                              //\n\n";
    result += getClippingState();

    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                         Textures                              //\n\n";

    result += getTextureState(showDisabled);

    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                          Other                                //\n\n";
    
    GLdouble d[4];
    GLboolean b[4];

    // Viewport
    glGetDoublev(GL_VIEWPORT, d);
    result += format("glViewport(%g, %g, %g, %g);\n\n", d[0], d[1], d[2], d[3]);

    //color
    result += enableEntry(GL_COLOR_ARRAY);
    result += enableEntry(GL_COLOR_LOGIC_OP);
    result += enableEntry(GL_COLOR_MATERIAL);

    glGetDoublev(GL_COLOR_CLEAR_VALUE, d);
    result += format("glClearColor(%g, %g, %g, %g);\n", d[0], d[1], d[2], d[3]);
    glGetDoublev(GL_CURRENT_COLOR, d);
    result += format("glColor4d(%g, %g, %g, %g);\n", d[0], d[1], d[2], d[3]);
    glGetBooleanv(GL_COLOR_WRITEMASK, b);
    result += format("glColorMask(%d, %d, %d, %d);\n", b[0], b[1], b[2], b[3]);

    result += format("\n");


    //blend
    result += enableEntry(GL_BLEND);

    if (showDisabled || glGetBoolean(GL_BLEND)) {
        result += format("glBlendFunc(%s, %s);\n", 
            GLenumToString(glGetInteger(GL_BLEND_DST)),
            GLenumToString(glGetInteger(GL_BLEND_SRC)));
        result += format("\n");
    }



    //alpha
    result += enableEntry(GL_ALPHA_TEST);

    if (showDisabled || glGetBoolean(GL_ALPHA_TEST)) {
        result += format("glAlphaFunc(%s, %g);\n", 
            GLenumToString(glGetInteger(GL_ALPHA_TEST_FUNC)),
            glGetDouble(GL_ALPHA_TEST_REF));
        result += format("\n");
    }


    //depth stuff
    result += "///////////////////////////////////////////////////////////////////\n";
    result += "//                      Depth Buffer                             //\n\n";
    result += enableEntry(GL_DEPTH_TEST);
    if (showDisabled || glGetBoolean(GL_DEPTH_TEST)) {
        result += format("glDepthFunc(%s);\n", 
            GLenumToString(glGetInteger(GL_DEPTH_FUNC)));
    }

    result += format("glClearDepth(%g);\n", glGetDouble(GL_DEPTH_CLEAR_VALUE));
    result += format("glDepthMask(%d);\n", glGetBoolean(GL_DEPTH_WRITEMASK));

    {
        Vector2 range = glGetVector2(GL_DEPTH_RANGE);
        result += format("glDepthRange(%g, %g);\n", range.x, range.y);
    }

    result += format("\n");


    //stencil stuff
    result += "///////////////////////////////////////////////////////////////////////\n";
    result += "// Stencil\n\n";

    result += enableEntry(GL_STENCIL_TEST);

    result += format("glClearStencil(0x%x);\n", glGetInteger(GL_STENCIL_CLEAR_VALUE));

    if (GLCaps::supports_GL_EXT_stencil_two_side()) {
        result += "glActiveStencilFaceEXT(GL_BACK);\n";
        glActiveStencilFaceEXT(GL_BACK);
    }

    if (showDisabled || glGetBoolean(GL_STENCIL_TEST)) 
        result += format(
            "glStencilFunc(%s, %d, %d);\n",
            GLenumToString(glGetInteger(GL_STENCIL_FUNC)),
            glGetInteger(GL_STENCIL_REF),
            glGetInteger(GL_STENCIL_VALUE_MASK));

    result += format(
        "glStencilOp(%s, %s, %s);\n",
        GLenumToString(glGetInteger(GL_STENCIL_FAIL)),
        GLenumToString(glGetInteger(GL_STENCIL_PASS_DEPTH_FAIL)),
        GLenumToString(glGetInteger(GL_STENCIL_PASS_DEPTH_PASS)));

    result += format("glStencilMask(0x%x);\n", glGetInteger(GL_STENCIL_WRITEMASK));

    if (GLCaps::supports_GL_EXT_stencil_two_side()) {
        result += "\nglActiveStencilFaceEXT(GL_FRONT);\n";
        glActiveStencilFaceEXT(GL_FRONT);

        if (showDisabled || glGetBoolean(GL_STENCIL_TEST)) 
            result += format(
                "glStencilFunc(%s, %d, %d);\n",
                GLenumToString(glGetInteger(GL_STENCIL_FUNC)),
                glGetInteger(GL_STENCIL_REF),
                glGetInteger(GL_STENCIL_VALUE_MASK));

        result += format(
            "glStencilOp(%s, %s, %s);\n",
            GLenumToString(glGetInteger(GL_STENCIL_FAIL)),
            GLenumToString(glGetInteger(GL_STENCIL_PASS_DEPTH_FAIL)),
            GLenumToString(glGetInteger(GL_STENCIL_PASS_DEPTH_PASS)));

        result += format("glStencilMask(0x%x);\n", glGetInteger(GL_STENCIL_WRITEMASK));
    }
    
    result += ("\n");

    //misc
    result += enableEntry(GL_NORMAL_ARRAY);
    result += enableEntry(GL_NORMALIZE);

    glGetDoublev(GL_CURRENT_NORMAL, d);
    result += format("glNormal3d(%g, %g, %g);\n", d[0], d[1], d[2]);

    result += ("\n");

    result += format("glPixelZoom(%g, %g);\n", glGetDouble(GL_ZOOM_X), 
        glGetDouble(GL_ZOOM_Y));

    result += format("glReadBuffer(%s);\n", 
        GLenumToString(glGetInteger(GL_READ_BUFFER)));

    result += enableEntry(GL_POLYGON_SMOOTH);
    result += enableEntry(GL_POLYGON_STIPPLE);
    result += enableEntry(GL_LINE_SMOOTH);
    result += enableEntry(GL_LINE_STIPPLE);
    result += enableEntry(GL_POINT_SMOOTH);

    result += enableEntry(GL_AUTO_NORMAL);
    result += enableEntry(GL_CULL_FACE);

    result += enableEntry(GL_POLYGON_OFFSET_FILL);
    result += enableEntry(GL_POLYGON_OFFSET_LINE);
    result += enableEntry(GL_POLYGON_OFFSET_POINT);

    result += ("\n");

    result += enableEntry(GL_DITHER);
    result += enableEntry(GL_FOG);

    result += enableEntry(GL_VERTEX_ARRAY);
    result += enableEntry(GL_INDEX_ARRAY);
    result += enableEntry(GL_INDEX_LOGIC_OP);

    result += format("\n");

    result += enableEntry(GL_MAP1_COLOR_4);
    result += enableEntry(GL_MAP1_INDEX);
    result += enableEntry(GL_MAP1_NORMAL);
    result += enableEntry(GL_MAP1_TEXTURE_COORD_1);
    result += enableEntry(GL_MAP1_TEXTURE_COORD_2);
    result += enableEntry(GL_MAP1_TEXTURE_COORD_3);
    result += enableEntry(GL_MAP1_TEXTURE_COORD_4);
    result += enableEntry(GL_MAP1_VERTEX_3);
    result += enableEntry(GL_MAP1_VERTEX_4);
    result += enableEntry(GL_MAP2_COLOR_4);
    result += enableEntry(GL_MAP2_INDEX);
    result += enableEntry(GL_MAP2_NORMAL);
    result += enableEntry(GL_MAP2_TEXTURE_COORD_1);
    result += enableEntry(GL_MAP2_TEXTURE_COORD_2);
    result += enableEntry(GL_MAP2_TEXTURE_COORD_3);
    result += enableEntry(GL_MAP2_TEXTURE_COORD_4);
    result += enableEntry(GL_MAP2_VERTEX_3);
    result += enableEntry(GL_MAP2_VERTEX_4);

    result += format("\n");

    result += enableEntry(GL_SCISSOR_TEST);

    return result;
}
void Shader::ShaderProgram::addActiveUniformsFromProgram() {
    // Length of the longest variable name
    GLint maxLength;

    // Number of uniform variables
    GLint uniformCount;
    // Get the number of uniforms, and the length of the longest name.
    glGetProgramiv(glShaderProgramObject(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
    glGetProgramiv(glShaderProgramObject(), GL_ACTIVE_UNIFORMS, &uniformCount);
    GLchar* name = (GLchar *) malloc(maxLength * sizeof(GLchar));
    
    // Get the sizes, types and names
    int lastTextureUnit = -1;
    int lastImageUnit = -1;
    // Loop over glGetActiveUniform and store the results away.
    for (int i = 0; i < uniformCount; ++i) {
        const GLuint uniformIndex = i;
        GLuint programObject = glShaderProgramObject();

        GLint elementNum;
        GLenum type;
        glGetActiveUniform(programObject, uniformIndex, maxLength, NULL, &elementNum, &type, name);
        UniformDeclaration& d = uniformDeclarationTable.getCreate(name);
        d.name = name;
        d.location = glGetUniformLocation(glShaderProgramObject(), name);
        d.type = type;
        d.elementNum = elementNum;

        bool isGLBuiltIn = (d.location == -1) || 
            ((strlen(name) > 3) && beginsWith(String(name), "gl_"));

        d.dummy = isGLBuiltIn;
        d.index = -1;
        if (! isGLBuiltIn) {
            if (isSamplerType(d.type)) {
                ++lastTextureUnit;
                d.glUnit = lastTextureUnit;           
            } else if (isImageType(d.type)) {
                ++lastImageUnit;
                d.glUnit = lastImageUnit;
            } else if (d.elementNum == 1) { 
                // Not array
                d.glUnit = -1;
            } else { 
                // Is an array, remove from uniform declaration table, and add it's elements
                GLint type      = d.type;
                int arraySize   = (int)d.elementNum;
                int glUnit = -1;
                uniformDeclarationTable.remove(name);
                
                // Get rid of [0] if it exists (depends on driver)
                String arrayName = name;
                if (arrayName[arrayName.length()-1] == ']') {
                    size_t bracketLoc = arrayName.rfind('[');
                    // TODO: error handle if "[" doesn't exist
                    arrayName = arrayName.substr(0, bracketLoc);
                }
                
                
                for (int i = 0; i < arraySize; ++i) {
                    const String appendedName = format("%s[%d]", arrayName.c_str(), i);
                    UniformDeclaration& elementDeclaration = uniformDeclarationTable.getCreate(appendedName);
                    GLint location = glGetUniformLocation(glShaderProgramObject(), appendedName.c_str());
                    debugAssertGLOk();
		            bool dummy = (location == -1);
                    elementDeclaration.setAllFields(appendedName, i, type, location, dummy, glUnit);
                }
            }
        }
    }

    free(name);
}