-
Senior Member
Noise texture generator
I'm trying to do a texture generator using OpenGl.
The thing I can't seem to get right, is manipulating the pData in gluBuild2DMipmaps which I use to build a bitmap of the generated texture.
I tried using some code I found here on DGDev to do the noise, but this
was rather unsuccesfull since the code uses scanline.
Currently, it throws me an access violation. (of course, even I can see that
it wont work
)
So I have a procedure to do the bitmap building of the data pointer, but
have no idea how to get the data pointer right.
[pascal]
type
TRGBArray = array[0..MAXPIXELS - 1] of TRGBTriple;
pRGBArray = ^TRGBArray;
type
TGeneratedTexture=class
private
public
pTextureData: pointer;
Texture: glUint;
procedure GenerateTexture;
procedure AddNoise(R,G,B: byte);
procedure AssignData(Data: pointer);
procedure GetColor(Color: byte);
procedure Bind;
end;
procedure TGeneratedTexture.AddNoise(R,G,B: byte);
var
pData: pRGBArray;
J,I: integer;
begin
for J := 0 to TEXHEIGHT - 1 do
begin
for I := 0 to TEXWIDTH - 1 do
begin
pData[I].rgbtRed:=Random(R);
pData[I].rgbtGreen:=Random(G);
pData[I].rgbtBlue:=Random(B);
end;
pTextureData:=pData;
GenerateTexture;
end;
end;
procedure TGeneratedTexture.GenerateTexture;
begin
glGenTextures(1, Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TEXWIDTH, TEXHeight, GL_RGB, GL_UNSIGNED_BYTE, pTextureData);
end;
[/pascal]
-
Super Member
Noise texture generator
You have to make a pointer point somewhere before trying to write to memory through it, and your GenerateTexture call is in a for J := 0 to TEXHEIGHT ?¢_" 1 loop. It should look something like this:
[pascal]procedure TGeneratedTexture.AddNoise(R, G, B: byte);
var
pData: PRGBTriple;
j, i: integer;
begin
GetMem(pData, TEXHEIGHT * TEXWIDTH * SizeOf(TRGBTriple));
pTextureData:= pData;
for j := 0 to TEXHEIGHT - 1 do
for I := 0 to TEXWIDTH - 1 do
begin
pData.rgbtRed:= Random(R);
pData.rgbtGreen:= Random(G);
pData.rgbtBlue:= Random(B);
inc(pData, SizeoOf(TRGBTriple));
end;
GenerateTexture;
Dispose(pTextureData);
end;[/pascal]
-
Senior Member
-
Super Member
Noise texture generator
A bit of an oversight, inc in the loop should be by 1 instead of SizeoOf(TRGBTriple).
-
-
Senior Member
Noise texture generator
I was just wondering, whats the best way to apply operators to textures created this way? (IE: combining textures and applying distortion)
-
Super Member
Noise texture generator
The best and simplest way is to not do anything with textures but with data you are generating textures with, storing that data in a 2D array should save you some sanity.
-
Senior Member
Noise texture generator
Thanks for the tip
I've allready implemented arrays.
I did it like this:
Pixel/shader creator example (woks perfect):
(t3arr is just a record containing r,g,b bytes)
[pascal]
const
TEXWIDTH=256;
TEXHEIGHT=256;
type
TextureItem=record
Data: Pointer;
Texture: gluInt;
Raw: array[0..255,0..255] of T3Arr;
end;
function GetPixelShape(X,Y: byte):byte;
var
x2,y2,radius,baseradius,temp: extended;
begin
x2:=128;
y2:=128;
radius:=Sqrt(power((x2-x),2)+power((y2-y),2));
baseradius:=Sqrt(power((x2-30),2)+power((y2-12
,2));
if radius<=baseradius then
Result:=255-trunc(2.5*radius)
else
Result:=0;
end;
procedure Pixel(LayerNumber: integer; Grid: byte);
var
pData: pRGBTriple;
j, i: integer;
temp: integer;
F: boolean;
begin
if Grid=1 then
F:=true
else
F:=false;
GetMem(pData, TEXHEIGHT * TEXWIDTH * SizeOf(TRGBTriple));
FTextures[LayerNumber].Data:= pData;
for j := 0 to TEXHEIGHT - 1 do
for I := 0 to TEXWIDTH - 1 do
begin
Temp:=GetPixelShape(I,J);
if f=false then //don't draw with grid
begin
case FCurrentOperator of
0: //Overwrite
begin
FTextures[LayerNumber].Raw[J,I].r:=temp;
FTextures[LayerNumber].Raw[J,I].g:=temp;
FTextures[LayerNumber].Raw[J,I].b:=temp;
end;
1: //Add
begin
if temp<>0 then
begin
FTextures[LayerNumber].Raw[J,I].r:=trunc((FTextures[LayerNumber].Raw[J,I].r /2)+(temp/2));
FTextures[LayerNumber].Raw[J,I].g:=trunc((FTextures[LayerNumber].Raw[J,I].g /2)+(temp/2));
FTextures[LayerNumber].Raw[J,I].b:=trunc((FTextures[LayerNumber].Raw[J,I].b /2)+(temp/2));
end;
end;
end;
pData.rgbtRed:= FTextures[LayerNumber].raw[J,I].r;
pData.rgbtGreen:= FTextures[LayerNumber].raw[J,I].g;
pData.rgbtBlue:= FTextures[LayerNumber].raw[J,I].b;
end
else //draw with grid
if (odd(i)) and (odd(j)) then
begin
FTextures[LayerNumber].Raw[J,I].r:=0;
FTextures[LayerNumber].Raw[J,I].g:=0;
FTextures[LayerNumber].Raw[J,I].b:=0;
pData.rgbtRed:= 0;
pData.rgbtGreen:= 0;
pData.rgbtBlue:= 0;
end
else
begin
case FCurrentOperator of
0: //overwrite
begin
FTextures[LayerNumber].Raw[J,I].r:=temp;
FTextures[LayerNumber].Raw[J,I].g:=temp;
FTextures[LayerNumber].Raw[J,I].b:=temp;
end;
1: //add
begin
if temp<>0 then
begin
FTextures[LayerNumber].Raw[J,I].r:=trunc((FTextures[LayerNumber].Raw[J,I].r /2)+(temp/2));
FTextures[LayerNumber].Raw[J,I].g:=trunc((FTextures[LayerNumber].Raw[J,I].g /2)+(temp/2));
FTextures[LayerNumber].Raw[J,I].b:=trunc((FTextures[LayerNumber].Raw[J,I].b /2)+(temp/2));
end;
end;
end;
pData.rgbtRed:=FTextures[LayerNumber].Raw[J,I].r;
pData.rgbtGreen:=FTextures[LayerNumber].Raw[J,I].g;
pData.rgbtBlue:=FTextures[LayerNumber].Raw[J,I].b;
end;
inc(pData, 1);
end;
end;
[/pascal]
However, I've had some problems getting my blending procedure right, which was the reason for my question:
[pascal]
procedure CombineTextures(src1,src2,dest: integer);
var
pData: pRGBTriple;
j, i: integer;
temp: byte;
begin
GetMem(pData, TEXHEIGHT * TEXWIDTH * SizeOf(TRGBTriple));
FTextures[dest].Data:= pData;
for j := 0 to TEXHEIGHT - 1 do
for I := 0 to TEXWIDTH - 1 do
begin
FTextures[Dest].raw[J,I].r:=trunc((FTextures[src1].Raw[J,I].r/2)+((FTextures[Src2].Raw[J,I].r / 2)));
FTextures[Dest].raw[J,I].g:=trunc((FTextures[src1].Raw[J,I].g/2)+((FTextures[Src2].Raw[J,I].g / 2)));
FTextures[Dest].raw[J,I].b:=trunc((FTextures[src1].Raw[J,I].b/2)+((FTextures[Src2].Raw[J,I].b / 2)));
pData.rgbtRed:=FTextures[Dest].raw[J,I].r;
pData.rgbtGreen:=FTextures[Dest].raw[J,I].g;
pData.rgbtBlue:=FTextures[Dest].raw[J,I].b;
inc(pData, 1);
end;
end;
[/pascal]
-
Super Member
Noise texture generator
Whoa, you do not need to duplicate texture data, do your operations with the array and when you want to use a pointer simply get the address of the first element of the array. You're procedure is missing a begin
-
Senior Member
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
http://flippulseimages.com/Computer/