This blog will be associated with eclipse, Java Micro Edition, Android, etc... My premiere blogging date began from March, 25th, 2009
6/27/2009
Qt4.5.2-tower
Recently, Nokia published the new version of Qt4.5.2-tower which can be operated in many platforms. Previously, I installed the Qt4.5.0-garden for s60 and windows platforms. A couple of days ago, I tried to install S60 5th edition SDK and s60 3rd Feature pack II. I already had N97 0.5 version SDK. The S60 5th edition emulator provided a couple of resolution of mobile screen. So, I uninstalled 3rd edition and N97 edition SDK. Yesterday, I downloaded the Qt4.5.2-tower and I did install process into my old laptop notebook. The install required many things to install the Qt4.5.2-tower. I completed the install process yesterday night due to what I got. I like 2d graphics API. It easily use and so powerful. I am not sure now how an application install into real device. Since I like the emulator and I can launch my testing application into the emulator.
6/21/2009
Qt4.5.0-Garden
For Nokia Application developers, Now They have a little strong development toolkit. ‘Qt4.5.0-garden’ which supports library for s60 mobile makes low a barrier then before. It means S60 mobile application developers can develop application more easy. For me, I was trying to learn about Carbide C++ and S60 library but it gave to me very complex. But Qt garden takes away some complex. To launch an application under S60 emulator, it is very simple. The picture shows my first trying of tutorial which was presented from qt garden prereleased web site. At the moment, I only use text editor called Notepad++, Dos command for building tutorial C++ code and emulator. Of course, there are some things should installed before use Qt garden.
6/19/2009
Translation bitmap image
Bitmap image contains BitmapHeader, pixels data and palette. The palette only need less than 16 bit color bitmap image, so This article will not include. Microsoft Visual studio has BitmapHeader structure in some header files. It also provides some functions which often give developer difficult to understand. Anyone who may has basic knowledge of c++ and the structure of bitmap file will has no problem with this article. The aritcle will touch only Device Independent Bitmap and pixels data are not compressed.
Code begining here // ->>
#include <stdio.h>
#include <stdlib.h>
#pragma pack(1) // get the structure size 54 not 56
typedef struct {
unsigned char bfType1; // fixed 'B'
unsigned char bfType2; // fixed 'M'
unsigned int bfSize; // Size of File. Zero is acceptable
unsigned short bfReserved1; // Zero
unsigned short bfReserved2; // Zero
unsigned int bfOffBits; // Offset to beginning of bitmap
unsigned int biSize; // Number of Bytes in Structure
unsigned int biWidth; // width of bitmap in pixels
unsigned int biHeight; // height of bitmap in pixels
unsigned short biPlanes; // Planes in target device = 1
unsigned short biBitCount; // Bits per Pixel 1, 4, 8, 16, 24, 32
unsigned int biCompression; // BI_RGB = 0, BI_RLE8, BI_RLE4
unsigned int biSizeImage; // Size of Image Part (often ignored)
unsigned int biXPelsPerMeter; // Always Zero
unsigned int biYPelsPerMeter; // Always Zero
unsigned int biClrUsed; // Number of Colors used in Palette
unsigned int biClrImportant; // Number of Colors that are Important
} TBmpHeader;
<<- // Code end here
The pixels data fills the end of bitmap file after bitmap header. The 1 point pixel data consists of red, green and blue color value each. The each color value has the size of 8 bit.
This is a structure for 24 bit color.
Code begining here // ->>
typedef struct {
unsigned char rgbBlue; //intensity of blue in the color
unsigned char rgbGreen; //intensity of green in the color
unsigned char rgbRed; //intensity of red in the color
} TRGB;
<<- // Code end here
32 bit color adds alpha color value which sometimes use calcuration for mixing two images.
Code begining here // ->>
typedef struct {
unsigned char rgbBlue; //intensity of blue in the color
unsigned char rgbGreen; //intensity of green in the color
unsigned char rgbRed; //intensity of red in the color
unsigned char rgbAlpha; //intensity of Alpha in the color
} TRGBA;
<<- // Code end here
This routine fills bitmapheader structure by using width, height and color bit. The third argument is color type. It can use with 16, 24 and 32 value.
Code begin here // ->>
TBmpHeader FillBitmapHeader(unsigned int width, unsigned int height,
unsigned short bitmapType)
{
TBmpHeader MyBitmapHeader;
MyBitmapHeader.bfType1 = 0x42;
MyBitmapHeader.bfType2 = 0x4D;
MyBitmapHeader.bfSize = 0x00000000;
MyBitmapHeader.bfReserved1 = 0x0000;
MyBitmapHeader.bfReserved2 = 0x0000;
MyBitmapHeader.bfOffBits = 0x36; // the location of bitmap data
MyBitmapHeader.biSize = 0x28; // Size of the BItmapHeader
MyBitmapHeader.biWidth = width;
MyBitmapHeader.biHeight = height;
MyBitmapHeader.biPlanes = 0x0001; // Plane target device 1
MyBitmapHeader.biBitCount = bitmapType; // Bits per Pixel 1, 4, 8, 16, 24, 32
MyBitmapHeader.biCompression = 0x00000000; // BI_RGB = 0, BI_RLE8, BI_RLE4
MyBitmapHeader.biSizeImage = 0x00000000;
MyBitmapHeader.biXPelsPerMeter = 0x00000000;
MyBitmapHeader.biYPelsPerMeter = 0x00000000;
MyBitmapHeader.biClrUsed = 0x00000000;
MyBitmapHeader.biClrImportant = 0x00000000;
return MyBitmapHeader;
}
<<- // Code end here
16 bit color can consist 32 bit color but each RGBA color has to decrease there own size half. Therefore, the result image can not avoid color loss.
Code begin here // ->>
void ConvertBmp32to16(const char *srcfname, const char *dstfname)
{
TBmpHeader MyBitmapHeader;
FILE *finput = fopen(srcfname, “rb”);
if(finput == NULL) return;
fread(&MyBitmapHeader, sizeof(TBmpHeader), 1, finput);
TRGBA * rgbdata;
unsigned short *rgbdata16;
int SSize = MyBitmapHeader.biWidth * MyBitmapHeader.biHeight;
int Size = SSize * 4;
rgbdata = (TRGBA *)malloc(Size);
fread(rgbdata, Size, 1, finput);
fclose(finput);
rgbdata16 = (unsigned short *)malloc(SSize*2);
unsigned short r, g, b, a;
for(int i=0; i < SSize; i++) {
b = rgbdata[i].rgbBlue >> 4;
g = rgbdata[i].rgbGreen >> 4;
r = rgbdata[i].rgbRed >> 4;
a = rgbdata[i].rgbAlpha >> 4;
rgbdata16[i] = (r << 12) + (g << 8) + (b << 4) + a;
}
MyBitmapHeader = FillBitmapHeader(MyBitmapHeader.biWidth, MyBitmapHeader.biHeight, 16);
FILE *fpout = fopen(dstfname, “wb”);
if(fpout == NULL) return;
fwrite(&MyBitmapHeader, sizeof(TBmpHeader), 1, fpout);
fwrite(rgbdata16, SSize*2, 1, fpout);
fclose(fpout);
free(rgbdata);
free(rgbdata16);
}
<<- // Code End here
After execute the ConvertBmp32to16() routine, a bitmap image will be generated. The aim of this routine is for keeping alpha value after translation. So, you don't have to confirm the generated image.
Code begin here // ->>
void ConvertBmp16to32(const char *srcfname, const char *dstfname)
{
TBmpHeader MyBitmapHeader;
FILE *finput = fopen(srcfname, “rb”);
if(finput == NULL) return;
fread(&MyBitmapHeader, sizeof(TBmpHeader), 1, finput);
TRGBA * rgbdata;
unsigned short *rgbdata16;
int SSize = MyBitmapHeader.biWidth * MyBitmapHeader.biHeight;
int Size = SSize * 2;
rgbdata16 = (unsigned short *)malloc(Size);
fread(rgbdata16, Size, 1, finput);
fclose(finput);
rgbdata = (TRGBA *)malloc(SSize*4);
unsigned short r, g, b, a;
for(int i=0; i < SSize; i++) {
b = (rgbdata16[i] >> 4) & 0x0f;
g = (rgbdata16[i] >> 8) & 0x0f;
r = (rgbdata16[i] >> 12) & 0x0f;
a = rgbdata16[i] & 0x0f;
rgbdata[i].rgbBlue = b << 4;
rgbdata[i].rgbGreen = g << 4;
rgbdata[i].rgbRed = r << 4;
rgbdata[i].rgbAlpha = a << 4;
}
MyBitmapHeader = FillBitmapHeader(MyBitmapHeader.biWidth, MyBitmapHeader.biHeight, 32);
FILE *fpout = fopen(dstfname, “wb”);
if(fpout == NULL) return;
fwrite(&MyBitmapHeader, sizeof(TBmpHeader), 1, fpout);
fwrite(rgbdata, SSize*4, 1, fpout);
fclose(fpout);
free(rgbdata);
free(rgbdata16);
}
<<- // Code end here
After execute the ConvertBmp16to32() routine, a bitmap image will also be generated. The image color shows
some color loss.
The shown below routine is translation routine which converts 24 bit color into 16 bit color bitmap.
Code begin here // ->>
void ConvertBmp24to16_555(const char *srcfname, const char *dstfname)
{
TBmpHeader MyBitmapHeader;
FILE *finput = fopen(srcfname, “rb”);
if(finput == NULL) return;
fread(&MyBitmapHeader, sizeof(TBmpHeader), 1, finput);
TRGB * rgbdata;
unsigned short *rgbdata16;
int SSize = MyBitmapHeader.biWidth * MyBitmapHeader.biHeight;
int Size = SSize * 3;
rgbdata = (TRGB *)malloc(Size);
fread(rgbdata, Size, 1, finput);
fclose(finput);
rgbdata16 = (unsigned short *)malloc(SSize*2);
unsigned short r, g, b, a;
for(int i=0; i < SSize; i++) {
b = rgbdata[i].rgbBlue >> 3;
g = rgbdata[i].rgbGreen >> 3;
r = rgbdata[i].rgbRed >> 3;
rgbdata16[i] = (r << 10) + (g << 5) + b;
}
MyBitmapHeader = FillBitmapHeader(MyBitmapHeader.biWidth, MyBitmapHeader.biHeight, 16);
FILE *fpout = fopen(dstfname, “wb&rdquo);
if(fpout == NULL) return;
fwrite(&MyBitmapHeader, sizeof(TBmpHeader), 1, fpout);
fwrite(rgbdata16, SSize*2, 1, fpout);
fclose(fpout);
free(rgbdata);
free(rgbdata16);
}
<<- // Code end here
Code begin here // ->>
int main(int argc, char **argv)
{
ConvertBmp32to16(“bitmap32.bmp”, “bitmap16r1.bmp”);
ConvertBmp16to32(“bitmap16r1.bmp”, “bitmap32r1.bmp”);
ConvertBmp24to16_555(“bitmap24.bmp”, “bitmap16r2.bmp”);
return 0;
}
<<- // Code end here
6/17/2009
This will be my second Android game application...
Since, I am trying to complete this application. The application still miss some routines but the routines will be made soon.
6/09/2009
Sphere on my Android emulator...
Both 'setModel()' and 'setModelEX()' methods work with making points of sphere surface. Now I get my drawing sphere routine. I recommend a URL which provides some glut functions that can be used under Android. akjava-android-project
class GLBall {
private int VertexCount, mallocCount;
private FloatBuffer mVertexBuffer;
private FloatBuffer mNormalBuffer;
public float z_angle;
private int slices, stacks;
public GLBall()
{
mVertexBuffer = null;
mNormalBuffer = null;
}
public void setModel(double radius, int lats, int longs)
{
double lat0, z0, zr0, lat1, z1, zr1, lng, x, y;
float normal[];
float vertices[];
int mindex = 0, nindex=0;
VertexCount = (lats+1) * (longs+1) * 2;
mallocCount = VertexCount * 3;
normal = new float[mallocCount];
vertices = new float[mallocCount];
stacks = lats+1;
slices = longs+1;
for(int i = 0; i <= lats; i++) {
lat0 = (double)Math.PI * (-0.5 + (i - 1) / (double)lats);
z0 = (double)Math.sin(lat0) * radius;
zr0 = (double)Math.cos(lat0) * radius;
lat1 = (double)Math.PI * (-0.5 + i / (double)lats);
z1 = (double)Math.sin(lat1) * radius;
zr1 = (double)Math.cos(lat1) * radius;
for(int j = 0; j <= longs; j++) {
lng = 2 * Math.PI * (j - 1) /(double)longs;
x = Math.cos(lng);
y = Math.sin(lng);
normal[nindex++] = vertices[mindex++] = (float)(x * zr0);
normal[nindex++] = vertices[mindex++] = (float)(y * zr0);
normal[nindex++] = vertices[mindex++] = (float)z0;
normal[nindex++] = vertices[mindex++] = (float)(x * zr1);
normal[nindex++] = vertices[mindex++] = (float)(y * zr1);
normal[nindex++] = vertices[mindex++] = (float)z1;
}
}
mVertexBuffer = FloatBuffer.wrap(vertices);
mNormalBuffer = FloatBuffer.wrap(normal);
z_angle = 0.0f;
}
public void setModelEX(float radius, int astacks, int aslices)
{
int i, j, vindex = 0, nindex = 0;
float slicestep, stackstep;
stackstep = ((float)Math.PI) / astacks;
slicestep = 2.0f * ((float)Math.PI) / aslices;
VertexCount = astacks * (aslices+1) * 2;
mallocCount = VertexCount * 3;
float normal[] = new float[mallocCount];
float vertices[] = new float[mallocCount];
for (i = 0; i < astacks; i++)
{
float a = i * stackstep;
float b = a + stackstep;
float s0 = (float)Math.sin(a);
float s1 = (float)Math.sin(b);
float c0 = (float)Math.cos(a);
float c1 = (float)Math.cos(b);
float nv;
for (j = 0; j <= aslices; j++)
{
float c = j * slicestep;
float x = (float)Math.cos(c);
float y = (float)Math.sin(c);
nv=x * s0;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
nv=y * s0;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
nv=c0;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
nv=x * s1;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
nv=y * s1;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
nv=c1;
normal[nindex++] = nv;
vertices[vindex++] = nv * radius;
}
}
mVertexBuffer = FloatBuffer.wrap(vertices);
mNormalBuffer = FloatBuffer.wrap(normal);
z_angle = 0.0f;
this.stacks = astacks;
this.slices = aslices+1;
}
public void draw(GL10 gl) {
int triangles;
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glNormalPointer(GL10.GL_FLOAT, 0, mNormalBuffer);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
triangles = slices * 2;
for(int i=0; i < stacks; i++)
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i*triangles, triangles);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL10.GL_TEXTURE_2D);
}
}
6/06/2009
Drawing sphere again
With Mingw I can use OpenGL function within main.cpp. I tried to use OPenGL function in my sphere.cpp but link error occured When i compiled and linked. So, I moved draw() function into my main.cpp. Once sphere
object is made, then the object will can share and will draw many with different color and angle.
main.cpp>
void drawSphere(TSphere sphere)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, sphere.modelvalue);
glNormalPointer(GL_FLOAT, 0, sphere.normalvalue);
glDrawArrays(GL_QUAD_STRIP, 0, sphere.VertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
sphere.h>
#ifndef __SPHERE_H__
#define __SPHERE_H__
#include
#include
#include
typedef struct {
float x, y, z;
} Vertex3D;
class TSphere {
public:
TSphere();
void SetModelValue(float radius, int slices, int stacks);
public:
int VertexCount;
Vertex3D *modelvalue;
Vertex3D *normalvalue;
};
#endif
sphere.cpp>
#include "sphere.h"
TSphere::TSphere()
{
//
}
void TSphere::SetModelValue(float radius, int slices, int stacks)
{
float lat0, z0, zr0, lat1, z1, zr1, x, y, lng;
int index = 0;
VertexCount = (slices+1) * (stacks+1) * 2;
modelvalue = new Vertex3D[VertexCount];
normalvalue = new Vertex3D[VertexCount];
for(int i = 0; i <= slices; i++) {
lat0 = M_PI * (-0.5 + (i - 1) / (float)slices);
z0 = sin(lat0) * radius;
zr0 = cos(lat0) * radius;
lat1 = M_PI * (-0.5 + i / (float)slices);
z1 = sin(lat1) * radius;
zr1 = cos(lat1) * radius;
for(int j = 0; j <= stacks; j++) {
lng = 2 * M_PI * (j - 1) / stacks;
x = cos(lng);
y = sin(lng);
modelvalue[index].x = x * zr0;
modelvalue[index].y = y * zr0;
modelvalue[index].z = z0;
normalvalue[index].x = x * zr0;
normalvalue[index].y = y * zr0;
normalvalue[index].z = z0;
index++;
modelvalue[index].x = x * zr1;
modelvalue[index].y = y * zr1;
modelvalue[index].z = z1;
normalvalue[index].x = x * zr1;
normalvalue[index].y = y * zr1;
normalvalue[index].z = z1;
index++;
}
}
}
Drawing sphere without glut...
Finally, I got a picture which is about drawing sphere. The routine does not contain glut function and neither glBegin() function. It is very simple to use. I would like to appreciate to http://ozark.hendrix.edu/~burch/cs/490/sched/feb8/. You can get c source code by visiting the url but u can see little bit different.
Probably, I will change this routine to c code and Android Java code ...
For example)
SPhere1 := TSPhere.Create;
SPhere1.SetModelValue(0.75, 8, 8);
in my render() routine...
begin
...
glLoadIdentity;
glTranslatef(-1.5, 0.0, -3.0);
glRotatef(Angle, 1.0, 1.0, -1.0);
glColor3f(0.9, 0.9, 0.9);
SPhere1.Draw();
glColor3f(1.0, 1.0, 1.0);
...
end;
type
TXCustomVertex = packed Record
fX, fY, fZ : single;
end;
TSphere = class
public
Constructor Create;
Procedure Draw();
procedure SetModelValue(r: single; lats, longs : Integer);
protected
private
clats, clongs, vertexCount : Integer;
ModelValue : Array of TXCustomVertex;
NormalValue : Array of TXCustomVertex;
end;
Constructor TSphere.Create;
Begin
//
end;
procedure TSphere.SetModelValue(r: single; lats, longs : Integer);
var
i, j, index : Integer;
lat0, z0, zr0, lat1,z1, zr1, lng, x, y : Single;
begin
clats := lats;
clongs := longs;
vertexCount := (lats+1) * (longs+1) * 2;
SetLength(ModelValue, (lats+1) * (longs+1) * 2);
SetLength(NormalValue, (lats+1) * (longs+1) * 2);
index := 0;
for i := 0 to lats do begin
lat0 := PI * (-0.5 + (i - 1) / lats);
z0 := sin(lat0) * r;
zr0 := cos(lat0) * r;
lat1 := PI * (-0.5 + i / lats);
z1 := sin(lat1) * r;
zr1 := cos(lat1) * r;
for j := 0 to longs do begin
lng := 2 * PI * (j - 1) / longs;
x := cos(lng);
y := sin(lng);
ModelValue[index].fX := x * zr0;
ModelValue[index].fY := y * zr0;
ModelValue[index].fZ := z0;
NormalValue[index].fX := x * zr0;
NormalValue[index].fY := y * zr0;
NormalValue[index].fZ := z0;
index := index + 1;
ModelValue[index].fX := x * zr1;
ModelValue[index].fY := y * zr1;
ModelValue[index].fZ := z1;
NormalValue[index].fX := x * zr1;
NormalValue[index].fY := y * zr1;
NormalValue[index].fZ := z1;
index := index + 1;
end;
end;
end;
Procedure TSphere.Draw();
Begin
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_Float, 0, ModelValue);
glNormalPointer(GL_Float, 0, NormalValue);
glDrawArrays(GL_QUAD_STRIP, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
End;
Subscribe to:
Posts (Atom)