| @@ -78,6 +78,7 @@ tools/make-font | |||||
| tutorial/01_triangle | tutorial/01_triangle | ||||
| tutorial/02_cube | tutorial/02_cube | ||||
| tutorial/03_noise | tutorial/03_noise | ||||
| tutorial/04_texture | |||||
| tutorial/05_easymesh | tutorial/05_easymesh | ||||
| tutorial/08_fbo | tutorial/08_fbo | ||||
| tutorial/11_fractal | tutorial/11_fractal | ||||
| @@ -50,6 +50,7 @@ struct ShaderTexture | |||||
| { | { | ||||
| friend class Shader; | friend class Shader; | ||||
| friend class FrameBuffer; | friend class FrameBuffer; | ||||
| friend class Texture; | |||||
| public: | public: | ||||
| inline ShaderTexture() : m_flags(0) {} | inline ShaderTexture() : m_flags(0) {} | ||||
| @@ -45,11 +45,11 @@ class TextureData | |||||
| PixelFormat m_format; | PixelFormat m_format; | ||||
| #if defined USE_D3D9 | #if defined USE_D3D9 | ||||
| IDirect3DTexture9 *m_tex; | |||||
| IDirect3DTexture9 *m_texture; | |||||
| #elif defined _XBOX | #elif defined _XBOX | ||||
| D3DTexture *m_tex; | |||||
| D3DTexture *m_texture; | |||||
| #else | #else | ||||
| GLuint m_texid; | |||||
| GLuint m_texture; | |||||
| GLint m_internal_format; | GLint m_internal_format; | ||||
| GLenum m_gl_format, m_gl_type; | GLenum m_gl_format, m_gl_type; | ||||
| #endif | #endif | ||||
| @@ -101,7 +101,7 @@ Texture::Texture(ivec2 size, PixelFormat format) | |||||
| g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, | g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, | ||||
| d3d_usage, d3d_format, | d3d_usage, d3d_format, | ||||
| D3DPOOL_DEFAULT, &m_data->m_tex, NULL); | |||||
| D3DPOOL_DEFAULT, &m_data->m_texture, NULL); | |||||
| #else | #else | ||||
| static struct | static struct | ||||
| { | { | ||||
| @@ -143,8 +143,8 @@ Texture::Texture(ivec2 size, PixelFormat format) | |||||
| m_data->m_gl_format = GET_CLAMPED(gl_formats, format).format; | m_data->m_gl_format = GET_CLAMPED(gl_formats, format).format; | ||||
| m_data->m_gl_type = GET_CLAMPED(gl_formats, format).type; | m_data->m_gl_type = GET_CLAMPED(gl_formats, format).type; | ||||
| glGenTextures(1, &m_data->m_texid); | |||||
| glBindTexture(GL_TEXTURE_2D, m_data->m_texid); | |||||
| glGenTextures(1, &m_data->m_texture); | |||||
| glBindTexture(GL_TEXTURE_2D, m_data->m_texture); | |||||
| # if defined __CELLOS_LV2__ | # if defined __CELLOS_LV2__ | ||||
| /* We need this hint because by default the storage type is | /* We need this hint because by default the storage type is | ||||
| @@ -157,15 +157,26 @@ Texture::Texture(ivec2 size, PixelFormat format) | |||||
| #endif | #endif | ||||
| } | } | ||||
| ShaderTexture Texture::GetTexture() const | |||||
| { | |||||
| ShaderTexture ret; | |||||
| #if defined USE_D3D9 || defined _XBOX | |||||
| ret.m_flags = (uint64_t)(uintptr_t)m_data->m_texture; | |||||
| #else | |||||
| ret.m_flags = m_data->m_texture; | |||||
| #endif | |||||
| return ret; | |||||
| } | |||||
| void Texture::Bind() | void Texture::Bind() | ||||
| { | { | ||||
| #if defined _XBOX || defined USE_D3D9 | #if defined _XBOX || defined USE_D3D9 | ||||
| g_d3ddevice->SetTexture(0, m_data->m_tex); | |||||
| g_d3ddevice->SetTexture(0, m_data->m_texture); | |||||
| #else | #else | ||||
| # if !defined HAVE_GLES_2X | # if !defined HAVE_GLES_2X | ||||
| glEnable(GL_TEXTURE_2D); | glEnable(GL_TEXTURE_2D); | ||||
| # endif | # endif | ||||
| glBindTexture(GL_TEXTURE_2D, m_data->m_texid); | |||||
| glBindTexture(GL_TEXTURE_2D, m_data->m_texture); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -174,14 +185,14 @@ void Texture::SetData(void *data) | |||||
| #if defined _XBOX || defined USE_D3D9 | #if defined _XBOX || defined USE_D3D9 | ||||
| D3DLOCKED_RECT rect; | D3DLOCKED_RECT rect; | ||||
| # if defined USE_D3D9 | # if defined USE_D3D9 | ||||
| m_data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_DISCARD); | |||||
| m_data->m_texture->LockRect(0, &rect, NULL, D3DLOCK_DISCARD); | |||||
| # else | # else | ||||
| m_data->m_tex->LockRect(0, &rect, NULL, 0); | |||||
| m_data->m_texture->LockRect(0, &rect, NULL, 0); | |||||
| # endif | # endif | ||||
| memcpy(rect.pBits, data, rect.Pitch * m_data->m_size.y); | memcpy(rect.pBits, data, rect.Pitch * m_data->m_size.y); | ||||
| m_data->m_tex->UnlockRect(0); | |||||
| m_data->m_texture->UnlockRect(0); | |||||
| #else | #else | ||||
| glTexImage2D(GL_TEXTURE_2D, 0, m_data->m_internal_format, | glTexImage2D(GL_TEXTURE_2D, 0, m_data->m_internal_format, | ||||
| @@ -194,7 +205,7 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data) | |||||
| { | { | ||||
| #if defined _XBOX || defined USE_D3D9 | #if defined _XBOX || defined USE_D3D9 | ||||
| D3DLOCKED_RECT rect; | D3DLOCKED_RECT rect; | ||||
| m_data->m_tex->LockRect(0, &rect, NULL, 0); | |||||
| m_data->m_texture->LockRect(0, &rect, NULL, 0); | |||||
| for (int j = 0; j < size.y; j++) | for (int j = 0; j < size.y; j++) | ||||
| { | { | ||||
| @@ -204,7 +215,7 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data) | |||||
| memcpy(dst, src, size.x * 4); | memcpy(dst, src, size.x * 4); | ||||
| } | } | ||||
| m_data->m_tex->UnlockRect(0); | |||||
| m_data->m_texture->UnlockRect(0); | |||||
| #else | #else | ||||
| glTexSubImage2D(GL_TEXTURE_2D, 0, origin.x, origin.y, size.x, size.y, | glTexSubImage2D(GL_TEXTURE_2D, 0, origin.x, origin.y, size.x, size.y, | ||||
| @@ -215,9 +226,9 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data) | |||||
| Texture::~Texture() | Texture::~Texture() | ||||
| { | { | ||||
| #if defined USE_D3D9 || defined _XBOX | #if defined USE_D3D9 || defined _XBOX | ||||
| m_data->m_tex->Release(); | |||||
| m_data->m_texture->Release(); | |||||
| #else | #else | ||||
| glDeleteTextures(1, &m_data->m_texid); | |||||
| glDeleteTextures(1, &m_data->m_texture); | |||||
| #endif | #endif | ||||
| delete m_data; | delete m_data; | ||||
| @@ -46,6 +46,8 @@ public: | |||||
| void SetData(void *data); | void SetData(void *data); | ||||
| void SetSubData(ivec2 origin, ivec2 size, void *data); | void SetSubData(ivec2 origin, ivec2 size, void *data); | ||||
| ShaderTexture GetTexture() const; | |||||
| private: | private: | ||||
| class TextureData *m_data; | class TextureData *m_data; | ||||
| }; | }; | ||||
| @@ -0,0 +1,156 @@ | |||||
| // | |||||
| // Lol Engine - Noise tutorial | |||||
| // | |||||
| // Copyright: (c) 2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||||
| // | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include "core.h" | |||||
| #include "loldebug.h" | |||||
| using namespace std; | |||||
| using namespace lol; | |||||
| extern char const *lolfx_04_texture; | |||||
| class TextureDemo : public WorldEntity | |||||
| { | |||||
| public: | |||||
| TextureDemo() : | |||||
| m_frames(0), | |||||
| m_ready(false) | |||||
| { | |||||
| m_vertices << vec2(-1.0, 1.0); | |||||
| m_vertices << vec2(-1.0, -1.0); | |||||
| m_vertices << vec2( 1.0, -1.0); | |||||
| m_vertices << vec2(-1.0, 1.0); | |||||
| m_vertices << vec2( 1.0, -1.0); | |||||
| m_vertices << vec2( 1.0, 1.0); | |||||
| m_heightmap = new uint8_t[4 * 512 * 1]; | |||||
| } | |||||
| virtual ~TextureDemo() | |||||
| { | |||||
| delete m_heightmap; | |||||
| } | |||||
| virtual void TickGame(float seconds) | |||||
| { | |||||
| WorldEntity::TickGame(seconds); | |||||
| /* Generate a new heightmap every 400 frames */ | |||||
| if (m_frames % 400 == 0) | |||||
| { | |||||
| for (int i = 0, height = 64; i < 512; i++) | |||||
| { | |||||
| m_heightmap[4 * i] = height; | |||||
| m_heightmap[4 * i + 1] = 255; /* unused */ | |||||
| m_heightmap[4 * i + 2] = 255; /* unused */ | |||||
| m_heightmap[4 * i + 3] = 255; /* unused */ | |||||
| height += rand() % 17 - 8; | |||||
| height += rand() % 17 - 8; | |||||
| height = std::max(15, std::min(height, 240)); | |||||
| } | |||||
| } | |||||
| /* Slightly disturb the terrain */ | |||||
| for (int i = 1; i < 511; i++) | |||||
| { | |||||
| int delta = (rand() & 1) ? 1 : -1; | |||||
| if (rand() & 3) | |||||
| continue; | |||||
| uint8_t ¢er = m_heightmap[4 * i]; | |||||
| uint8_t &side1 = m_heightmap[4 * (i - delta)]; | |||||
| uint8_t &side2 = m_heightmap[4 * (i + delta)]; | |||||
| if (center > side1) | |||||
| { | |||||
| center--; | |||||
| side1++; | |||||
| } | |||||
| else if (center > side2) | |||||
| { | |||||
| center--; | |||||
| side2++; | |||||
| } | |||||
| } | |||||
| /* Update frame counter */ | |||||
| ++m_frames; | |||||
| } | |||||
| virtual void TickDraw(float seconds) | |||||
| { | |||||
| WorldEntity::TickDraw(seconds); | |||||
| /* Initialise GPU data */ | |||||
| if (!m_ready) | |||||
| { | |||||
| m_texture = new Texture(ivec2(512, 1), PixelFormat::A8R8G8B8); | |||||
| m_shader = Shader::Create(lolfx_04_texture); | |||||
| m_coord = m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); | |||||
| m_vdecl = new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position)); | |||||
| m_vbo = new VertexBuffer(m_vertices.Bytes()); | |||||
| void *vertices = m_vbo->Lock(0, 0); | |||||
| memcpy(vertices, &m_vertices[0], m_vertices.Bytes()); | |||||
| m_vbo->Unlock(); | |||||
| m_ready = true; | |||||
| /* FIXME: this object never cleans up */ | |||||
| } | |||||
| /* Send new heightmap to GPU */ | |||||
| m_texture->SetData(m_heightmap); | |||||
| m_shader->Bind(); | |||||
| m_shader->SetUniform(m_texture_uni, m_texture->GetTexture(), 0); | |||||
| m_vdecl->SetStream(m_vbo, m_coord); | |||||
| m_vdecl->Bind(); | |||||
| m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); | |||||
| m_vdecl->Unbind(); | |||||
| } | |||||
| private: | |||||
| Array<vec2> m_vertices; | |||||
| Texture *m_texture; | |||||
| Shader *m_shader; | |||||
| ShaderAttrib m_coord; | |||||
| ShaderUniform m_texture_uni; | |||||
| VertexDeclaration *m_vdecl; | |||||
| VertexBuffer *m_vbo; | |||||
| uint8_t *m_heightmap; | |||||
| int m_frames; | |||||
| bool m_ready; | |||||
| }; | |||||
| int main(int argc, char **argv) | |||||
| { | |||||
| Application app("Tutorial 4: Texture", ivec2(640, 480), 60.0f); | |||||
| #if defined _MSC_VER && !defined _XBOX | |||||
| _chdir("../.."); | |||||
| #elif defined _WIN32 && !defined _XBOX | |||||
| _chdir("../.."); | |||||
| #endif | |||||
| new TextureDemo(); | |||||
| app.Run(); | |||||
| return EXIT_SUCCESS; | |||||
| } | |||||
| @@ -0,0 +1,64 @@ | |||||
| [vert.glsl] | |||||
| #version 120 | |||||
| attribute vec2 in_Position; | |||||
| varying vec4 pass_Position; | |||||
| void main(void) | |||||
| { | |||||
| pass_Position = vec4(0.5 * in_Position + 0.5, 0.0, 1.0); | |||||
| gl_Position = vec4(in_Position, 0.0, 1.0); | |||||
| } | |||||
| [frag.glsl] | |||||
| #version 120 | |||||
| uniform sampler2D u_Texture; | |||||
| varying vec4 pass_Position; | |||||
| float rand(in vec2 p, in float v) | |||||
| { | |||||
| return fract(v * sin(dot(p, vec2(1298.9837, 7823.33145)))); | |||||
| } | |||||
| void main(void) | |||||
| { | |||||
| vec2 t = pass_Position.xy; | |||||
| vec4 c0 = texture2D(u_Texture, t); | |||||
| float f = rand(pass_Position.xy, 12345.67); | |||||
| if (t.y > c0.x) | |||||
| { | |||||
| /* Sky */ | |||||
| float val = min(t.y * 2.0, 1.0); | |||||
| if (f > 0.999) | |||||
| gl_FragColor = vec4(1.0); | |||||
| else | |||||
| gl_FragColor = vec4(0.4, t.y, val, 1.0); | |||||
| } | |||||
| else if (t.y > c0.x - 0.02) | |||||
| { | |||||
| /* Grass */ | |||||
| if (f > 0.99) | |||||
| gl_FragColor = vec4(0.4, 0.7, 0.3, 1.0); | |||||
| else if (f > 0.9) | |||||
| gl_FragColor = vec4(0.3, 0.6, 0.2, 1.0); | |||||
| else | |||||
| gl_FragColor = vec4(0.2, 0.5, 0.1, 1.0); | |||||
| } | |||||
| else | |||||
| { | |||||
| /* Earth */ | |||||
| if (f > 0.99) | |||||
| gl_FragColor = vec4(0.7, 0.4, 0.3, 1.0); | |||||
| else if (f > 0.9) | |||||
| gl_FragColor = vec4(0.6, 0.3, 0.2, 1.0); | |||||
| else | |||||
| gl_FragColor = vec4(0.5, 0.2, 0.1, 1.0); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,68 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
| <ItemGroup Label="ProjectConfigurations"> | |||||
| <ProjectConfiguration Include="Debug|PS3"> | |||||
| <Configuration>Debug</Configuration> | |||||
| <Platform>PS3</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Debug|Win32"> | |||||
| <Configuration>Debug</Configuration> | |||||
| <Platform>Win32</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Debug|x64"> | |||||
| <Configuration>Debug</Configuration> | |||||
| <Platform>x64</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Debug|Xbox 360"> | |||||
| <Configuration>Debug</Configuration> | |||||
| <Platform>Xbox 360</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Release|PS3"> | |||||
| <Configuration>Release</Configuration> | |||||
| <Platform>PS3</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Release|Win32"> | |||||
| <Configuration>Release</Configuration> | |||||
| <Platform>Win32</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Release|x64"> | |||||
| <Configuration>Release</Configuration> | |||||
| <Platform>x64</Platform> | |||||
| </ProjectConfiguration> | |||||
| <ProjectConfiguration Include="Release|Xbox 360"> | |||||
| <Configuration>Release</Configuration> | |||||
| <Platform>Xbox 360</Platform> | |||||
| </ProjectConfiguration> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ClCompile Include="04_texture.cpp" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <LolFxCompile Include="04_texture.lolfx" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="$(SolutionDir)\..\..\src\lolcore.vcxproj"> | |||||
| <Project>{9e62f2fe-3408-4eae-8238-fd84238ceeda}</Project> | |||||
| </ProjectReference> | |||||
| </ItemGroup> | |||||
| <PropertyGroup Label="Globals"> | |||||
| <ProjectGuid>{834852db-edb6-4fd0-bcf9-45cd01126962}</ProjectGuid> | |||||
| <ConfigurationType>Application</ConfigurationType> | |||||
| <Keyword>Win32Proj</Keyword> | |||||
| </PropertyGroup> | |||||
| <Import Project="$(SolutionDir)\Lol.Core.Config.props" /> | |||||
| <ImportGroup Label="ExtensionSettings"> | |||||
| <Import Project="$(SolutionDir)\Lol.Fx.props" /> | |||||
| </ImportGroup> | |||||
| <ImportGroup Label="PropertySheets"> | |||||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
| <Import Project="$(SolutionDir)\Lol.Core.Vars.props" /> | |||||
| </ImportGroup> | |||||
| <PropertyGroup Label="UserMacros" /> | |||||
| <Import Project="$(SolutionDir)\Lol.Core.Rules.props" /> | |||||
| <ItemDefinitionGroup /> | |||||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||||
| <ImportGroup Label="ExtensionTargets"> | |||||
| <Import Project="$(SolutionDir)\Lol.Fx.targets" /> | |||||
| </ImportGroup> | |||||
| </Project> | |||||
| @@ -3,7 +3,8 @@ include $(top_srcdir)/build/autotools/common.am | |||||
| AM_CPPFLAGS = -I$(top_srcdir)/src | AM_CPPFLAGS = -I$(top_srcdir)/src | ||||
| noinst_PROGRAMS = 01_triangle 02_cube 03_noise 05_easymesh 08_fbo 11_fractal | |||||
| noinst_PROGRAMS = 01_triangle 02_cube 03_noise 04_texture 05_easymesh \ | |||||
| 08_fbo 11_fractal | |||||
| 01_triangle_SOURCES = 01_triangle.cpp 01_triangle.lolfx | 01_triangle_SOURCES = 01_triangle.cpp 01_triangle.lolfx | ||||
| 01_triangle_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | 01_triangle_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | ||||
| @@ -20,6 +21,11 @@ noinst_PROGRAMS = 01_triangle 02_cube 03_noise 05_easymesh 08_fbo 11_fractal | |||||
| 03_noise_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | 03_noise_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | ||||
| 03_noise_DEPENDENCIES = $(top_builddir)/src/liblol.a | 03_noise_DEPENDENCIES = $(top_builddir)/src/liblol.a | ||||
| 04_texture_SOURCES = 04_texture.cpp 04_texture.lolfx | |||||
| 04_texture_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | |||||
| 04_texture_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | |||||
| 04_texture_DEPENDENCIES = $(top_builddir)/src/liblol.a | |||||
| 05_easymesh_SOURCES = 05_easymesh.cpp | 05_easymesh_SOURCES = 05_easymesh.cpp | ||||
| 05_easymesh_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | 05_easymesh_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | ||||
| 05_easymesh_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | 05_easymesh_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | ||||