зеркало из https://github.com/AvaloniaUI/angle.git
Port the ParticleSystem sample to the new sample framework.
BUG=angle:521 Change-Id: I6d00333ac7761f15ee83a47dc3e6e3cc13c675cd Reviewed-on: https://chromium-review.googlesource.com/188195 Reviewed-by: Shannon Woods <shannonwoods@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Tested-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
6e05c2724d
Коммит
d19fae55ea
|
@ -86,7 +86,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_texture", "..\samples
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "particle_system", "..\samples\particle_system.vcxproj", "{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{80E5C3D9-93C2-943E-176F-C9A903E27BC9} = {80E5C3D9-93C2-943E-176F-C9A903E27BC9}
|
||||
{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
|
||||
{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
|
||||
{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
|
||||
EndProjectSection
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\samples\gles2_book\Common;..\..\include;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4530;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4201;4100;4127;4189;4239;4244;4245;4512;4702;4530;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<Optimization>Disabled</Optimization>
|
||||
|
@ -67,17 +67,17 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\samples\gles2_book\Common;..\..\include;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\samples\gles2_book\Common;..\..\include;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4530;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4201;4100;4127;4189;4239;4244;4245;4512;4702;4530;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
|
@ -102,7 +102,7 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\..\samples\gles2_book\Common;..\..\include;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\samples\angle\sample_util;C:\Program Files (x86)\Windows Kits\8.0\Include\shared;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -110,19 +110,19 @@
|
|||
<None Include="..\..\samples\samples.gyp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\samples\gles2_book\ParticleSystem\ParticleSystem.c"/>
|
||||
<ClCompile Include="..\..\samples\angle\particle_system\ParticleSystem.cpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\samples\gles2_book\ParticleSystem\smoke.tga">
|
||||
<CustomBuild Include="..\..\samples\angle\particle_system\smoke.tga">
|
||||
<FileType>Document</FileType>
|
||||
<Command>call mkdir "$(OutDir)" 2>nul & set ERRORLEVEL=0 & copy /Y "..\..\samples\gles2_book\ParticleSystem\smoke.tga" "$(OutDir)smoke.tga"</Command>
|
||||
<Message>Copying gles2_book/ParticleSystem/smoke.tga to $(OutDir)\smoke.tga</Message>
|
||||
<Command>call mkdir "$(OutDir)" 2>nul & set ERRORLEVEL=0 & copy /Y "..\..\samples\angle\particle_system\smoke.tga" "$(OutDir)smoke.tga"</Command>
|
||||
<Message>Copying angle/particle_system/smoke.tga to $(OutDir)\smoke.tga</Message>
|
||||
<Outputs>$(OutDir)\smoke.tga</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="es_util.vcxproj">
|
||||
<Project>{80E5C3D9-93C2-943E-176F-C9A903E27BC9}</Project>
|
||||
<ProjectReference Include="sample_util.vcxproj">
|
||||
<Project>{297C46B0-9263-A9EA-82B1-EA221E7D7C7F}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\src\libEGL.vcxproj">
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="gles2_book">
|
||||
<UniqueIdentifier>{01DCD872-C931-E1FA-4F9F-EBFA79587BB6}</UniqueIdentifier>
|
||||
<Filter Include="angle">
|
||||
<UniqueIdentifier>{2039F76D-4C9A-B8A0-444A-4766C6F6104A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="gles2_book\ParticleSystem">
|
||||
<UniqueIdentifier>{05979F6F-F708-2C87-17F3-3B3AA4892DDF}</UniqueIdentifier>
|
||||
<Filter Include="angle\particle_system">
|
||||
<UniqueIdentifier>{BF3D6113-EF81-F63D-D06D-FD080BFBE471}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\samples\samples.gyp"/>
|
||||
<ClCompile Include="..\..\samples\gles2_book\ParticleSystem\ParticleSystem.c">
|
||||
<Filter>gles2_book\ParticleSystem</Filter>
|
||||
<ClCompile Include="..\..\samples\angle\particle_system\ParticleSystem.cpp">
|
||||
<Filter>angle\particle_system</Filter>
|
||||
</ClCompile>
|
||||
<None Include="..\..\samples\gles2_book\ParticleSystem\smoke.tga">
|
||||
<Filter>gles2_book\ParticleSystem</Filter>
|
||||
<None Include="..\..\samples\angle\particle_system\smoke.tga">
|
||||
<Filter>angle\particle_system</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -61,7 +61,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_texture", "multi_text
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "particle_system", "particle_system.vcxproj", "{8C20B90A-FBCB-B63F-435A-3299A1C38B2C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{80E5C3D9-93C2-943E-176F-C9A903E27BC9} = {80E5C3D9-93C2-943E-176F-C9A903E27BC9}
|
||||
{297C46B0-9263-A9EA-82B1-EA221E7D7C7F} = {297C46B0-9263-A9EA-82B1-EA221E7D7C7F}
|
||||
{FBAEE4F6-562A-588F-01F9-72DCABB3B061} = {FBAEE4F6-562A-588F-01F9-72DCABB3B061}
|
||||
{7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81} = {7FBD6F69-B9A4-69F1-A12B-8DACB3F8CD81}
|
||||
EndProjectSection
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Based on ParticleSystem.c from
|
||||
// Book: OpenGL(R) ES 2.0 Programming Guide
|
||||
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
|
||||
// ISBN-10: 0321502795
|
||||
// ISBN-13: 9780321502797
|
||||
// Publisher: Addison-Wesley Professional
|
||||
// URLs: http://safari.informit.com/9780321563835
|
||||
// http://www.opengles-book.com
|
||||
|
||||
#include "SampleApplication.h"
|
||||
#include "Vector.h"
|
||||
#include "shader_utils.h"
|
||||
#include "random_utils.h"
|
||||
#include "tga_utils.h"
|
||||
#include "path_utils.h"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
class ParticleSystemSample : public SampleApplication
|
||||
{
|
||||
public:
|
||||
ParticleSystemSample::ParticleSystemSample()
|
||||
: SampleApplication("ParticleSystem", 1280, 720)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool initialize()
|
||||
{
|
||||
const std::string vs = SHADER_SOURCE
|
||||
(
|
||||
uniform float u_time;
|
||||
uniform vec3 u_centerPosition;
|
||||
attribute float a_lifetime;
|
||||
attribute vec3 a_startPosition;
|
||||
attribute vec3 a_endPosition;
|
||||
varying float v_lifetime;
|
||||
void main()
|
||||
{
|
||||
if (u_time <= a_lifetime)
|
||||
{
|
||||
gl_Position.xyz = a_startPosition + (u_time * a_endPosition);
|
||||
gl_Position.xyz += u_centerPosition;
|
||||
gl_Position.w = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_Position = vec4(-1000, -1000, 0, 0);
|
||||
}
|
||||
v_lifetime = 1.0 - (u_time / a_lifetime);
|
||||
v_lifetime = clamp(v_lifetime, 0.0, 1.0);
|
||||
gl_PointSize = (v_lifetime * v_lifetime) * 40.0;
|
||||
}
|
||||
);
|
||||
|
||||
const std::string fs = SHADER_SOURCE
|
||||
(
|
||||
precision mediump float;
|
||||
uniform vec4 u_color;
|
||||
varying float v_lifetime;
|
||||
uniform sampler2D s_texture;
|
||||
void main()
|
||||
{
|
||||
vec4 texColor;
|
||||
texColor = texture2D(s_texture, gl_PointCoord);
|
||||
gl_FragColor = vec4(u_color) * texColor;
|
||||
gl_FragColor.a *= v_lifetime;
|
||||
}
|
||||
);
|
||||
|
||||
mProgram = CompileProgram(vs, fs);
|
||||
if (!mProgram)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the attribute locations
|
||||
mLifetimeLoc = glGetAttribLocation(mProgram, "a_lifetime");
|
||||
mStartPositionLoc = glGetAttribLocation(mProgram, "a_startPosition");
|
||||
mEndPositionLoc = glGetAttribLocation(mProgram, "a_endPosition");
|
||||
|
||||
// Get the uniform locations
|
||||
mTimeLoc = glGetUniformLocation(mProgram, "u_time");
|
||||
mCenterPositionLoc = glGetUniformLocation(mProgram, "u_centerPosition");
|
||||
mColorLoc = glGetUniformLocation(mProgram, "u_color");
|
||||
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Fill in particle data array
|
||||
for (size_t i = 0; i < mParticleCount; i++)
|
||||
{
|
||||
mParticles[i].lifetime = RandomBetween(0.0f, 1.0f);
|
||||
|
||||
float endAngle = RandomBetween(0, 2.0f * float(M_PI));
|
||||
float endRadius = RandomBetween(0.0f, 2.0f);
|
||||
mParticles[i].endPosition.x = sinf(endAngle) * endRadius;
|
||||
mParticles[i].endPosition.y = cosf(endAngle) * endRadius;
|
||||
mParticles[i].endPosition.z = 0.0f;
|
||||
|
||||
float startAngle = RandomBetween(0, 2.0f * float(M_PI));
|
||||
float startRadius = RandomBetween(0.0f, 0.25f);
|
||||
mParticles[i].startPosition.x = sinf(startAngle) * startRadius;
|
||||
mParticles[i].startPosition.y = cosf(startAngle) * startRadius;
|
||||
mParticles[i].startPosition.z = 0.0f;
|
||||
}
|
||||
|
||||
mParticleTime = 1.0f;
|
||||
|
||||
TGAImage img;
|
||||
if (!LoadTGAImageFromFile(GetExecutableDirectory() + "/smoke.tga", &img))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mTextureID = LoadTextureFromTGAImage(img);
|
||||
if (!mTextureID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void destroy()
|
||||
{
|
||||
glDeleteProgram(mProgram);
|
||||
}
|
||||
|
||||
virtual void step(float dt, double totalTime)
|
||||
{
|
||||
// Use the program object
|
||||
glUseProgram(mProgram);
|
||||
|
||||
mParticleTime += dt;
|
||||
if (mParticleTime >= 1.0f)
|
||||
{
|
||||
mParticleTime = 0.0f;
|
||||
|
||||
// Pick a new start location and color
|
||||
Vector3 centerPos(RandomBetween(-0.5f, 0.5f),
|
||||
RandomBetween(-0.5f, 0.5f),
|
||||
RandomBetween(-0.5f, 0.5f));
|
||||
glUniform3fv(mCenterPositionLoc, 1, centerPos.data);
|
||||
|
||||
// Random color
|
||||
Vector4 color(RandomBetween(0.0f, 1.0f),
|
||||
RandomBetween(0.0f, 1.0f),
|
||||
RandomBetween(0.0f, 1.0f),
|
||||
0.5f);
|
||||
glUniform4fv(mColorLoc, 1, color.data);
|
||||
}
|
||||
|
||||
// Load uniform time variable
|
||||
glUniform1f(mTimeLoc, mParticleTime);
|
||||
}
|
||||
|
||||
virtual void draw()
|
||||
{
|
||||
// Set the viewport
|
||||
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
|
||||
|
||||
// Clear the color buffer
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Use the program object
|
||||
glUseProgram(mProgram);
|
||||
|
||||
// Load the vertex attributes
|
||||
glVertexAttribPointer(mLifetimeLoc, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), &mParticles[0].lifetime);
|
||||
glVertexAttribPointer(mEndPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), &mParticles[0].endPosition);
|
||||
glVertexAttribPointer(mStartPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), &mParticles[0].startPosition);
|
||||
|
||||
glEnableVertexAttribArray(mLifetimeLoc);
|
||||
glEnableVertexAttribArray(mEndPositionLoc);
|
||||
glEnableVertexAttribArray(mStartPositionLoc);
|
||||
|
||||
// Blend particles
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
// Bind the texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
// Set the sampler texture unit to 0
|
||||
glUniform1i(mSamplerLoc, 0);
|
||||
|
||||
glDrawArrays(GL_POINTS, 0, mParticleCount);
|
||||
}
|
||||
|
||||
private:
|
||||
// Handle to a program object
|
||||
GLuint mProgram;
|
||||
|
||||
// Attribute locations
|
||||
GLint mLifetimeLoc;
|
||||
GLint mStartPositionLoc;
|
||||
GLint mEndPositionLoc;
|
||||
|
||||
// Uniform location
|
||||
GLint mTimeLoc;
|
||||
GLint mColorLoc;
|
||||
GLint mCenterPositionLoc;
|
||||
GLint mSamplerLoc;
|
||||
|
||||
// Texture handle
|
||||
GLuint mTextureID;
|
||||
|
||||
// Particle vertex data
|
||||
struct Particle
|
||||
{
|
||||
float lifetime;
|
||||
Vector3 startPosition;
|
||||
Vector3 endPosition;
|
||||
};
|
||||
static const size_t mParticleCount = 1024;
|
||||
std::array<Particle, mParticleCount> mParticles;
|
||||
float mParticleTime;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ParticleSystemSample app;
|
||||
return app.run();
|
||||
}
|
До Ширина: | Высота: | Размер: 48 KiB После Ширина: | Высота: | Размер: 48 KiB |
|
@ -1,294 +0,0 @@
|
|||
//
|
||||
// Book: OpenGL(R) ES 2.0 Programming Guide
|
||||
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
|
||||
// ISBN-10: 0321502795
|
||||
// ISBN-13: 9780321502797
|
||||
// Publisher: Addison-Wesley Professional
|
||||
// URLs: http://safari.informit.com/9780321563835
|
||||
// http://www.opengles-book.com
|
||||
//
|
||||
|
||||
// ParticleSystem.c
|
||||
//
|
||||
// This is an example that demonstrates rendering a particle system
|
||||
// using a vertex shader and point sprites.
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "esUtil.h"
|
||||
|
||||
#define NUM_PARTICLES 1000
|
||||
#define PARTICLE_SIZE 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Handle to a program object
|
||||
GLuint programObject;
|
||||
|
||||
// Attribute locations
|
||||
GLint lifetimeLoc;
|
||||
GLint startPositionLoc;
|
||||
GLint endPositionLoc;
|
||||
|
||||
// Uniform location
|
||||
GLint timeLoc;
|
||||
GLint colorLoc;
|
||||
GLint centerPositionLoc;
|
||||
GLint samplerLoc;
|
||||
|
||||
// Texture handle
|
||||
GLuint textureId;
|
||||
|
||||
// Particle vertex data
|
||||
float particleData[ NUM_PARTICLES * PARTICLE_SIZE ];
|
||||
|
||||
// Current time
|
||||
float time;
|
||||
|
||||
} UserData;
|
||||
|
||||
///
|
||||
// Load texture from disk
|
||||
//
|
||||
GLuint LoadTexture ( char *fileName )
|
||||
{
|
||||
int width,
|
||||
height;
|
||||
char *buffer = esLoadTGA ( fileName, &width, &height );
|
||||
GLuint texId;
|
||||
|
||||
if ( buffer == NULL )
|
||||
{
|
||||
esLogMessage ( "Error loading (%s) image.\n", fileName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
glGenTextures ( 1, &texId );
|
||||
glBindTexture ( GL_TEXTURE_2D, texId );
|
||||
|
||||
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer );
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||
|
||||
free ( buffer );
|
||||
|
||||
return texId;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
// Initialize the shader and program object
|
||||
//
|
||||
int Init ( ESContext *esContext )
|
||||
{
|
||||
UserData *userData = esContext->userData;
|
||||
int i;
|
||||
|
||||
GLbyte vShaderStr[] =
|
||||
"uniform float u_time; \n"
|
||||
"uniform vec3 u_centerPosition; \n"
|
||||
"attribute float a_lifetime; \n"
|
||||
"attribute vec3 a_startPosition; \n"
|
||||
"attribute vec3 a_endPosition; \n"
|
||||
"varying float v_lifetime; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" if ( u_time <= a_lifetime ) \n"
|
||||
" { \n"
|
||||
" gl_Position.xyz = a_startPosition + \n"
|
||||
" (u_time * a_endPosition); \n"
|
||||
" gl_Position.xyz += u_centerPosition; \n"
|
||||
" gl_Position.w = 1.0; \n"
|
||||
" } \n"
|
||||
" else \n"
|
||||
" gl_Position = vec4( -1000, -1000, 0, 0 ); \n"
|
||||
" v_lifetime = 1.0 - ( u_time / a_lifetime ); \n"
|
||||
" v_lifetime = clamp ( v_lifetime, 0.0, 1.0 ); \n"
|
||||
" gl_PointSize = ( v_lifetime * v_lifetime ) * 40.0; \n"
|
||||
"}";
|
||||
|
||||
GLbyte fShaderStr[] =
|
||||
"precision mediump float; \n"
|
||||
"uniform vec4 u_color; \n"
|
||||
"varying float v_lifetime; \n"
|
||||
"uniform sampler2D s_texture; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 texColor; \n"
|
||||
" texColor = texture2D( s_texture, gl_PointCoord ); \n"
|
||||
" gl_FragColor = vec4( u_color ) * texColor; \n"
|
||||
" gl_FragColor.a *= v_lifetime; \n"
|
||||
"} \n";
|
||||
|
||||
// Load the shaders and get a linked program object
|
||||
userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
|
||||
|
||||
// Get the attribute locations
|
||||
userData->lifetimeLoc = glGetAttribLocation ( userData->programObject, "a_lifetime" );
|
||||
userData->startPositionLoc = glGetAttribLocation ( userData->programObject, "a_startPosition" );
|
||||
userData->endPositionLoc = glGetAttribLocation ( userData->programObject, "a_endPosition" );
|
||||
|
||||
// Get the uniform locations
|
||||
userData->timeLoc = glGetUniformLocation ( userData->programObject, "u_time" );
|
||||
userData->centerPositionLoc = glGetUniformLocation ( userData->programObject, "u_centerPosition" );
|
||||
userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color" );
|
||||
userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
|
||||
|
||||
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
|
||||
// Fill in particle data array
|
||||
srand ( 0 );
|
||||
for ( i = 0; i < NUM_PARTICLES; i++ )
|
||||
{
|
||||
float *particleData = &userData->particleData[i * PARTICLE_SIZE];
|
||||
|
||||
// Lifetime of particle
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 10000.0f );
|
||||
|
||||
// End position of particle
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
|
||||
|
||||
// Start position of particle
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
|
||||
(*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
|
||||
|
||||
}
|
||||
|
||||
// Initialize time to cause reset on first update
|
||||
userData->time = 1.0f;
|
||||
|
||||
userData->textureId = LoadTexture ( "smoke.tga" );
|
||||
if ( userData->textureId <= 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///
|
||||
// Update time-based variables
|
||||
//
|
||||
void Update ( ESContext *esContext, float deltaTime )
|
||||
{
|
||||
UserData *userData = esContext->userData;
|
||||
|
||||
userData->time += deltaTime;
|
||||
|
||||
if ( userData->time >= 1.0f )
|
||||
{
|
||||
float centerPos[3];
|
||||
float color[4];
|
||||
|
||||
userData->time = 0.0f;
|
||||
|
||||
// Pick a new start location and color
|
||||
centerPos[0] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
|
||||
centerPos[1] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
|
||||
centerPos[2] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
|
||||
|
||||
glUniform3fv ( userData->centerPositionLoc, 1, ¢erPos[0] );
|
||||
|
||||
// Random color
|
||||
color[0] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
|
||||
color[1] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
|
||||
color[2] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
|
||||
color[3] = 0.5;
|
||||
|
||||
glUniform4fv ( userData->colorLoc, 1, &color[0] );
|
||||
}
|
||||
|
||||
// Load uniform time variable
|
||||
glUniform1f ( userData->timeLoc, userData->time );
|
||||
}
|
||||
|
||||
///
|
||||
// Draw a triangle using the shader pair created in Init()
|
||||
//
|
||||
void Draw ( ESContext *esContext )
|
||||
{
|
||||
UserData *userData = esContext->userData;
|
||||
|
||||
// Set the viewport
|
||||
glViewport ( 0, 0, esContext->width, esContext->height );
|
||||
|
||||
// Clear the color buffer
|
||||
glClear ( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// Use the program object
|
||||
glUseProgram ( userData->programObject );
|
||||
|
||||
// Load the vertex attributes
|
||||
glVertexAttribPointer ( userData->lifetimeLoc, 1, GL_FLOAT,
|
||||
GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
|
||||
userData->particleData );
|
||||
|
||||
glVertexAttribPointer ( userData->endPositionLoc, 3, GL_FLOAT,
|
||||
GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
|
||||
&userData->particleData[1] );
|
||||
|
||||
glVertexAttribPointer ( userData->startPositionLoc, 3, GL_FLOAT,
|
||||
GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
|
||||
&userData->particleData[4] );
|
||||
|
||||
|
||||
glEnableVertexAttribArray ( userData->lifetimeLoc );
|
||||
glEnableVertexAttribArray ( userData->endPositionLoc );
|
||||
glEnableVertexAttribArray ( userData->startPositionLoc );
|
||||
// Blend particles
|
||||
glEnable ( GL_BLEND );
|
||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE );
|
||||
|
||||
// Bind the texture
|
||||
glActiveTexture ( GL_TEXTURE0 );
|
||||
glBindTexture ( GL_TEXTURE_2D, userData->textureId );
|
||||
glEnable ( GL_TEXTURE_2D );
|
||||
|
||||
// Set the sampler texture unit to 0
|
||||
glUniform1i ( userData->samplerLoc, 0 );
|
||||
|
||||
glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
|
||||
|
||||
eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
|
||||
}
|
||||
|
||||
///
|
||||
// Cleanup
|
||||
//
|
||||
void ShutDown ( ESContext *esContext )
|
||||
{
|
||||
UserData *userData = esContext->userData;
|
||||
|
||||
// Delete texture object
|
||||
glDeleteTextures ( 1, &userData->textureId );
|
||||
|
||||
// Delete program object
|
||||
glDeleteProgram ( userData->programObject );
|
||||
}
|
||||
|
||||
|
||||
int main ( int argc, char *argv[] )
|
||||
{
|
||||
ESContext esContext;
|
||||
UserData userData;
|
||||
|
||||
esInitContext ( &esContext );
|
||||
esContext.userData = &userData;
|
||||
|
||||
esCreateWindow ( &esContext, TEXT("ParticleSystem"), 640, 480, ES_WINDOW_RGB );
|
||||
|
||||
if ( !Init ( &esContext ) )
|
||||
return 0;
|
||||
|
||||
esRegisterDrawFunc ( &esContext, Draw );
|
||||
esRegisterUpdateFunc ( &esContext, Update );
|
||||
|
||||
esMainLoop ( &esContext );
|
||||
|
||||
ShutDown ( &esContext );
|
||||
}
|
|
@ -130,13 +130,13 @@
|
|||
{
|
||||
'target_name': 'particle_system',
|
||||
'type': 'executable',
|
||||
'dependencies': [ 'es_util' ],
|
||||
'sources': [ '<!@(python <(angle_path)/enumerate_files.py gles2_book/ParticleSystem -types *.c *.h)' ],
|
||||
'dependencies': [ 'sample_util' ],
|
||||
'sources': [ '<!@(python <(angle_path)/enumerate_files.py angle/particle_system -types *.cpp *.h)' ],
|
||||
'copies':
|
||||
[
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [ '<!@(python <(angle_path)/enumerate_files.py gles2_book/ParticleSystem -types *.tga)' ],
|
||||
'files': [ '<!@(python <(angle_path)/enumerate_files.py angle/particle_system -types *.tga)' ],
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче