示例#1
0
/*!
    \internal
    Construct a new QGLSection on the display list \a list, and with smoothing \a s.
    By default the smoothing is QGL::Smooth.

    See QGLBuilder for a discussion of smoothing.

    The pointer \a list must be non-null, and in debug mode, unless QT_NO_DEBUG is
    defined, this function will assert if \a list is null.

    The following lines of code have identical effect:
    \code
    QGLSection *s = myDisplayList->newSection(QGL::Faceted);
    QGLSection *s2 = new QGLSection(myDisplayList, QGL::Faceted);
    \endcode
*/
QGLSection::QGLSection(QGLBuilder *list, QGL::Smoothing s)
    : m_smoothing(s)
    , m_displayList(list)
    , d(0)
{
    Q_ASSERT(m_displayList);
    enableField(QGL::Position);
    Q_ASSERT(vertexData());
    d = new QGLSectionPrivate(vertexData());
    m_displayList->addSection(this);
}
示例#2
0
void Quads::uploadVertices() const
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexAndTextureBuf);
    glBufferData(
        GL_ARRAY_BUFFER,
        vertexDataByteCount(),
        vertexData(),
        GL_STATIC_DRAW);
}
示例#3
0
Mesh* CreateSolidPlane(float xSize, float zSize, int xSegments, int zSegments, const glm::mat4& transform)
{
    int numVertices = (xSegments + 1) * (zSegments + 1);

    std::vector<VertexPositionNormal> vertexData(numVertices);

    float xStep = xSize / xSegments;
    float zStep = zSize / zSegments;

    VertexPositionNormal* vertexPtr = &vertexData[0];

    float z = -0.5f * zSize;
    for (int j = 0; j <= zSegments; j++) {
        float x = -0.5f * xSize;
        for (int i = 0; i <= xSegments; i++) {
            vertexPtr->pos.x = x;
            vertexPtr->pos.y = 0;
            vertexPtr->pos.z = z;
            vertexPtr->normal.x = 0;
            vertexPtr->normal.y = 1;
            vertexPtr->normal.z = 0;
            ++vertexPtr;
            x += xStep;
        }
        z += zStep;
    }

    int numTriangles = 2 * xSegments * zSegments;

    int numElements = 3 * numTriangles;
    std::vector<unsigned> indexData(numElements);   // use 32-bit indices for large planes!!!11!!!

    unsigned* indexPtr = &indexData[0];
    unsigned e = 0;
    for (int j = 0; j < zSegments; j++) {
        for (int i = 0; i < xSegments; i++) {
            // the four corners of this "square"
            unsigned e = (xSegments + 1) * j + i;
            unsigned e1 = e;
            unsigned e2 = e + 1;
            unsigned e3 = e + xSegments + 1;
            unsigned e4 = e + xSegments + 2;
            // triangle 1
            *indexPtr++ = e1;
            *indexPtr++ = e3;
            *indexPtr++ = e4;
            // triangle 2
            *indexPtr++ = e1;
            *indexPtr++ = e4;
            *indexPtr++ = e2;
            ++e;
        }
        ++e;
    }

    return CreateMesh(GL_TRIANGLES, vertexData, indexData);
}
void BindlingLoopsGeometry::addExpandedEvent(float itemCenter)
{
    float verticalCenter = Timeline::TimelineModel::defaultRowHeight() / 2.0;
    Point2DWithOffset *v = vertexData() + usedVertices;
    v[0].set(itemCenter, verticalCenter, -1.0f, currentY);
    v[1].set(itemCenter, verticalCenter, +1.0f, currentY);
    currentY = -currentY;
    v[2].set(itemCenter, verticalCenter, -1.0f, currentY);
    v[3].set(itemCenter, verticalCenter, +1.0f, currentY);
    usedVertices += 4;
}
示例#5
0
std::shared_ptr<MeshData>& ResourceManager::makeMesh(const std::string& name) {
    if (this->meshDataCache.find(name) == this->meshDataCache.end()) {
        Logger::getInstance().log(Logger::LOG_INFO, "Loading mesh `%s'", name.c_str());

        std::shared_ptr<MeshData> vertexData(new MeshData());
        if (!vertexData->load(name)) {
            // VertexData::load() prints errors for us
            return this->meshDataCache["nullptr"];
        }

        this->meshDataCache.insert(std::make_pair(name, vertexData));
    }

    return this->meshDataCache[name];
}
void PCPRenderer::invalidateBuffer() {
    if (!_inport.hasData())
        return;

    std::shared_ptr<const ParallelCoordinatesPlotData> data = _inport.getData();


    if (_dimensionOrdering.empty()) {
        _dimensionOrdering.resize(data->nDimensions);
        std::iota(_dimensionOrdering.begin(), _dimensionOrdering.end(), 0);
    }
    if (_dimensionOrdering.size() != data->nDimensions) {
        LogError("Wrong dimensions. Dimension ordering: " << _dimensionOrdering.size() <<
            "  nDimensions: " << data->nDimensions
        );
        return;
    }

    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    std::vector<float> vertexData(data->nDimensions);
    for (int i = 0; i < data->nDimensions; ++i)
        vertexData[i] = dimensionLocation(i, _horizontalBorder, data->nDimensions);

        //int dim = _dimensionOrdering[i];


    glBufferData(GL_ARRAY_BUFFER,
        vertexData.size() * sizeof(float),
        vertexData.data(),
        GL_DYNAMIC_DRAW
    );
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, _dimensionOrderingBuffer);
    glBufferData(
        GL_SHADER_STORAGE_BUFFER,
        _dimensionOrdering.size() * sizeof(int),
        _dimensionOrdering.data(),
        GL_STATIC_DRAW
    );

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

}
示例#7
0
shared_ptr<VertexBuffer> createQuad2(const VertexFormat &vf, float x, float y, float w, float h, GpuBufferUsageType usage)
{
    // TODO_REFACTO remove this shit!!!

    float w2 = w / 2.0f;
    float h2 = h / 2.0f;

    float quad_pos[][2] =
    {
        { x - w2, y - h2 },
        { x + w2, y - h2 },
        { x + w2, y + h2 },
        { x + w2, y + h2 },
        { x - w2, y + h2 },
        { x - w2, y - h2 }
    };
    float quad_uv[][2] =
    {
        { 0.0, 0.0 },
        { 1.0, 0.0 },
        { 1.0, 1.0 },
        { 1.0, 1.0 },
        { 0.0, 1.0 },
        { 0.0, 0.0 }
    };

    VertexData vertexData(vf);

    for (int i = 0; i < 6; i++)
    {
        auto v = vertexData.allocVertex();

        v.setPosition({ quad_pos[i][0], quad_pos[i][1], 0.0f });
        v.setTx({ quad_uv[i][0], quad_uv[i][1] });
        v.setColor({ 1.0f, 1.0f, 1.0f, 1.0f });
    }

    auto result = make_shared<VertexBuffer>(vf);
    result->alloc(vertexData, usage);

    return result;
}
示例#8
0
std::shared_ptr<Geom> TriSoup::CreateGeom(const TriSoup& soup)
{
	std::vector<IndexType> indices(3 * soup.NumFaces());
	std::vector<float> vertexData(6 * soup.NumVertices());

	const int vtxStride = 6 * sizeof(float);
	unsigned int offset = 0;
	const unsigned int numVertices = 
		Min<unsigned int>(soup.m_vertices.size(), std::numeric_limits<IndexType>::max());
	for(unsigned int i = 0; i < numVertices; ++i)
	{
		const auto& vtx = soup.m_vertices[i];
		vertexData[offset++] = vtx.m_pos.x;
		vertexData[offset++] = vtx.m_pos.y;
		vertexData[offset++] = vtx.m_pos.z;
		vertexData[offset++] = vtx.m_normal.x;
		vertexData[offset++] = vtx.m_normal.y;
		vertexData[offset++] = vtx.m_normal.z;
	}

	offset = 0;
	for(const auto& face: soup.m_faces)
	{
		if(std::any_of(face.m_vertices, face.m_vertices+3, 
			[](int val) { return (unsigned int)val > std::numeric_limits<IndexType>::max(); }))
			continue;
		
		indices[offset++] = face.m_vertices[0];
		indices[offset++] = face.m_vertices[1];
		indices[offset++] = face.m_vertices[2];
	}
	const unsigned int numIndices = offset;

	return std::make_shared<Geom>(
		numVertices, &vertexData[0],
		numIndices, &indices[0],
		vtxStride, GL_TRIANGLES,
		std::vector<GeomBindPair>{
			{GEOM_Pos, 3, 0},
			{GEOM_Normal, 3, 3 * sizeof(float)},
		});
}
示例#9
0
文件: Quad.cpp 项目: Dragnalith/bud
Quad::Quad(RenderDevice* renderDevice)
	: Mesh(renderDevice)
{
	VertexFloat verticeArray[] = {
        VertexFloat(-1.0f, 1.0f, 0.0f, 0.0, 0.0, 1.0, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f),
        VertexFloat(-1.0f, -1.0f, 0.0f, 0.0, 0.0, 1.0, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f),
        VertexFloat(1.0f, -1.0f, 0.0f, 0.0, 0.0, 1.0, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f),
        VertexFloat(1.0f, 1.0f, 0.0f, 0.0, 0.0, 1.0, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f)
	};
	std::vector<VertexFloat> vertexData(verticeArray, verticeArray + sizeof(verticeArray) / sizeof(verticeArray[0]));
    
    unsigned int indexArray[] = {
        0, 1, 2,
        0, 2, 3,
    };
    std::vector<unsigned int> indexData(indexArray, indexArray + sizeof(indexArray) / sizeof(indexArray[0]));
    
    m_Buffer->setVertices(vertexData.size(), &vertexData[0]);
    m_Buffer->setIndices(indexData.size(), &indexData[0]);
}
void BindlingLoopsGeometry::addCollapsedEvent(float horizontalCenterSource,
                                              float horizontalCenterTarget,
                                              float verticalCenterSource,
                                              float verticalCenterTarget)
{
    if (verticalCenterSource < verticalCenterTarget) {
        qSwap(verticalCenterSource, verticalCenterTarget);
        qSwap(horizontalCenterSource, horizontalCenterTarget);
    }

    float tilt = horizontalCenterSource < horizontalCenterTarget ? +0.3 : -0.3;

    Point2DWithOffset *v = vertexData() + usedVertices;
    v[0].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[1].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[2].set(horizontalCenterSource, verticalCenterSource, +0.3f, -tilt);

    v[3].set(horizontalCenterTarget, verticalCenterTarget, -0.3f, tilt);
    v[4].set(horizontalCenterTarget, verticalCenterTarget, +0.3f, -tilt);
    v[5].set(horizontalCenterTarget, verticalCenterTarget, -1.0f, -1.0f);
    v[6].set(horizontalCenterTarget, verticalCenterTarget, +1.0f, -1.0f);
    v[7].set(horizontalCenterTarget, verticalCenterTarget, -1.0f, +1.0f);
    v[8].set(horizontalCenterTarget, verticalCenterTarget, +1.0f, +1.0f);
    v[9].set(horizontalCenterTarget, verticalCenterTarget, -0.3f, tilt);
    v[10].set(horizontalCenterTarget, verticalCenterTarget, +0.3f, -tilt);

    v[11].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[12].set(horizontalCenterSource, verticalCenterSource, +0.3f, -tilt);
    v[13].set(horizontalCenterSource, verticalCenterSource, -1.0f, +1.0f);
    v[14].set(horizontalCenterSource, verticalCenterSource, +1.0f, +1.0f);
    v[15].set(horizontalCenterSource, verticalCenterSource, -1.0f, -1.0f);
    v[16].set(horizontalCenterSource, verticalCenterSource, +1.0f, -1.0f);
    v[17].set(horizontalCenterSource, verticalCenterSource, +1.0f, -1.0f);

    usedVertices += 18;
}
void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
{

	btSoftBodySolver *solver = softBody->getSoftBodySolver();
	btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER );
	btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver );
	checkInitialized();
	btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody );
	btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData );	

	const int firstVertex = currentCloth->getFirstVertex();
	const int lastVertex = firstVertex + currentCloth->getNumVertices();

	if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) {		

		const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer);						
		cl_int ciErrNum = CL_SUCCESS;    

		cl_mem clBuffer = openGLVertexBuffer->getBuffer();		
		cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel;
		if( !vertexBuffer->hasNormals() )
			outputKernel = outputToVertexArrayWithoutNormalsKernel;

		ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
		if( ciErrNum != CL_SUCCESS )
		{
			btAssert( 0 &&  "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
		}

		int numVertices = currentCloth->getNumVertices();

		ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex );
		ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices );
		ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
		if( vertexBuffer->hasVertexPositions() )
		{
			int vertexOffset = vertexBuffer->getVertexOffset();
			int vertexStride = vertexBuffer->getVertexStride();
			ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset );
			ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride );
			ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer );

		}
		if( vertexBuffer->hasNormals() )
		{
			int normalOffset = vertexBuffer->getNormalOffset();
			int normalStride = vertexBuffer->getNormalStride();
			ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset );
			ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride );
			ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer );

		}
		size_t	numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize);
		ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
		if( ciErrNum != CL_SUCCESS ) 
		{
			btAssert( 0 &&  "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)");
		}

		ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0);
		if( ciErrNum != CL_SUCCESS )
		{
			btAssert( 0 &&  "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)");
		}
	} else {
		btAssert( "Undefined output for this solver output" == false );
	}

	// clFinish in here may not be the best thing. It's possible that we should have a waitForFrameComplete function.
	clFinish(m_cqCommandQue);

} // btSoftBodySolverOutputCLtoGL::outputToVertexBuffers
int main()
{
    int width = 640;
    int height = 480;
    
    if(glfwInit() == GL_FALSE)
    {
        std::cerr << "failed to init GLFW" << std::endl;
        return 1;
    } 
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
 
    // create a window
    if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE)
    {
        std::cerr << "failed to open window" << std::endl;
        glfwTerminate();
        return 1;
    }
    
    // setup windows close callback
    glfwSetWindowCloseCallback(closedWindow);
    
    if (gl3wInit())
    {
        std::cerr << "failed to init GL3W" << std::endl;
        glfwCloseWindow();
        glfwTerminate();
        return 1;
    }

    // shader source code
    
    // the vertex shader simply passes through data
    std::string vertex_source =
        "#version 430\n"
        "layout(location = 0) in vec4 vposition;\n"
        "void main() {\n"
        "   gl_Position = vposition;\n"
        "}\n";
    
    // the geometry shader creates the billboard quads
    std::string geometry_source =
        "#version 430\n"
        "uniform mat4 View;\n"
        "uniform mat4 Projection;\n"
        "layout (points) in;\n"
        "layout (triangle_strip, max_vertices = 4) out;\n"
        "out vec2 txcoord;\n"
        "void main() {\n"
        "   vec4 pos = View*gl_in[0].gl_Position;\n"
        "   txcoord = vec2(-1,-1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1,-1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2(-1, 1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1, 1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "}\n";    
    
    // the fragment shader creates a bell like radial color distribution    
    std::string fragment_source =
        "#version 330\n"
        "in vec2 txcoord;\n"
        "layout(location = 0) out vec4 FragColor;\n"
        "void main() {\n"
        "   float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n"
        "   FragColor = s*vec4(0.3,0.3,1.0,1);\n"
        "}\n";
   
    // program and shader handles
    GLuint shader_program, vertex_shader, geometry_shader, fragment_shader;
    
    // we need these to properly pass the strings
    const char *source;
    int length;

    // create and compiler vertex shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    source = vertex_source.c_str();
    length = vertex_source.size();
    glShaderSource(vertex_shader, 1, &source, &length); 
    glCompileShader(vertex_shader);
    if(!check_shader_compile_status(vertex_shader))
    {
        return 1;
    }
    
    // create and compiler geometry shader
    geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
    source = geometry_source.c_str();
    length = geometry_source.size();
    glShaderSource(geometry_shader, 1, &source, &length); 
    glCompileShader(geometry_shader);
    if(!check_shader_compile_status(geometry_shader))
    {
        return 1;
    }
 
    // create and compiler fragment shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    source = fragment_source.c_str();
    length = fragment_source.size();
    glShaderSource(fragment_shader, 1, &source, &length);   
    glCompileShader(fragment_shader);
    if(!check_shader_compile_status(fragment_shader))
    {
        return 1;
    }
    
    // create program
    shader_program = glCreateProgram();
    
    // attach shaders
    glAttachShader(shader_program, vertex_shader);
    glAttachShader(shader_program, geometry_shader);
    glAttachShader(shader_program, fragment_shader);
    
    // link the program and check for errors
    glLinkProgram(shader_program);
    check_program_link_status(shader_program);
    
    // obtain location of projection uniform
    GLint View_location = glGetUniformLocation(shader_program, "View");
    GLint Projection_location = glGetUniformLocation(shader_program, "Projection");

    std::string compute_source =
        "#version 430\n"
        "layout(local_size_x=256) in;\n"
        
        "uniform vec3 center[3];\n"
        "uniform float radius[3];\n"
        "uniform vec3 g;\n"
        "uniform float dt;\n"
        "uniform float bounce;\n"
        "uniform int seed;\n"
        "uniform layout(rgba32f) imageBuffer particles;\n"
                
        "float hash(int x) {\n"
        "   x = x*1235167 + int(gl_GlobalInvocationID)*948737 + seed*9284365;\n"
        "   x = (x >> 13) ^ x;\n"
        "   return ((x * (x * x * 60493 + 19990303) + 1376312589) & 0x7fffffff)/float(0x7fffffff-1);\n"
        "}\n"
        
        "void main() {\n"
        "   int index = int(gl_GlobalInvocationID);\n"
        "   vec3 inposition = imageLoad(particles, 2*index).xyz;\n"
        "   vec3 invelocity = imageLoad(particles, 2*index+1).xyz;\n"
        "   vec3 outvelocity = invelocity;\n"
        "   for(int j = 0;j<3;++j) {\n"
        "       vec3 diff = inposition-center[j];\n"
        "       float dist = length(diff);\n"
        "       float vdot = dot(diff, invelocity);\n"
        "       if(dist<radius[j] && vdot<0.0)\n"
        "           outvelocity -= bounce*diff*vdot/(dist*dist);\n"
        "   }\n"
        "   outvelocity += dt*g;\n"
        "   vec3 outposition = inposition + dt*outvelocity;\n"
        "   if(outposition.y < -30.0)\n"
        "   {\n"
        "       outvelocity = vec3(0,0,0);\n"
        "       outposition = 0.5-vec3(hash(3*index+0),hash(3*index+1),hash(3*index+2));\n"
        "       outposition = vec3(0,20,0) + 5.0*outposition;\n"
        "   }\n"
        "   imageStore(particles, 2*index, vec4(outposition,1));\n"
        "   imageStore(particles, 2*index+1, vec4(outvelocity,1));\n"
        "}\n";
   
    // program and shader handles
    GLuint compute_program, compute_shader;

    // create and compiler vertex shader
    compute_shader = glCreateShader(GL_COMPUTE_SHADER);
    source = compute_source.c_str();
    length = compute_source.size();
    glShaderSource(compute_shader, 1, &source, &length); 
    glCompileShader(compute_shader);
    if(!check_shader_compile_status(compute_shader))
    {
        return 1;
    }

    // create program
    compute_program = glCreateProgram();
    
    // attach shaders
    glAttachShader(compute_program, compute_shader);
   
    // link the program and check for errors
    glLinkProgram(compute_program);
    check_program_link_status(compute_program);

    GLint center_location = glGetUniformLocation(compute_program, "center");
    GLint radius_location = glGetUniformLocation(compute_program, "radius");
    GLint g_location = glGetUniformLocation(compute_program, "g");
    GLint dt_location = glGetUniformLocation(compute_program, "dt");
    GLint bounce_location = glGetUniformLocation(compute_program, "bounce");
    GLint seed_location = glGetUniformLocation(compute_program, "seed");
    GLint particles_location = glGetUniformLocation(compute_program, "particles");
   
    const int particles = 128*1024;

    // randomly place particles in a cube
    std::vector<glm::vec4> vertexData(2*particles);
    for(int i = 0;i<particles;++i)
    {
        // initial position
        vertexData[2*i+0] = glm::vec4(
                                0.5f-float(std::rand())/RAND_MAX,
                                0.5f-float(std::rand())/RAND_MAX,
                                0.5f-float(std::rand())/RAND_MAX,
                                0
                            );
        vertexData[2*i+0] = glm::vec4(0.0f,20.0f,0.0f,1) + 5.0f*vertexData[2*i+0];
        
        // initial velocity
        vertexData[2*i+1] = glm::vec4(0,0,0,0);
    }
    
    // generate vbos and vaos
    GLuint vao, vbo;
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    

    glBindVertexArray(vao);
        
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    // fill with initial data
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4)*vertexData.size(), &vertexData[0], GL_STATIC_DRAW);
                        
    // set up generic attrib pointers
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat));
    // set up generic attrib pointers
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0 + 4*sizeof(GLfloat));


    // "unbind" vao
    glBindVertexArray(0);
    
    // texture handle
    GLuint buffer_texture;
    
    // generate and bind the buffer texture
    glGenTextures(1, &buffer_texture);
    glBindTexture(GL_TEXTURE_BUFFER, buffer_texture);
    
    // tell the buffer texture to use 
    glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, vbo);
    
    
    
    // we are blending so no depth testing
    glDisable(GL_DEPTH_TEST);
    
    // enable blending
    glEnable(GL_BLEND);
    //  and set the blend function to result = 1*source + 1*destination
    glBlendFunc(GL_ONE, GL_ONE);

    // define spheres for the particles to bounce off
    const int spheres = 3;
    glm::vec3 center[spheres];
    float radius[spheres];
    center[0] = glm::vec3(0,12,1);
    radius[0] = 3;
    center[1] = glm::vec3(-3,0,0);
    radius[1] = 7;
    center[2] = glm::vec3(5,-10,0);
    radius[2] = 12;

    // physical parameters
    float dt = 1.0f/60.0f;
    glm::vec3 g(0.0f, -9.81f, 0.0f);
    float bounce = 1.2f; // inelastic: 1.0f, elastic: 2.0f

    int current_buffer=0;
    running = true;
    while(running)
    {   
        // get the time in seconds
        float t = glfwGetTime();
        
        // terminate on excape 
        if(glfwGetKey(GLFW_KEY_ESC))
        {
            running = false;
        }



        // use the transform shader program
        glUseProgram(compute_program);

        // set the uniforms
        glUniform3fv(center_location, 3, reinterpret_cast<GLfloat*>(center)); 
        glUniform1fv(radius_location, 3, reinterpret_cast<GLfloat*>(radius));
        glUniform3fv(g_location, 1, glm::value_ptr(g));
        glUniform1f(dt_location, dt);
        glUniform1f(bounce_location, bounce);
        glUniform1i(seed_location, std::rand());
        
        glBindImageTexture(0, buffer_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
        glUniform1i(particles_location, 0);

        glDispatchCompute(particles/256, 1, 1);

        
        // clear first
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // use the shader program
        glUseProgram(shader_program);
        
        // calculate ViewProjection matrix
        glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f);
        
        // translate the world/view position
        glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f));
        
        // make the camera rotate around the origin
        View = glm::rotate(View, 30.0f, glm::vec3(1.0f, 0.0f, 0.0f)); 
        View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f)); 
        
        // set the uniform
        glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View)); 
        glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection)); 
        
        // bind the current vao
        glBindVertexArray(vao);

        // draw
        glDrawArrays(GL_POINTS, 0, particles);
       
        // check for errors
        GLenum error = glGetError();
        if(error != GL_NO_ERROR)
        {
            std::cerr << gluErrorString(error);
            running = false;       
        }
        
        // finally swap buffers
        glfwSwapBuffers();
    }
    
    // delete the created objects
        
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteTextures(1, &buffer_texture);
    
    glDetachShader(shader_program, vertex_shader);	
    glDetachShader(shader_program, geometry_shader);	
    glDetachShader(shader_program, fragment_shader);
    glDeleteShader(vertex_shader);
    glDeleteShader(geometry_shader);
    glDeleteShader(fragment_shader);
    glDeleteProgram(shader_program);

    glDetachShader(compute_program, compute_shader);	
    glDeleteShader(compute_shader);
    glDeleteProgram(compute_program);
    
    glfwCloseWindow();
    glfwTerminate();
    return 0;
}
示例#13
0
int main()
{
    int width = 640;
    int height = 480;

    if(glfwInit() == GL_FALSE)
    {
        std::cerr << "failed to init GLFW" << std::endl;
        return 1;
    }

    // select opengl version
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);

    // create a window
    if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE)
    {
        std::cerr << "failed to open window" << std::endl;
        glfwTerminate();
        return 1;
    }

    // setup windows close callback
    glfwSetWindowCloseCallback(closedWindow);



    if (gl3wInit())
    {
        std::cerr << "failed to init GL3W" << std::endl;
        glfwCloseWindow();
        glfwTerminate();
        return 1;
    }

    // shader source code

    // the vertex shader simply passes through data
    std::string vertex_source =
        "#version 330\n"
        "layout(location = 0) in vec4 vposition;\n"
        "void main() {\n"
        "   gl_Position = vposition;\n"
        "}\n";

    // the geometry shader creates the billboard quads
    std::string geometry_source =
        "#version 330\n"
        "uniform mat4 View;\n"
        "uniform mat4 Projection;\n"
        "layout (points) in;\n"
        "layout (triangle_strip, max_vertices = 4) out;\n"
        "out vec2 txcoord;\n"
        "void main() {\n"
        "   vec4 pos = View*gl_in[0].gl_Position;\n"
        "   txcoord = vec2(-1,-1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1,-1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2(-1, 1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1, 1);\n"
        "   gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "}\n";

    // the fragment shader creates a bell like radial color distribution
    std::string fragment_source =
        "#version 330\n"
        "in vec2 txcoord;\n"
        "layout(location = 0) out vec4 FragColor;\n"
        "void main() {\n"
        "   float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n"
        "   FragColor = s*vec4(0.3,0.3,1.0,1);\n"
        "}\n";

    // program and shader handles
    GLuint shader_program, vertex_shader, geometry_shader, fragment_shader;

    // we need these to properly pass the strings
    const char *source;
    int length;

    // create and compiler vertex shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    source = vertex_source.c_str();
    length = vertex_source.size();
    glShaderSource(vertex_shader, 1, &source, &length);
    glCompileShader(vertex_shader);
    if(!check_shader_compile_status(vertex_shader))
    {
        return 1;
    }

    // create and compiler geometry shader
    geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
    source = geometry_source.c_str();
    length = geometry_source.size();
    glShaderSource(geometry_shader, 1, &source, &length);
    glCompileShader(geometry_shader);
    if(!check_shader_compile_status(geometry_shader))
    {
        return 1;
    }

    // create and compiler fragment shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    source = fragment_source.c_str();
    length = fragment_source.size();
    glShaderSource(fragment_shader, 1, &source, &length);
    glCompileShader(fragment_shader);
    if(!check_shader_compile_status(fragment_shader))
    {
        return 1;
    }

    // create program
    shader_program = glCreateProgram();

    // attach shaders
    glAttachShader(shader_program, vertex_shader);
    glAttachShader(shader_program, geometry_shader);
    glAttachShader(shader_program, fragment_shader);

    // link the program and check for errors
    glLinkProgram(shader_program);
    check_program_link_status(shader_program);

    // obtain location of projection uniform
    GLint View_location = glGetUniformLocation(shader_program, "View");
    GLint Projection_location = glGetUniformLocation(shader_program, "Projection");



    const int particles = 128*1024;

    // randomly place particles in a cube
    std::vector<glm::vec3> vertexData(particles);
    std::vector<glm::vec3> velocity(particles);
    for(int i = 0; i<particles; ++i)
    {
        vertexData[i] = glm::vec3(0.5f-float(std::rand())/RAND_MAX,
                                  0.5f-float(std::rand())/RAND_MAX,
                                  0.5f-float(std::rand())/RAND_MAX);
        vertexData[i] = glm::vec3(0.0f,20.0f,0.0f) + 5.0f*vertexData[i];
    }


    int buffercount = 3;
    // generate vbos and vaos
    GLuint vao[buffercount], vbo[buffercount];
    glGenVertexArrays(buffercount, vao);
    glGenBuffers(buffercount, vbo);

    for(int i = 0; i<buffercount; ++i)
    {
        glBindVertexArray(vao[i]);

        glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);

        // fill with initial data
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertexData.size(), &vertexData[0], GL_DYNAMIC_DRAW);

        // set up generic attrib pointers
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat));
    }

    // "unbind" vao
    glBindVertexArray(0);

    // we are blending so no depth testing
    glDisable(GL_DEPTH_TEST);

    // enable blending
    glEnable(GL_BLEND);
    //  and set the blend function to result = 1*source + 1*destination
    glBlendFunc(GL_ONE, GL_ONE);

    // define spheres for the particles to bounce off
    const int spheres = 3;
    glm::vec3 center[spheres];
    float radius[spheres];
    center[0] = glm::vec3(0,12,1);
    radius[0] = 3;
    center[1] = glm::vec3(-3,0,0);
    radius[1] = 7;
    center[2] = glm::vec3(5,-10,0);
    radius[2] = 12;

    // physical parameters
    float dt = 1.0f/60.0f;
    glm::vec3 g(0.0f, -9.81f, 0.0f);
    float bounce = 1.2f; // inelastic: 1.0f, elastic: 2.0f

    int current_buffer=0;
    running = true;
    while(running)
    {
        // get the time in seconds
        float t = glfwGetTime();

        // terminate on escape
        if(glfwGetKey(GLFW_KEY_ESC))
        {
            running = false;
        }

        // update physics
        for(int i = 0; i<particles; ++i)
        {
            // resolve sphere collisions
            for(int j = 0; j<spheres; ++j)
            {
                glm::vec3 diff = vertexData[i]-center[j];
                float dist = glm::length(diff);
                if(dist<radius[j] && glm::dot(diff, velocity[i])<0.0f)
                    velocity[i] -= bounce*diff/(dist*dist)*glm::dot(diff, velocity[i]);
            }
            // euler iteration
            velocity[i] += dt*g;
            vertexData[i] += dt*velocity[i];
            // reset particles that fall out to a starting position
            if(vertexData[i].y<-30.0)
            {
                vertexData[i] = glm::vec3(
                                    0.5f-float(std::rand())/RAND_MAX,
                                    0.5f-float(std::rand())/RAND_MAX,
                                    0.5f-float(std::rand())/RAND_MAX
                                );
                vertexData[i] = glm::vec3(0.0f,20.0f,0.0f) + 5.0f*vertexData[i];
                velocity[i] = glm::vec3(0,0,0);
            }
        }

        // bind a buffer to upload to
        glBindBuffer(GL_ARRAY_BUFFER, vbo[(current_buffer+buffercount-1)%buffercount]);

        // explicitly invalidate the buffer
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertexData.size(), 0, GL_DYNAMIC_DRAW);

        // map the buffer
        glm::vec3 *mapped =
            reinterpret_cast<glm::vec3*>(
                glMapBufferRange(GL_ARRAY_BUFFER, 0,
                                 sizeof(glm::vec3)*vertexData.size(),
                                 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT
                                )
            );

        // copy data into the mapped memory
        std::copy(vertexData.begin(), vertexData.end(), mapped);

        // unmap the buffer
        glUnmapBuffer(GL_ARRAY_BUFFER);


        // clear first
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // use the shader program
        glUseProgram(shader_program);

        // calculate ViewProjection matrix
        glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f);

        // translate the world/view position
        glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f));

        // make the camera rotate around the origin
        View = glm::rotate(View, 30.0f, glm::vec3(1.0f, 0.0f, 0.0f));
        View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f));

        // set the uniform
        glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View));
        glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection));

        // bind the current vao
        glBindVertexArray(vao[current_buffer]);

        // draw
        glDrawArrays(GL_POINTS, 0, particles);

        // check for errors
        GLenum error = glGetError();
        if(error != GL_NO_ERROR)
        {
            std::cerr << gluErrorString(error);
            running = false;
        }

        // finally swap buffers
        glfwSwapBuffers();

        // advance buffer index
        current_buffer = (current_buffer + 1) % buffercount;
    }

    // delete the created objects

    glDeleteVertexArrays(buffercount, vao);
    glDeleteBuffers(buffercount, vbo);

    glDetachShader(shader_program, vertex_shader);
    glDetachShader(shader_program, geometry_shader);
    glDetachShader(shader_program, fragment_shader);
    glDeleteShader(vertex_shader);
    glDeleteShader(geometry_shader);
    glDeleteShader(fragment_shader);
    glDeleteProgram(shader_program);

    glfwCloseWindow();
    glfwTerminate();
    return 0;
}
int main()
{
    int width = 640;
    int height = 480;
   
    UserData userdata;
    userdata.running = true;
    
    GLWTConfig glwt_config;
    glwt_config.red_bits = 8;
    glwt_config.green_bits = 8;
    glwt_config.blue_bits = 8;
    glwt_config.alpha_bits = 8;
    glwt_config.depth_bits = 24;
    glwt_config.stencil_bits = 8;
    glwt_config.samples = 0;
    glwt_config.sample_buffers = 0;
    glwt_config.api = GLWT_API_OPENGL | GLWT_PROFILE_CORE;
    glwt_config.api_version_major = 3;
    glwt_config.api_version_minor = 3;
    
    GLWTAppCallbacks app_callbacks;
    app_callbacks.error_callback = error_callback;
    app_callbacks.userdata = &userdata;
    
    if(glwtInit(&glwt_config, &app_callbacks) != 0)
    {
        std::cerr << "failed to init GLWT" << std::endl;
        return 1;
    }
 
    GLWTWindowCallbacks win_callbacks;
    win_callbacks.close_callback = close_callback;
    win_callbacks.expose_callback = 0;
    win_callbacks.resize_callback = 0;
    win_callbacks.show_callback = 0;
    win_callbacks.focus_callback = 0;
    win_callbacks.key_callback = key_callback,
    win_callbacks.motion_callback = 0;
    win_callbacks.button_callback = 0;
    win_callbacks.mouseover_callback = 0;
    win_callbacks.userdata = &userdata;
    
    // create a window
    GLWTWindow *window = glwtWindowCreate("", width, height, &win_callbacks, 0);
    if(window == 0)
    {
        std::cerr << "failed to open window" << std::endl;
        glwtQuit();
        return 1;
    }
    
    if (glxwInit())
    {
        std::cerr << "failed to init GLXW" << std::endl;
        glwtWindowDestroy(window);
        glwtQuit();
        return 1;
    }
    
    glwtWindowShow(window, 1);
    glwtMakeCurrent(window);
    glwtSwapInterval(window, 1);

    // shader source code
    
    // the vertex shader simply passes through data
    std::string vertex_source =
        "#version 330\n"
        "layout(location = 0) in vec4 vposition;\n"
        "void main() {\n"
        "   gl_Position = vposition;\n"
        "}\n";

    // the geometry shader creates the billboard quads
    std::string geometry_source =
        "#version 330\n"
        "uniform mat4 View;\n"
        "uniform mat4 Projection;\n"
        "layout (points) in;\n"
        "layout (triangle_strip, max_vertices = 4) out;\n"
        "out vec2 txcoord;\n"
        "void main() {\n"
        "   vec4 pos = View*gl_in[0].gl_Position;\n"
        "   txcoord = vec2(-1,-1);\n"
        "   gl_Position = Projection*(pos+vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1,-1);\n"
        "   gl_Position = Projection*(pos+vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2(-1, 1);\n"
        "   gl_Position = Projection*(pos+vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "   txcoord = vec2( 1, 1);\n"
        "   gl_Position = Projection*(pos+vec4(txcoord,0,0));\n"
        "   EmitVertex();\n"
        "}\n";    
    
    // the fragment shader creates a bell like radial color distribution    
    std::string fragment_source =
        "#version 330\n"
        "in vec2 txcoord;\n"
        "layout(location = 0) out vec4 FragColor;\n"
        "void main() {\n"
        "   float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n"
        "   FragColor = s*vec4(1,0.9,0.6,1);\n"
        "}\n";
   
    // program and shader handles
    GLuint shader_program, vertex_shader, geometry_shader, fragment_shader;
    
    // we need these to properly pass the strings
    const char *source;
    int length;

    // create and compiler vertex shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    source = vertex_source.c_str();
    length = vertex_source.size();
    glShaderSource(vertex_shader, 1, &source, &length); 
    glCompileShader(vertex_shader);
    if(!check_shader_compile_status(vertex_shader))
    {
        return 1;
    }
    
    // create and compiler geometry shader
    geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
    source = geometry_source.c_str();
    length = geometry_source.size();
    glShaderSource(geometry_shader, 1, &source, &length); 
    glCompileShader(geometry_shader);
    if(!check_shader_compile_status(geometry_shader))
    {
        return 1;
    }
 
    // create and compiler fragment shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    source = fragment_source.c_str();
    length = fragment_source.size();
    glShaderSource(fragment_shader, 1, &source, &length);   
    glCompileShader(fragment_shader);
    if(!check_shader_compile_status(fragment_shader))
    {
        return 1;
    }
    
    // create program
    shader_program = glCreateProgram();
    
    // attach shaders
    glAttachShader(shader_program, vertex_shader);
    glAttachShader(shader_program, geometry_shader);
    glAttachShader(shader_program, fragment_shader);
    
    // link the program and check for errors
    glLinkProgram(shader_program);
    check_program_link_status(shader_program);
    
    // obtain location of projection uniform
    GLint View_location = glGetUniformLocation(shader_program, "View");
    GLint Projection_location = glGetUniformLocation(shader_program, "Projection");
    
    
    // vao and vbo handle
    GLuint vao, vbo;
 
    // generate and bind the vao
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    
    // generate and bind the vertex buffer object
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    
    const int particles = 128*1024;

    // create a galaxylike distribution of points
    std::vector<GLfloat> vertexData(particles*3);
    for(int i = 0;i<particles;++i)
    {
        int arm = 3*(std::rand()/float(RAND_MAX));
        float alpha = 1/(0.1f+std::pow(std::rand()/float(RAND_MAX),0.7f))-1/1.1f;
        float r = 4.0f*alpha;
        alpha += arm*2.0f*3.1416f/3.0f;
        
        vertexData[3*i+0] = r*std::sin(alpha);
        vertexData[3*i+1] = 0;
        vertexData[3*i+2] = r*std::cos(alpha);
        
        vertexData[3*i+0] += (4.0f-0.2*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+
                                                  std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)));
        vertexData[3*i+1] += (2.0f-0.1*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+
                                                  std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)));
        vertexData[3*i+2] += (4.0f-0.2*alpha)*(2-(std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)+
                                                  std::rand()/float(RAND_MAX)+std::rand()/float(RAND_MAX)));
    }

    // fill with data
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*vertexData.size(), &vertexData[0], GL_STATIC_DRAW);
                    
           
    // set up generic attrib pointers
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat));
 
    
    // "unbind" vao
    glBindVertexArray(0);

    
    // we are blending so no depth testing
    glDisable(GL_DEPTH_TEST);
    
    // enable blending
    glEnable(GL_BLEND);
    //  and set the blend function to result = 1*source + 1*destination
    glBlendFunc(GL_ONE, GL_ONE);

    while(userdata.running)
    {   
        // get the time in seconds
        float t = glwtGetNanoTime()*1.e-9f;
        
        // update events
        glwtEventHandle(0);
        
        // clear first
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // use the shader program
        glUseProgram(shader_program);
        
        // calculate ViewProjection matrix
        glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f);
        
        // translate the world/view position
        glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -50.0f));
        
        // make the camera rotate around the origin
        View = glm::rotate(View, 30.0f*std::sin(0.1f*t), glm::vec3(1.0f, 0.0f, 0.0f)); 
        View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f)); 
        
        
        // set the uniform
        glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View)); 
        glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection)); 
        
        // bind the vao
        glBindVertexArray(vao);

        // draw
        glDrawArrays(GL_POINTS, 0, particles);
       
        // check for errors
        GLenum error = glGetError();
        if(error != GL_NO_ERROR)
        {
            userdata.running = false;       
        }
        
        // finally swap buffers
        glwtSwapBuffers(window);       
    }
    
    // delete the created objects
        
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    
    glDetachShader(shader_program, vertex_shader);	
    glDetachShader(shader_program, geometry_shader);	
    glDetachShader(shader_program, fragment_shader);
    glDeleteShader(vertex_shader);
    glDeleteShader(geometry_shader);
    glDeleteShader(fragment_shader);
    glDeleteProgram(shader_program);
    
    glwtWindowDestroy(window);
    glwtQuit();
    return 0;
}
void Terrain::InitVB(ID3D11Device* device)
{
	std::vector<Vertex::TerrainVertex> vertexData(mTerrainData.width *
		mTerrainData.height);

	UINT cellsWide = mTerrainData.width - 1;
	UINT cellsHigh = mTerrainData.height - 1;

	for (int row = 0; row < mTerrainData.height; ++row)
	{
		for (int col = 0; col < mTerrainData.width; ++col)
		{
			UINT index = row * mTerrainData.width + col;
			vertexData[index].pos = XMFLOAT3(col * mTerrainData.cellWidth,
				mHeightMap[index],
				row * mTerrainData.cellHeight);

			float u = mTerrainData.texTilesWide / mTerrainData.width;
			u *= col;

			float v = mTerrainData.texTilesHigh / mTerrainData.height;
			v *= row;

			vertexData[index].tiledTex.x = u;
			vertexData[index].tiledTex.y = v;

			u = (float)col / (mTerrainData.width - 1);
			v = (float)row / (mTerrainData.height - 1);

			vertexData[index].tex.x = u;
			vertexData[index].tex.y = v;

		}
	}

	std::vector<XMFLOAT3> normals;
	for (int row = 0; row < cellsHigh; ++row)
	{
		for (int col = 0; col < cellsWide; ++col)
		{
			//determine the row and column in terms of vertices given the 
			//cell row and column
			UINT top = row + 1;
			UINT right = col + 1;
			UINT bot = row;
			UINT left = col;

			XMVECTOR A = XMVectorSet(0.0f, mHeightMap[top * mTerrainData.width + left] -
				mHeightMap[bot * mTerrainData.width + left], mTerrainData.cellHeight, 0.0f);

			XMVECTOR B = XMVectorSet(mTerrainData.cellWidth, mHeightMap[bot * mTerrainData.width + right] -
				mHeightMap[bot * mTerrainData.width + left], 0.0f, 0.0f);

			XMVECTOR C = XMVectorSet(mTerrainData.cellWidth, mHeightMap[top * mTerrainData.width + right] -
				mHeightMap[top * mTerrainData.width + left], 0.0f, 0.0f);

			XMVECTOR D = XMVectorSet(0.0f, mHeightMap[top * mTerrainData.width + right] -
				mHeightMap[bot * mTerrainData.width + right], mTerrainData.cellHeight, 0.0f);

			XMVECTOR topNormal = XMVector3Cross(D, C);

			XMVECTOR botNormal = XMVector3Cross(A, B);

			topNormal = XMVector3Normalize(topNormal);
			botNormal = XMVector3Normalize(botNormal);

			XMFLOAT3 topNormalF3, botNormalF3;

			XMStoreFloat3(&topNormalF3, topNormal);
			XMStoreFloat3(&botNormalF3, botNormal);

			normals.push_back(topNormalF3);
			normals.push_back(botNormalF3);
		}
	}

	for (int row = 0; row < mTerrainData.height; ++row)
	{
		for (int col = 0; col < mTerrainData.width; ++col)
		{
			UINT index = row * mTerrainData.width + col;

			int top = row;
			int bot = row - 1;
			int left = col - 1;
			int right = col;

			int normalCounter = 0;
			XMVECTOR normsCombined = XMVectorZero();
			//get the two top left normals
			if (top < cellsHigh && left >= 0)
			{
				UINT topLeftIndex = (top * cellsWide + left) * 2;

				normsCombined = normsCombined + XMLoadFloat3(&normals[topLeftIndex]);
				normsCombined = normsCombined + XMLoadFloat3(&normals[topLeftIndex + 1]);
				normalCounter += 2;
			}

			//get the bottom left normal
			if (bot >= 0 && left >= 0)
			{
				UINT botLeftIndex = (bot * cellsWide + left) * 2;

				normsCombined = normsCombined + XMLoadFloat3(&normals[botLeftIndex]);
				normalCounter++;
			}

			//get the top right normal
			if (top < cellsHigh && right < cellsWide)
			{
				UINT topRightIndex = (top * cellsWide + right) * 2;

				normsCombined = normsCombined + XMLoadFloat3(&normals[topRightIndex]);
				normalCounter++;
			}

			//get the two bot right normals
			if (bot >= 0 && right < cellsWide)
			{
				UINT botRightIndex = (bot * cellsWide + right) * 2;

				normsCombined = normsCombined + XMLoadFloat3(&normals[botRightIndex]);
				normsCombined = normsCombined + XMLoadFloat3(&normals[botRightIndex + 1]);
				normalCounter += 2;
			}

			normsCombined = normsCombined / (float)normalCounter;
			XMStoreFloat3(&(vertexData[index].normal), normsCombined);
		}
	}

	D3D11_BUFFER_DESC vbd;
	vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::TerrainVertex) * vertexData.size();
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vbd.CPUAccessFlags = 0;
	vbd.MiscFlags = 0;
	vbd.StructureByteStride = 0;

	D3D11_SUBRESOURCE_DATA vinitData;
	vinitData.pSysMem = &vertexData[0];
	HR(device->CreateBuffer(&vbd, &vinitData, &mVB));

}
    v[3].set(itemCenter, verticalCenter, +1.0f, currentY);
    usedVertices += 4;
}

