Browse Source

tutorial: add a new texture generation example.

legacy
Sam Hocevar sam 12 years ago
parent
commit
6944db663b
8 changed files with 325 additions and 16 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -0
      src/gpu/shader.h
  3. +26
    -15
      src/gpu/texture.cpp
  4. +2
    -0
      src/gpu/texture.h
  5. +156
    -0
      tutorial/04_texture.cpp
  6. +64
    -0
      tutorial/04_texture.lolfx
  7. +68
    -0
      tutorial/04_texture.vcxproj
  8. +7
    -1
      tutorial/Makefile.am

+ 1
- 0
.gitignore View File

@@ -78,6 +78,7 @@ tools/make-font
tutorial/01_triangle
tutorial/02_cube
tutorial/03_noise
tutorial/04_texture
tutorial/05_easymesh
tutorial/08_fbo
tutorial/11_fractal


+ 1
- 0
src/gpu/shader.h View File

@@ -50,6 +50,7 @@ struct ShaderTexture
{
friend class Shader;
friend class FrameBuffer;
friend class Texture;

public:
inline ShaderTexture() : m_flags(0) {}


+ 26
- 15
src/gpu/texture.cpp View File

@@ -45,11 +45,11 @@ class TextureData
PixelFormat m_format;

#if defined USE_D3D9
IDirect3DTexture9 *m_tex;
IDirect3DTexture9 *m_texture;
#elif defined _XBOX
D3DTexture *m_tex;
D3DTexture *m_texture;
#else
GLuint m_texid;
GLuint m_texture;
GLint m_internal_format;
GLenum m_gl_format, m_gl_type;
#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,
d3d_usage, d3d_format,
D3DPOOL_DEFAULT, &m_data->m_tex, NULL);
D3DPOOL_DEFAULT, &m_data->m_texture, NULL);
#else
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_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__
/* We need this hint because by default the storage type is
@@ -157,15 +157,26 @@ Texture::Texture(ivec2 size, PixelFormat format)
#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()
{
#if defined _XBOX || defined USE_D3D9
g_d3ddevice->SetTexture(0, m_data->m_tex);
g_d3ddevice->SetTexture(0, m_data->m_texture);
#else
# if !defined HAVE_GLES_2X
glEnable(GL_TEXTURE_2D);
# endif
glBindTexture(GL_TEXTURE_2D, m_data->m_texid);
glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
#endif
}

@@ -174,14 +185,14 @@ void Texture::SetData(void *data)
#if defined _XBOX || defined USE_D3D9
D3DLOCKED_RECT rect;
# 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
m_data->m_tex->LockRect(0, &rect, NULL, 0);
m_data->m_texture->LockRect(0, &rect, NULL, 0);
# endif

memcpy(rect.pBits, data, rect.Pitch * m_data->m_size.y);

m_data->m_tex->UnlockRect(0);
m_data->m_texture->UnlockRect(0);

#else
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
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++)
{
@@ -204,7 +215,7 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data)
memcpy(dst, src, size.x * 4);
}

m_data->m_tex->UnlockRect(0);
m_data->m_texture->UnlockRect(0);

#else
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()
{
#if defined USE_D3D9 || defined _XBOX
m_data->m_tex->Release();
m_data->m_texture->Release();
#else
glDeleteTextures(1, &m_data->m_texid);
glDeleteTextures(1, &m_data->m_texture);
#endif

delete m_data;


+ 2
- 0
src/gpu/texture.h View File

@@ -46,6 +46,8 @@ public:
void SetData(void *data);
void SetSubData(ivec2 origin, ivec2 size, void *data);

ShaderTexture GetTexture() const;

private:
class TextureData *m_data;
};


+ 156
- 0
tutorial/04_texture.cpp View File

@@ -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 &center = 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;
}


+ 64
- 0
tutorial/04_texture.lolfx View File

@@ -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);
}
}


+ 68
- 0
tutorial/04_texture.vcxproj View File

@@ -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>

+ 7
- 1
tutorial/Makefile.am View File

@@ -3,7 +3,8 @@ include $(top_srcdir)/build/autotools/common.am

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_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_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_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@
05_easymesh_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@


Loading…
Cancel
Save