aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/documentation.md208
-rw-r--r--smelt/glfw_m/gfx_glfw.cpp50
2 files changed, 156 insertions, 102 deletions
diff --git a/doc/documentation.md b/doc/documentation.md
index 1361005..bf0fd9e 100644
--- a/doc/documentation.md
+++ b/doc/documentation.md
@@ -4,12 +4,12 @@
## Table of contents
1. [Overview](#overview)
2. [History](#history)
-5. [Macros](#macros)
-3. [Data Types](#types)
-4. [Core Functions](#core)
-5. [Extensions](#extensions)
+3. [Macros](#macros)
+4. [Data Types](#types)
+5. [Core Functions](#core)
+6. [Extensions](#extensions)
7. [Implementation details](#implementation)
-6. [General considerations](#considerations)
+8. [General considerations](#considerations)
## Overview <a name="overview"></a>
SMELT is a wrapper class for hardware-accelerated graphics rendering,
@@ -80,7 +80,7 @@ test for a modifier.
`smVertex`: Vertex structure.
- `x,y,z`: Position. `z` can be used for depth testing in 2D mode.
-- `col`: Vertex color.
+- `col`: Vertex color. This color is in the format "AARRGGBB" (hex).
- `tx,ty`: Texture coordinates.
`smTriangle`: Triangle primitive structure.
@@ -247,8 +247,8 @@ Limitations of `smSFXLoad()` also applies.
Plays the given SFX. All parameters except the FX name is optional.
A channel is generated and can be used to control the playing of the SFX.
The channel is valid until it stops.
-Volume should be 0~100.
-Panning should be -100~100.
+Volume should be in [0,100].
+Panning should be [-100,100].
These values will be clamped to the range given above.
Note: There's a limit of the total available channels. This is defined in
the header `smelt\_config.hpp` with the macro `SRC_MAX`. If you are playing
@@ -275,10 +275,10 @@ Releases the sound file from memory.
The handle will be invalid thereafter.
- `void smChannelVol(SMCHN chn,int vol)`
-Sets channel volume (0~100).
+Sets channel volume ([0,100]).
- `void smChannelPan(SMCHN chn,int pan)`
-Sets channel panning (-100~100).
+Sets channel panning ([-100,100]).
- `void smChannelPitch(SMCHN chn,float pitch)`
Sets channel pitch.
@@ -445,84 +445,152 @@ If you are not quite sure about what this function does, just ignore it.
- `blend`: blending mode.
- `texture`: texture used for the drawing.
-SMTRG smTargetCreate(int w,int h,int ms=0) [core/GFX]
-Creates a rendering target (sized w*h) with multisampling level ms.
-Modern OpenGL supports non-power-of-two targets, however some of the D3D9
-hardwares doesn't.
-The target will be automatically resized, larger than the requested size, if
-the given size is not supported.
-Multisampling is disabled if ms=0. If multisampling is not supported, it
-will be disabled automatically.
+- `SMTRG smTargetCreate(int w,int h,int ms=0)`
+Creates a rendering target (sized `w*h`) with multisampling level ms.
+Modern OpenGL supports non-power-of-two sized targets. However some legacy
+hardware may lack the support.
+In this case, the target will be automatically enlarged.
+Multisampling is disabled if `ms=0`. This value is only a hint to SMELT.
+If multisampling is not supported, it will be disabled automatically.
-SMTEX smTargetTexture(SMTRG targ) [core/GFX]
-Gets the texture of the rendering target.
+- `SMTEX smTargetTexture(SMTRG targ)`
+Gets the texture of the rendering target. The texture contains the resulting
+image rendered to that target.
-void smTargetFree(SMTRG targ) [core/GFX]
+- `void smTargetFree(SMTRG targ)`
Frees the rendering target.
-SMTEX smTextureCreate(int w,int h) [core/GFX]
-Creates a blank texture (sized w*h).
-OpenGL version supports non-power-of-two textures, however some of the D3D9
-hardwares doesn't.
-The texture will be automatically resized, larger than the requested size, if
-it is not supported.
+- `SMTEX smTextureCreate(int w,int h)`
+Creates a blank texture (sized `w*h`).
+Modern OpenGL supports non-power-of-two sized textures. However some legacy
+hardware may lack the support.
+In this case, the texture will be automatically enlarged.
-SMTEX smTextureLoad(const char *path,bool mipmap=false) [core/GFX]
+- `SMTEX smTextureLoad(const char *path,bool mipmap=false)`
Loads texture from the given file.
-OpenGL version supports non-power-of-two textures, however some of the D3D9
-hardwares doesn't.
-The texture will be automatically resized, larger than the requested size, if
-it is not supported.
-mipmapping doesn't work in OpenGL versions.
-
-SMTEX smTextureLoadFromMemory(const char *ptr,DWORD size,bool mipmap=false)
-[core/GFX]
+The POT (power-of-two) issue above also applies here.
+Mipmapping is not implemented yet.
+
+- `SMTEX smTextureLoadFromMemory(const char *ptr,DWORD size,bool mipmap=false)`
Loads texture from the given memory block.
-OpenGL version supports non-power-of-two textures, however some of the D3D9
-hardwares doesn't.
-The texture will be automatically resized, larger than the requested size, if
-it is not supported.
-mipmapping doesn't work in OpenGL versions.
+See also `smTextureLoad()`.
-void smTextureFree(SMTEX tex) [core/GFX]
+- `void smTextureFree(SMTEX tex)`
Release the texture from memory.
-void smTextureOpt(int potopt=TPOT_NONPOT,int filter=TFLT_LINEAR) [core/GFX]
+- `void smTextureOpt(int potopt=TPOT_NONPOT,int filter=TFLT_LINEAR)`
Sets texture options.
-TPOT_POT: textures dimensions are resized to the minimal power of two value.
-TPOT_NONPOT: use textures whose dimensions are not power of two directly.
-Please note that only power-of-two textures supports texture repeating.
-TFLT_LINEAR: use the linear filter for texture scaling.
-TFLT_NEAREST: use the nearest filter for texture scaling.
-
-int smTextureGetWidth(SMTEX tex,bool original=false) [core/GFX]
-Gets the width of the texture.
-If original==false and the texture is resized, the function will return the
-resized p-o-t width of the texture.
+ - `TPOT_POT`: textures dimensions are _always_ resized to the minimal
+ power of two value. In this mode, textures repeat themselves if the
+ texture coordinate is greater than one (`GL_REPEAT` is used).
+ - `TPOT_NONPOT`: use textures whose dimensions are not power of
+ two directly. If unsupported by the hardware, textures will
+ be resized anyway. This turns off texture repeating.
+ - `TFLT_LINEAR`: use the linear filter for texture scaling.
+ - `TFLT_NEAREST`: use the nearest filter for texture scaling.
+
+- `int smTextureGetWidth(SMTEX tex,bool original=false)`
+Gets the width of the texture.
+If `original==false` and the texture is resized, the function will return
+the resized POT width of the texture.
Otherwise it returns the actual width of the texture file.
-int smTextureGetHeight(SMTEX tex,bool original=false) [core/GFX]
-Gets the height of the texture.
-If original==false and the texture is resized, the function will return the
-resized p-o-t height of the texture.
+- `int smTextureGetHeight(SMTEX tex,bool original=false)`
+Gets the height of the texture.
+If `original==false` and the texture is resized, the function will return
+the resized POT height of the texture.
Otherwise it returns the actual height of the texture file.
-DWORD* smTextureLock(SMTEX tex,int l,int t,int w,int h,bool ro=true) [core/GFX]
-Locks the texture for reading/writing.
-The locked area is defined as (l,t,w,h): left, top, width, height.
-if ro==true, the changes won't be written back to the video memory.
-Textures of rendering targets cannot be locked.
-
-void smTexutreUnlock(SMTEX tex) [core/GFX]
+- `DWORD* smTextureLock(SMTEX tex,int l,int t,int w,int h,bool ro=true)`
+Locks the texture for reading/writing.
+The locked area is defined as `(l,t,w,h)`: left, top, width, height.
+if `ro==true`, the changes won't be uploaded back to the video memory.
+Textures of rendering targets cannot be locked.
+Currently, textures are locked **upside-down** -- this is due to the fact
+that textures in OpenGL originate from bottom-left. However the `top`
+parameter really represents what its name means. This is insane but I've
+got used to it. AND the locked pixels are in `AABBGGRR` format with
+`AA` at the side of the most significant bit, which makes everything
+even better.
+
+- `void smTexutreUnlock(SMTEX tex)`
Unlocks the texture so that it can be used for rendering.
-The changes will be commited to the video memory if ro==false when locking
-the texture.
-
-SMELT extensions===============================================================
+The changes will only be commited to the video memory if `ro==false` when
+locking the texture.
+
+## Extensions <a name="extensions"></a>
+
+### smAnim
+This extension provides texture management and animated entity support.
+
+### smBMFont
+This extension provides bitmap font support.
+
+### smColor
+This extension provides conversion between color models.
+
+### smDataPack
+This extension provides managed resources loading/writing.
+
+### smEntity
+This extension provides easy entity rendering methods.
+
+### smGrid
+This extension allows you to create distortion using a grid.
+
+### smIndicator
+This extension implements several value indicators.
+
+### smMath
+This extension implements common math routines.
+
+### smProgresser
+This extension implements interpolation.
+
+### smRandom
+This extension implements a pseudo random number generator.
+
+### smTTFont
+This extension implements truetype font rendering.
+
+## Implementation details <a name="implementation"></a>
+
+- The OpenGL implementation uses a client-side vertex array.
+All `smRender*()` rendering commands are buffered here before
+a draw has to be done. The size of the vertex array can be
+adjusted by the `VERTEX_BUFFER_SIZE` macro, found in `smelt_config.hpp`.
+- A draw batch has to be done when at least one of these changes:
+ - Primitive type
+ - Texture
+ - Blending mode
+ or when...
+ - the vertex array is full
+ - `smRenderEnd()` is called
+ - changing camera properties
+ - using 'advanced' drawing functions (`smGetVertArray()`,
+ `smDrawCustomIndexedVertices`)
+- When doing a batch draw, SMELT uploads the _whole_ vertex array
+(actually only the portion with your data) to OpenGL. So there's no
+real need for a vertex buffer object, but it hurts if you draw a lot
+of static objects.
+- The sound system implementation puts a limit on the number of effects
+played at the same time. This is defined by the `SRC_MAX` macro in
+`smelt_config.hpp`.
+- Currently there's no way to use two or more instances of SMELT in one
+application at the same time.
+
+## General considerations <a name="considerations"></a>
+- For the sake of performance, keep the number of draw batches as low as
+possible. Avoid switching properties that will trigger a batch too
+frequently.
+- ~~Use profiling functions to help improve performance.~~ Profiling
+functions are not yet added.
+- If you are going to draw something with plenty of coinciding vertices,
+consider using `smDrawCustomIndexedVertices()`.
+
+Old junk starting from here.
smAnimation====================================================================
-The extension provides texture management and animated entity support.
-
Texture info class: smTexInfo
smTexRect rect; Texture rectangle
char *name,*path; name and internal path of the texture
diff --git a/smelt/glfw_m/gfx_glfw.cpp b/smelt/glfw_m/gfx_glfw.cpp
index 4f69a40..1310fb7 100644
--- a/smelt/glfw_m/gfx_glfw.cpp
+++ b/smelt/glfw_m/gfx_glfw.cpp
@@ -24,8 +24,8 @@ static const char* fixedfunc_pipeline_vsh=
"uniform mat4 mproj;"
"void main(){"
"gl_Position=mproj*mmodv*vec4(vp,1.0f);"
- "ftc=vec2(vtc.x,1.0f-vtc.y);"//do flipping at a lower level
- "fc=vc;"
+ "ftc=vec2(vtc.x,1.0f-vtc.y);"
+ "fc.rgba=vc.bgra;"
"}"
;
static const char* fixedfunc_pipeline_fsh=
@@ -36,7 +36,7 @@ static const char* fixedfunc_pipeline_fsh=
"uniform sampler2D tex;"
"void main(){"
"color=fc*texture(tex,ftc);"
- "if(color.a<1./256.)discard;"//alpha testing
+ "if(color.a<1./256.)discard;"
"}"
;
struct glTexture
@@ -262,7 +262,7 @@ void SMELT_IMPL::smDrawCustomIndexedVertices(smVertex* vb,WORD* ib,int vbc,int i
{
batchOGL();
- float twm=1.,thm=1.;
+ float twm=-1.,thm=-1.;
if(texture)
{
glTexture *ptex=(glTexture*)texture;
@@ -281,29 +281,22 @@ void SMELT_IMPL::smDrawCustomIndexedVertices(smVertex* vb,WORD* ib,int vbc,int i
vertexArray[i].z=-vertexArray[i].z;
}
}
+ if(twm>0&&thm>0)
for(int i=0;i<vbc;++i)
{
vb[i].tx*=twm;
- vb[i].ty=(1.-vb[i].ty)*thm;
- DWORD color=vb[i].col;
- BYTE *col=(BYTE*)&vb[i].col;
- BYTE a=((color>>24)&0xFF);
- BYTE r=((color>>16)&0xFF);
- BYTE g=((color>> 8)&0xFF);
- BYTE b=((color>> 0)&0xFF);
- col[0]=r;col[1]=g;
- col[2]=b;col[3]=a;
+ vb[i].ty*=thm;
}
if(texture!=primTex)bindTexture((glTexture*)texture);
if(blend!=primBlend)setBlend(blend);
glBindVertexArray(VertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*vbc,vb,GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*vbc,vb,GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IndexBufferObject);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*ibc,ib,GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*ibc,ib,GL_DYNAMIC_DRAW);
glDrawElements(GL_TRIANGLES,ibc,GL_UNSIGNED_SHORT,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IndexBufferObject);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*((VERTEX_BUFFER_SIZE*6)/4),indexBuf,GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*((VERTEX_BUFFER_SIZE*6)/4),indexBuf,GL_DYNAMIC_DRAW);
glBindVertexArray(0);
if(texture!=primTex)bindTexture((glTexture*)primTex);
@@ -546,8 +539,8 @@ void SMELT_IMPL::smTexutreUnlock(SMTEX tex)
{
glBindTexture(GL_TEXTURE_2D,ptex->name);
glTexSubImage2D(GL_TEXTURE_2D,0,ptex->locx,
- (ptex->rh-ptex->locy)-ptex->loch,ptex->locw,ptex->loch,GL_RGBA,
- GL_UNSIGNED_BYTE,ptex->locpx);
+ (ptex->rh-ptex->locy)-ptex->loch,ptex->locw,ptex->loch,GL_RGBA,
+ GL_UNSIGNED_BYTE,ptex->locpx);
glBindTexture(GL_TEXTURE_2D,primTex?(((glTexture*)primTex)->name):0);
}
}
@@ -588,7 +581,7 @@ DWORD* SMELT_IMPL::decodeImage(BYTE *data,const char *fn,DWORD size,int &w,int &
w=img.GetWidth();h=img.GetHeight();
px=new DWORD[w*h];
BYTE *sptr=(BYTE*)px;
- bool atunnel=img.AlphaIsValid();
+ bool achannel=img.AlphaIsValid();
for(int i=0;i<h;++i)
for(int j=0;j<w;++j)
{
@@ -596,7 +589,7 @@ DWORD* SMELT_IMPL::decodeImage(BYTE *data,const char *fn,DWORD size,int &w,int &
*(sptr++)=rgb.rgbRed;
*(sptr++)=rgb.rgbGreen;
*(sptr++)=rgb.rgbBlue;
- *(sptr++)=atunnel?rgb.rgbReserved:0xFF;
+ *(sptr++)=achannel?rgb.rgbReserved:0xFF;
}
}
return px;
@@ -748,7 +741,7 @@ void SMELT_IMPL::batchOGL(bool endScene)
{
if(vertexArray&&primcnt)
{
- float twm=1.,thm=1.;
+ float twm=-1.,thm=-1.;
if(primTex)
{
glTexture *ptex=(glTexture*)primTex;
@@ -767,22 +760,15 @@ void SMELT_IMPL::batchOGL(bool endScene)
vertexArray[i].z=-vertexArray[i].z;
}
}
+ if(twm>0&&thm>0)
for(int i=0;i<primcnt*primType;++i)
{
vertexArray[i].tx*=twm;
vertexArray[i].ty*=thm;
- DWORD color=vertexArray[i].col;
- BYTE *col=(BYTE*)&vertexArray[i].col;
- BYTE a=((color>>24)&0xFF);
- BYTE r=((color>>16)&0xFF);
- BYTE g=((color>> 8)&0xFF);
- BYTE b=((color>> 0)&0xFF);
- col[0]=r;col[1]=g;
- col[2]=b;col[3]=a;
}
glBindVertexArray(VertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*primcnt*primType,vertexBuf,GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*primcnt*primType,vertexBuf,GL_DYNAMIC_DRAW);
switch(primType)
{
case PRIM_LINES:
@@ -1004,9 +990,9 @@ bool SMELT_IMPL::confOGL()
glGenBuffers(1,&IndexBufferObject);
glBindVertexArray(VertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*VERTEX_BUFFER_SIZE,vertexBuf,GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER,sizeof(smVertex)*VERTEX_BUFFER_SIZE,vertexBuf,GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IndexBufferObject);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*((VERTEX_BUFFER_SIZE*6)/4),indexBuf,GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*((VERTEX_BUFFER_SIZE*6)/4),indexBuf,GL_DYNAMIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,0,sizeof(smVertex),(void*)offsetof(smVertex,x));//vp
glVertexAttribPointer(1,4,GL_UNSIGNED_BYTE,1,sizeof(smVertex),(void*)offsetof(smVertex,col));//vc
glVertexAttribPointer(2,2,GL_FLOAT,0,sizeof(smVertex),(void*)offsetof(smVertex,tx));//vtc