Browse Source

Adding the PNG exemple, cleaning some other MD files.

master
lerabot 4 years ago
parent
commit
cfab852024
  1. 16
      00_dreamcast_101/README.md
  2. 17
      02_drawing_using_GLdc/README.md
  3. 4
      02_drawing_using_GLdc/png_texture/Makefile
  4. 201
      02_drawing_using_GLdc/png_texture/gl_png.c
  5. 27
      02_drawing_using_GLdc/png_texture/gl_png.h
  6. BIN
      02_drawing_using_GLdc/png_texture/gl_png.h.gch
  7. 91
      02_drawing_using_GLdc/png_texture/main.c
  8. BIN
      02_drawing_using_GLdc/png_texture/main.elf
  9. 12
      02_drawing_using_GLdc/png_texture/makeCD.sh
  10. BIN
      02_drawing_using_GLdc/png_texture/romdisk.img
  11. BIN
      02_drawing_using_GLdc/png_texture/romdisk/controller.png
  12. 2
      03_controller_interaction/simple_control/main.c
  13. BIN
      03_controller_interaction/simple_control/main.elf

16
00_dreamcast_101/README.md

@ -1,13 +1,11 @@
# Dreamcast 101
Here are some must have knowledge you need to have before you start Dreamcast programming.
### KallistiOS
The library behind most of the DC homebrew scene is [KallistiOS](http://gamedev.allusion.net/softprj/kos/)(KOS).
In order to get anything running on the DC, we'll need to compile KOS and link it to your code.
The included `makefile` in the 02 folder will do this for you.
There are exemple on how to do this in the **02** folder.
### Programming language
@ -17,13 +15,19 @@ Also, I've been successfully working with LUA within my C code. I might include
### Testing your code
There are many way to test your code. The easiest is to run it in a emulator, this being said, you might run into some strange behaviors once you get your code running on console. There is a `makeCD.sh` script included that will transform your programs into .CDI. These .CDI will work wonderfully with [redream](https://redream.io) or [lxdream](http://www.lxdream.org/download.php) but won't work if you burn them. More on that later.
There are many way to test your code. The easiest is to run it in a emulator, this being said, you might run into some strange behaviors once you get your code running on console.
There is a `makeCD.sh` script included that will transform your programs into .CDI files. These .CDI will work with [redream](https://redream.io) or [lxdream](http://www.lxdream.org/download.php) but won't work if you burn them just yet. You can read more about that in the **07** sections
There will also be a tutorial to get your code on your machine using DC-IP-LOAD
### PVR (graphic chip) info
### PVR
Coming soon
The PVR is the graphic chip in your Dreamcast. It's capable of wonderful thing (for 1999) but it has some limitation. It has 8MB of vram and by default, can only use power of 2 texture (from 8x8 up to 2084x2084) to name only those two. There's multiple ways to use the PVR, KOS gives us a bunch of function in pvr.h, but for the scope of these tutorial we'll be using [GLdc](https://github.com/Kazade/GLdc.git), a modern OpenGL port written by Kazade.
We'll start using GLdc as soon as the **02** tutorial.
You can read more about specs [here](https://segaretro.org/Sega_Dreamcast/Technical_specifications#Graphics)
### Sound chip

17
02_drawing_using_GLdc/README.md

@ -0,0 +1,17 @@
# Drawing using GLDC
[GLdc](https://github.com/Kazade/GLdc) is a openGL implementation for the Dreamcast that is actively developed by Kazade.
**!! Make sure you clone this repo in the `addons` folder !!**
`cd /opt/toolchains/dc/kos/addons`
`git clone https://github.com/Kazade/GLdc.git`
### Building GLDC
Once the folder is cloned
`cd GLdc && make defaultall && make create_kos_link`
You can now link GLdc using -lGLdc

4
02_drawing_using_GLdc/png_texture/Makefile

@ -1,5 +1,5 @@
TARGET = main.elf
OBJS = main.o
OBJS = main.o gl_png.o
KOS_CFLAGS += -std=c99
all: rm-elf $(TARGET)
@ -14,7 +14,7 @@ rm-elf:
$(TARGET): $(OBJS) romdisk.o
$(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o $(TARGET) $(KOS_START) \
$(OBJS) romdisk.o $(KOS_LIBS) -lGLdc -lm
$(OBJS) romdisk.o -lpng -lz -lGLdc -lm $(KOS_LIBS)
romdisk.img:
$(KOS_GENROMFS) -f romdisk.img -d romdisk -v

201
02_drawing_using_GLdc/png_texture/gl_png.c

@ -0,0 +1,201 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <png/png.h>
#include <GL/gl.h>
#include <GL/glkos.h>
#include <GL/glext.h>
#include <GL/glu.h>
#include "gl_png.h"
#define CLEANUP(x) { ret = (x); goto cleanup; }
int png_to_gl_texture(texture *tex, char *filename) {
int ret = 0;
FILE * file = 0;
uint8_t * data = 0;
png_structp parser = 0;
png_infop info = 0;
png_bytep * row_pointers = 0;
png_uint_32 w, h;
int bit_depth;
int color_type;
if(!tex || !filename) {
CLEANUP(1);
}
file = fopen(filename, "rb");
if(!file) {
CLEANUP(2);
}
parser = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if(!parser) {
CLEANUP(3);
}
info = png_create_info_struct(parser);
if(!info) {
CLEANUP(4);
}
if(setjmp(png_jmpbuf(parser))) {
CLEANUP(5);
}
png_init_io(parser, file);
png_read_info(parser, info);
png_get_IHDR(parser, info, &w, &h, &bit_depth, &color_type, 0, 0, 0);
if((w & (w-1)) || (h & (h-1)) || w < 8 || h < 8) {
CLEANUP(6);
}
if(png_get_valid(parser, info, PNG_INFO_tRNS) || (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) || color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_expand(parser);
}
if(bit_depth == 16) {
png_set_strip_16(parser);
}
if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(parser);
}
png_read_update_info(parser, info);
int rowbytes = png_get_rowbytes(parser, info);
rowbytes += 3 - ((rowbytes-1) % 4); // align to 4 bytes
data = malloc(rowbytes * h * sizeof(png_byte) + 15);
if(!data) {
CLEANUP(7);
}
row_pointers = malloc(h * sizeof(png_bytep));
if(!row_pointers) {
CLEANUP(8);
}
// set the individual row_pointers to point at the correct offsets of data
for(png_uint_32 i = 0; i < h; ++i) {
row_pointers[h - 1 - i] = data + i * rowbytes;
}
png_read_image(parser, row_pointers);
// Generate the OpenGL texture object
GLuint texture_id;
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
GLenum texture_format = (color_type & PNG_COLOR_MASK_ALPHA) ? GL_RGBA : GL_RGB;
//GLenum texture_format = GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, texture_format, w, h, 0, texture_format, GL_UNSIGNED_BYTE, data);
tex->id = texture_id;
tex->w = w;
tex->h = h;
tex->u = 0.f;
tex->v = 0.f;
tex->uSize = tex->vSize = 1.f;
tex->xScale = tex->yScale = 1.f;
tex->format = texture_format;
tex->min_filter = tex->mag_filter = GL_LINEAR;
tex->blend_source = GL_SRC_ALPHA;
tex->blend_dest = GL_ONE_MINUS_SRC_ALPHA;
cleanup:
if(parser) {
png_destroy_read_struct(&parser, info ? &info : 0, 0);
}
if(row_pointers) {
free(row_pointers);
}
if(data) {
free(data);
}
if(file) {
fclose(file);
}
return ret;
}
void draw_textured_quad(texture *tex, float x, float y, float z) {
GLfloat texW = 1;
GLfloat texH = 1;
//texW = 10;
//texH = 10;
GLfloat x0 = x - texW / 2;
GLfloat y0 = y - texH / 2;
GLfloat x1 = x + texW / 2;
GLfloat y1 = y + texH / 2;
GLfloat u = tex->u;
GLfloat v = tex->v;
GLfloat xS = tex->uSize;
GLfloat yS = tex->vSize;
GLfloat vertex_data[] = {
/* 2D Coordinate, texture coordinate */
x0, y1, z,
x1, y1, z,
x1, y0, z,
x0, y0, z
};
GLfloat uv_data[] = {
/* 2D Coordinate, texture coordinate */
u, v + yS,
u + xS, v + yS,
u + xS, v,
u, v
};
GLfloat normal_data[] = {
/* 2D Coordinate, texture coordinate */
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0
};
GLfloat color_data[] = {
/* 2D Coordinate, texture coordinate */
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex->id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, vertex_data);
glTexCoordPointer (2, GL_FLOAT, 0, uv_data);
glNormalPointer (GL_FLOAT, 0, normal_data);
glColorPointer (4, GL_FLOAT, 0, color_data);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}

27
02_drawing_using_GLdc/png_texture/gl_png.h

@ -0,0 +1,27 @@
#ifndef __GL_PNG_H__
#define __GL_PNG_H__
#include <GL/gl.h>
typedef struct _texture {
GLuint id; // pointer to the texture ID (usefull for freeing them)
GLenum format; // color format
GLenum min_filter;
GLenum mag_filter;
GLenum blend_source;
GLenum blend_dest;
int w, h; // width / height of texture image
float u, v; // uv Cordinate
float uSize, vSize; // uv Size
float xScale, yScale; // render Scale
float a; // alpha
} texture;
// converts a png into a GL compatible texture.
int png_to_gl_texture(texture *tex, char *filename);
// draws a texture
void draw_textured_quad(texture *tex, float x, float y, float z);
#endif

BIN
02_drawing_using_GLdc/png_texture/gl_png.h.gch

Binary file not shown.

91
02_drawing_using_GLdc/png_texture/main.c

@ -1,11 +1,11 @@
/******************************************************
This is a simple exemple to learn
how to use the controller inputs.
how to draw texture on the screen.
This uses Kazade's GLdc and some part of his NeHe example.
Author: lerabot/magnes
Date : 09/09/2018
Author: lerabot
Date : 12/10/2018
*****************************************************/
#include <kos.h>
#include <GL/gl.h>
@ -13,26 +13,11 @@ Date : 09/09/2018
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include "gl_png.h"
float pos[2]; //rect position
float col[4] = {1.0f, 0.0f, 0.0f, 1.0f}; //rect color
float rot = 0.0f;
float speed = 0.3f; //movement speed
void drawRect(float x, float y) {
glPushMatrix();
glTranslatef(x, y,-20.0f); //Translate the rect to X & Y
glRotatef(rot, 0.0f, 0.0f, 1.0f); //Rotate around the Z axis
glBegin(GL_QUADS); //Start drawing a polygon (4 sided)
glColor3f(col[0], col[1], col[2]);//
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glEnd(); // done with the polygon
glPopMatrix();
}
extern uint8 romdisk[]; //Create a romsick pointer
KOS_INIT_ROMDISK(romdisk); //Init. the romdisk. Everything in the romdisk folder is now located at /rd/ on your DC.
texture t1;
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
@ -57,61 +42,19 @@ int main() {
glKosInit(); //Mandatory function to start KOS and set some GL params
InitGL(640, 480); //Create a "window" at the DC resolution
pos[0] = 0.0f; //position of cursor
pos[1] = 0.0f; //position of cursor
time_t t;
// Intializes random number generator. This is used for the random color
srand((unsigned) time(&t));
png_to_gl_texture(&t1, "/rd/controller.png"); //This function will load a PNG file into a texture <-------------------
float angle = 0.0f;
while(1) {
// Refresh the controller data
cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
// Check key status
state = (cont_state_t *)maple_dev_status(cont);
// If the state/controller is unavailable
if(!state) {
printf("Error reading controller\n");
break;
}
//This is a simple way to use the DPAD
if(state->buttons & CONT_DPAD_LEFT)
pos[0] -= speed;
if(state->buttons & CONT_DPAD_RIGHT)
pos[0] += speed;
if(state->buttons & CONT_DPAD_UP)
pos[1] += speed;
if(state->buttons & CONT_DPAD_DOWN)
pos[1] -= speed;
//Notice how holding A will retrigger this over and over.
//We'll fix that in a future example
if(state->buttons & CONT_A) {
col[0] = rand()%100 / 100.0f;
col[1] = rand()%100 / 100.0f;
col[2] = rand()%100 / 100.0f;
}
//Uncomment if you want to use the joystick to move the rect
//pos[0] = state->joyx / 10.0f;
//pos[1] = -state->joyy / 10.0f;
//Using the ltrig and rtrig is very similar to the joystick.
rot += state->ltrig / 100.0f;
rot -= state->rtrig / 100.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glLoadIdentity(); //Reset The View
drawRect(pos[0], pos[1]); //Draw the rectangle
glKosSwapBuffers(); //Swap buffer (draw the current frame)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glLoadIdentity(); //Reset the View
glPushMatrix(); //Push matrix
glRotatef(angle, 0.0f, 0.0f, 1.0f); //Rotating the canevas
angle += 0.25f; //Increasing the angle
draw_textured_quad(&t1, 0, 0, -5); //Draw the textured rectangle <--------------------------------
glPopMatrix(); //Poping the matrix back in place.
glKosSwapBuffers(); //Swap buffer (draw the current frame)
}
return(0);

BIN
02_drawing_using_GLdc/png_texture/main.elf

Binary file not shown.

12
02_drawing_using_GLdc/png_texture/makeCD.sh

@ -0,0 +1,12 @@
#! /bin/sh
#automating script for making CD games
DIR=$PWD
PROJECT_NAME="project_name"
TARGET="main.elf"
# go to build directory
# make clean
make
lxdream $TARGET

BIN
02_drawing_using_GLdc/png_texture/romdisk.img

Binary file not shown.

BIN
02_drawing_using_GLdc/png_texture/romdisk/controller.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

2
03_controller_interaction/simple_control/main.c

@ -22,7 +22,7 @@ float speed = 0.3f; //movement speed
void drawRect(float x, float y) {
glPushMatrix();
glTranslatef(x, y,-20.0f); //Translate the rect to X & Y
glTranslatef(x, y,-30.0f); //Translate the rect to X & Y
glRotatef(rot, 0.0f, 0.0f, 1.0f); //Rotate around the Z axis
glBegin(GL_QUADS); //Start drawing a polygon (4 sided)
glColor3f(col[0], col[1], col[2]);//

BIN
03_controller_interaction/simple_control/main.elf

Binary file not shown.
Loading…
Cancel
Save