void BindlingLoopsGeometry::addCollapsedEvent(float horizontalCenterSource,
                                              float horizontalCenterTarget,
                                              float verticalCenterSource,
                                              float verticalCenterTarget)
{
    // The source event should always be above the parent event because ranges are perfectly nested
    // and events are ordered by start time.
    QTC_ASSERT(verticalCenterSource > verticalCenterTarget, /**/);

    float tilt = horizontalCenterSource < horizontalCenterTarget ? +0.3f : -0.3f;

    Point2DWithOffset *v = vertexData() + usedVertices;
    v[0].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[1].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[2].set(horizontalCenterSource, verticalCenterSource, +0.3f, -tilt);

    v[3].set(horizontalCenterTarget, verticalCenterTarget, -0.3f, tilt);
    v[4].set(horizontalCenterTarget, verticalCenterTarget, +0.3f, -tilt);
    v[5].set(horizontalCenterTarget, verticalCenterTarget, -1.0f, -1.0f);
    v[6].set(horizontalCenterTarget, verticalCenterTarget, +1.0f, -1.0f);
    v[7].set(horizontalCenterTarget, verticalCenterTarget, -1.0f, +1.0f);
    v[8].set(horizontalCenterTarget, verticalCenterTarget, +1.0f, +1.0f);
    v[9].set(horizontalCenterTarget, verticalCenterTarget, -0.3f, tilt);
    v[10].set(horizontalCenterTarget, verticalCenterTarget, +0.3f, -tilt);

    v[11].set(horizontalCenterSource, verticalCenterSource, -0.3f, tilt);
    v[12].set(horizontalCenterSource, verticalCenterSource, +0.3f, -tilt);
示例#17
0
	void StaticMesh::Create(const char* fileName)
	{
		char baseDir[256];
		char fileNameWoExt[256];
		char tempPath[256];
		_splitpath_s(fileName, nullptr, 0, baseDir, sizeof(baseDir), fileNameWoExt, sizeof(baseDir), nullptr, 0);

		// キャッシュファイル名
		snprintf(tempPath, sizeof(tempPath), "%s%s.cache", baseDir, fileNameWoExt);
		std::ifstream cacheFile(tempPath, std::ios::in | std::ios::binary);
		if (cacheFile) {
			/** キャッシュから読み込み **/

			// ファイル全体をリード
			cacheFile.seekg(0, std::fstream::end);
			uint32_t eofPos = (uint32_t)cacheFile.tellg();
			cacheFile.clear();
			cacheFile.seekg(0, std::fstream::beg);
			uint32_t begPos = (uint32_t)cacheFile.tellg();
			uint32_t size = eofPos - begPos;
			std::unique_ptr<uint8_t> cacheData(new uint8_t[size]);
			cacheFile.read((char*)cacheData.get(), size);

			// パース
			const CacheHeader* header = (CacheHeader*)cacheData.get();
			const Shape* shapes = (Shape*)(cacheData.get() + header->offsetToShapes);
			shapes_.resize(header->shapeNum);
			memcpy(&shapes_[0], shapes, sizeof(Shape) * header->shapeNum);

			uint32_t vtxStride = ComputeVertexStride(header->vertexAttrs);
			vertexBuffer_.Create(cacheData.get() + header->offsetToVertices, vtxStride * header->vertexNum, header->vertexAttrs);
			indexBuffer_.Create(cacheData.get() + header->offsetToIndeces, sizeof(uint32_t) * header->vertexNum, INDEX_BUFFER_STRIDE_U32);

			const char* materials = (const char*)(cacheData.get() + header->offsetToMaterial);
			materials_.resize(header->materialNum);
			std::unordered_map<std::string, uint32_t> textureMap;
			for (size_t i = 0; i < (uint32_t)materials_.size(); i++) {
				const char* m = materials + (256 * i);
				ZeroMemory(&materials_[i], sizeof(materials_[i]));

				// テクスチャ検索
				if (strlen(m) > 0) {
					Texture* texture = nullptr;
					auto iter = textureMap.find(m);
					if (iter != textureMap.end()) {
						texture = textures_[iter->second];
					} else {
						texture = new Texture();
						snprintf(tempPath, sizeof(tempPath), "%s%s", baseDir, m);
						texture->LoadFromFile(tempPath);
						textures_.push_back(texture);
						uint32_t index = (uint32_t)textures_.size() - 1;
						textureMap[m] = index;

					}
					materials_[i].albedo = texture;
				}
			}
		} else {
			/** キャッシュがなかったらobjを読み込み **/
			tinyobj::attrib_t attrib;
			std::vector<tinyobj::shape_t> shapes;
			std::vector<tinyobj::material_t> materials;

			Printf("Loading %s\n", fileName);
			std::string err;
			if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, fileName, baseDir, true)) {
				if (!err.empty()) {
					Printf(err.c_str());
				}
				Printf("Failed to load/parse .obj.\n");
				return;
			}
			//Printf("# of vertices  : %d\n", (attrib.vertices.size() / 3));
			//Printf("# of normals   : %d\n", (attrib.normals.size() / 3));
			//Printf("# of texcoords : %d\n", (attrib.texcoords.size() / 2));
			//Printf("# of shapes    : %d\n", shapes.size());
			//Printf("# of materials : %d\n", materials.size());

			// 現状はすべてのシェイプで頂点構造が一致している前提で処理しているため1つの頂点バッファにすべて入っている
			// TODO:tangent, bitangent計算
			uint32_t vtxAttrs = VERTEX_ATTR_FLAG_POSITION;
			vtxAttrs |= (attrib.normals.size() > 0) ? VERTEX_ATTR_FLAG_NORMAL : 0;
			vtxAttrs |= (attrib.texcoords.size() > 0) ? VERTEX_ATTR_FLAG_TEXCOORD0 : 0;
			uint32_t vtxStride = ComputeVertexStride(vtxAttrs);

			// 全インデックス数を計算
			uint32_t totalIndexNum = 0;
			for (auto& shape : shapes) {
				totalIndexNum += static_cast<uint32_t>(shape.mesh.indices.size());
			}

			// 頂点をインデックス展開するためトータルインデックス数分の頂点バッファを確保
			std::unique_ptr<uint8_t> vertexData(new uint8_t[vtxStride * totalIndexNum]);
			std::unique_ptr<uint8_t> indexData(new uint8_t[sizeof(uint32_t) * totalIndexNum]);
			uint32_t currentIndex = 0;
			uint32_t* currentIndexBufferPtr = reinterpret_cast<uint32_t*>(indexData.get());
			for (uint32_t i = 0; i < shapes.size(); i++) {
				auto& shape = shapes[i];
				Assert(shape.mesh.num_face_vertices.size() == shape.mesh.material_ids.size());

				// For each face
				uint32_t currentMaterial = 0xffffffff;
				Shape currentShape;
				for (size_t f = 0; f < shape.mesh.num_face_vertices.size(); f++) {
					Assert(shape.mesh.num_face_vertices[f] == 3);	// 三角形化済みのはず

					// マテリアルの切り替わり判定
					if (currentMaterial != shape.mesh.material_ids[f]) {
						if (currentMaterial != 0xffffffff) {
							currentShape.indexCount = currentIndex - currentShape.indexStart;
							shapes_.push_back(currentShape);
						}
						currentMaterial = shape.mesh.material_ids[f];
						currentShape.materialIndex = currentMaterial;
						currentShape.indexStart = currentIndex;
						currentShape.indexCount = 0;
					}

					// For each vertex in the face
					uint32_t ptrOffset = 0;
					uint8_t* currentVertexBufferPtr = vertexData.get() + (vtxStride * currentIndex);
					for (size_t v = 0; v < 3; v++) {
						tinyobj::index_t idx = shape.mesh.indices[(f * 3) + v];

						// position
						memcpy(currentVertexBufferPtr + ptrOffset, &attrib.vertices[idx.vertex_index * 3], 12);
						ptrOffset += 12;

						// normal
						if (vtxAttrs & VERTEX_ATTR_FLAG_NORMAL) {
							memcpy(currentVertexBufferPtr + ptrOffset, &attrib.normals[idx.normal_index * 3], 12);
							ptrOffset += 12;
						}

						// texcoord
						if (vtxAttrs & VERTEX_ATTR_FLAG_TEXCOORD0) {
							float2* uv = reinterpret_cast<float2*>(currentVertexBufferPtr + ptrOffset);
							uv->x = attrib.texcoords[idx.texcoord_index * 2 + 0];
							uv->y = 1.0f - attrib.texcoords[idx.texcoord_index * 2 + 1]; // OpenGL -> DirectX
							ptrOffset += 8;
						}

						currentIndexBufferPtr[currentIndex] = currentIndex;
						currentIndex++;
					}
				}

				// 最後のマテリアル分追加
				currentShape.indexCount = currentIndex - currentShape.indexStart;
				shapes_.push_back(currentShape);
			}

			vertexBuffer_.Create(vertexData.get(), vtxStride * totalIndexNum, vtxAttrs);
			indexBuffer_.Create(indexData.get(), sizeof(uint32_t) * totalIndexNum, INDEX_BUFFER_STRIDE_U32);

			// マテリアル
			materials_.resize(materials.size());
			std::unordered_map<std::string, uint32_t> textureMap;
			for (size_t i = 0; i < (uint32_t)materials_.size(); i++) {
				auto& m = materials[i];
				ZeroMemory(&materials_[i], sizeof(materials_[i]));

				// テクスチャ検索
				if (m.diffuse_texname.size() > 0) {
					Texture* texture = nullptr;
					auto iter = textureMap.find(m.diffuse_texname);
					if (iter != textureMap.end()) {
						texture = textures_[iter->second];
					} else {
						texture = new Texture();
						snprintf(tempPath, sizeof(tempPath), "%s%s", baseDir, m.diffuse_texname.c_str());
						texture->LoadFromFile(tempPath);
						textures_.push_back(texture);
						uint32_t index = (uint32_t)textures_.size() - 1;
						textureMap[m.diffuse_texname] = index;

					}
					materials_[i].albedo = texture;
				}
			}

			// 読み込み高速化のためのキャッシュデータを生成
			{
				snprintf(tempPath, sizeof(tempPath), "%s%s.cache", baseDir, fileNameWoExt);
				std::ofstream file(tempPath, std::ios::out | std::ios::binary);

				CacheHeader header;
				header.shapeNum = (uint16_t)shapes_.size();
				header.materialNum = (uint16_t)materials_.size();
				header.vertexAttrs = (uint16_t)vtxAttrs;
				header.vertexNum = totalIndexNum;
				header.offsetToShapes = sizeof(CacheHeader);
				header.offsetToVertices = header.offsetToShapes + sizeof(Shape) * header.shapeNum;
				header.offsetToIndeces = header.offsetToVertices + (vtxStride * totalIndexNum);
				header.offsetToMaterial = header.offsetToIndeces + (sizeof(uint32_t) * totalIndexNum);
				file.write((char*)&header, sizeof(header));

				// シェイプ
				for (auto& s : shapes_) {
					file.write((char*)&s, sizeof(s));
				}
				// 頂点
				file.write((char*)vertexData.get(), vtxStride * totalIndexNum);
				// インデックス
				file.write((char*)indexData.get(), sizeof(uint32_t) * totalIndexNum);
				// マテリアル
				for (auto& m : materials) {
					FillMemory(tempPath, sizeof(tempPath), 0);
					snprintf(tempPath, sizeof(tempPath), "%s", m.diffuse_texname.c_str());
					file.write(tempPath, sizeof(tempPath));
				}
			}
		}
	}