Start implementing a multitexture example
This commit is contained in:
parent
37ba9bf3c3
commit
d36469faaf
|
@ -1,5 +1,4 @@
|
|||
#ifndef GLKOS_H
|
||||
#define GLKOS_H
|
||||
#pragma once
|
||||
|
||||
#include "gl.h"
|
||||
|
||||
|
@ -40,4 +39,3 @@ GLAPI void APIENTRY glKosSwapBuffers();
|
|||
|
||||
__END_DECLS
|
||||
|
||||
#endif // GLKOS_H
|
||||
|
|
|
@ -19,3 +19,4 @@ all:
|
|||
$(KOS_MAKE) -C zclip_trianglestrip all
|
||||
$(KOS_MAKE) -C terrain all
|
||||
$(KOS_MAKE) -C quadmark all
|
||||
$(KOS_MAKE) -C multitexture_arrays all
|
||||
|
|
29
samples/multitexture_arrays/Makefile
Normal file
29
samples/multitexture_arrays/Makefile
Normal file
|
@ -0,0 +1,29 @@
|
|||
TARGET = multitexture_arrays.elf
|
||||
OBJS = main.o pvr-texture.o
|
||||
|
||||
all: rm-elf $(TARGET)
|
||||
|
||||
include $(KOS_BASE)/Makefile.rules
|
||||
|
||||
clean:
|
||||
-rm -f $(TARGET) $(OBJS) romdisk.*
|
||||
|
||||
rm-elf:
|
||||
-rm -f $(TARGET) romdisk.*
|
||||
|
||||
$(TARGET): $(OBJS) romdisk.o
|
||||
$(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o $(TARGET) $(KOS_START) \
|
||||
$(OBJS) romdisk.o $(OBJEXTRA) -lm -lkosutils $(KOS_LIBS)
|
||||
|
||||
romdisk.img:
|
||||
$(KOS_GENROMFS) -f romdisk.img -d romdisk -v
|
||||
|
||||
romdisk.o: romdisk.img
|
||||
$(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o
|
||||
|
||||
run: $(TARGET)
|
||||
$(KOS_LOADER) $(TARGET)
|
||||
|
||||
dist:
|
||||
rm -f $(OBJS) romdisk.o romdisk.img
|
||||
$(KOS_STRIP) $(TARGET)
|
121
samples/multitexture_arrays/main.c
Normal file
121
samples/multitexture_arrays/main.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
main.c
|
||||
(c)2014 Josh Pearson
|
||||
|
||||
Open GL Multi-Texture example using Vertex Array Submission.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gl.h"
|
||||
#include "glu.h"
|
||||
#include "glkos.h"
|
||||
#include "glext.h"
|
||||
|
||||
/* Load a PVR texture - located in pvr-texture.c */
|
||||
extern GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap);
|
||||
|
||||
GLfloat VERTEX_ARRAY[4 * 3] = { -1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
GLfloat TEXCOORD_ARRAY[4 * 2] = { 0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1
|
||||
};
|
||||
|
||||
GLuint ARGB_ARRAY[4 * 1] = { 0xFFFF0000, 0xFF0000FF, 0xFF00FF00, 0xFFFFFF00 };
|
||||
|
||||
|
||||
/* Multi-Texture Example using Open GL Vertex Buffer Submission. */
|
||||
void RenderCallback(GLuint texID0, GLuint texID1) {
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -3.0f);
|
||||
|
||||
/* Enable Client States for OpenGL Arrays Submission */
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
/* Bind texture to GL_TEXTURE0_ARB and set texture parameters */
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texID0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FILTER, GL_LINEAR);
|
||||
|
||||
/* Bind multi-texture to GL_TEXTURE1_ARB and set texture parameters */
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texID1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FILTER, GL_LINEAR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
/* Set Blending Mode */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
|
||||
|
||||
/* Bind texture coordinates to GL_TEXTURE0_ARB */
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORD_ARRAY);
|
||||
|
||||
/* Bind texture coordinates to GL_TEXTURE1_ARB */
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORD_ARRAY);
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
/* Bind the Color Array */
|
||||
glColorPointer(1, GL_UNSIGNED_INT, 0, ARGB_ARRAY);
|
||||
|
||||
/* Bind the Vertex Array */
|
||||
glVertexPointer(3, GL_FLOAT, 0, VERTEX_ARRAY);
|
||||
|
||||
/* Render the Vertices as Indexed Arrays using glDrawArrays */
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
/* Disable GL_TEXTURE1 */
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
/* Make sure to set glActiveTexture back to GL_TEXTURE0_ARB when finished */
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
/* Disable Vertex, Color and Texture Coord Arrays */
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
extern uint8 romdisk[];
|
||||
KOS_INIT_ROMDISK(romdisk);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/* Notice we do not init the PVR here, that is handled by Open GL */
|
||||
glKosInit();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
/* Load two PVR textures to OpenGL */
|
||||
GLuint texID0 = glTextureLoadPVR("/rd/wp001vq.pvr", 0, 0);
|
||||
GLuint texID1 = glTextureLoadPVR("/rd/FlareWS_256.pvr", 0, 0);
|
||||
|
||||
while(1) {
|
||||
/* Draw the "scene" */
|
||||
RenderCallback(texID0, texID1);
|
||||
|
||||
/* Finish the frame - Notice there is no glKosBegin/FinshFrame */
|
||||
glKosSwapBuffers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
175
samples/multitexture_arrays/pvr-texture.c
Normal file
175
samples/multitexture_arrays/pvr-texture.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
pvr-texture.c
|
||||
(c)2014 Josh PH3NOM Pearson
|
||||
|
||||
Load A PVR Texture to the PVR using Open GL
|
||||
*/
|
||||
|
||||
#include <kos.h>
|
||||
|
||||
#include "gl.h"
|
||||
#include "glu.h"
|
||||
#include "glkos.h"
|
||||
#include "glext.h"
|
||||
|
||||
#define PVR_HDR_SIZE 0x20
|
||||
#define MAX(x, y) ((x > y) ? x : y)
|
||||
|
||||
static GLuint PVR_TextureHeight(unsigned char *HDR);
|
||||
static GLuint PVR_TextureWidth(unsigned char *HDR);
|
||||
static GLuint PVR_TextureFormat(unsigned char *HDR);
|
||||
|
||||
static GLuint _glGetMipmapLevelCount(GLuint width, GLuint height) {
|
||||
return 1 + floor(log2(MAX(width, height)));
|
||||
}
|
||||
|
||||
static GLuint _glGetMipmapDataSize(GLuint width, GLuint height) {
|
||||
GLuint size = 0;
|
||||
|
||||
GLuint i = 0;
|
||||
|
||||
for(; i < _glGetMipmapLevelCount(width, height); ++i) {
|
||||
size += (width * height * 2);
|
||||
|
||||
if(width > 1) {
|
||||
width /= 2;
|
||||
}
|
||||
|
||||
if(height > 1) {
|
||||
height /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Load a PVR texture file into memory, and then bind the texture to Open GL.
|
||||
fname is the name of the PVR texture file to be opened and read.
|
||||
isMipMapped should be passed as 1 if the texture contains MipMap levels, 0 otherwise.
|
||||
glMipMap should be passed as 1 if Open GL should calculate the Mipmap levels, 0 otherwise */
|
||||
GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap) {
|
||||
FILE *tex = NULL;
|
||||
uint16 *TEX0 = NULL;
|
||||
uint8 HDR[PVR_HDR_SIZE];
|
||||
GLuint texID, texSize, texW, texH, texFormat;
|
||||
|
||||
/* Open the PVR texture file, and get its file size */
|
||||
tex = fopen(fname, "rb");
|
||||
|
||||
if(tex == NULL) {
|
||||
printf("FILE READ ERROR: %s\n", fname);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
fseek(tex, 0, SEEK_END);
|
||||
texSize = ftell(tex) - PVR_HDR_SIZE;
|
||||
fseek(tex, 0, SEEK_SET);
|
||||
|
||||
/* Read in the PVR texture file header */
|
||||
fread(HDR, 1, PVR_HDR_SIZE, tex);
|
||||
|
||||
/* Extract some information from the PVR texture file header */
|
||||
texW = PVR_TextureWidth(HDR);
|
||||
texH = PVR_TextureHeight(HDR);
|
||||
texFormat = PVR_TextureFormat(HDR);
|
||||
|
||||
/* Allocate Some Memory for the texture. If we are using Open GL to build the MipMap,
|
||||
we need to allocate enough space to hold the MipMap texture levels. */
|
||||
if(!isMipMapped && glMipMap)
|
||||
TEX0 = malloc(_glGetMipmapDataSize(texW, texH));
|
||||
else
|
||||
TEX0 = malloc(texSize);
|
||||
|
||||
fread(TEX0, 1, texSize, tex); /* Read in the PVR texture data */
|
||||
|
||||
/* Generate and bind a texture as normal for Open GL */
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
if(texFormat != GL_UNSIGNED_SHORT_5_6_5)
|
||||
glCompressedTexImage2DARB(GL_TEXTURE_2D,
|
||||
0,
|
||||
texFormat,
|
||||
texW,
|
||||
texH,
|
||||
0,
|
||||
texSize,
|
||||
TEX0);
|
||||
else {
|
||||
fprintf(stderr, "%x\n", texFormat);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB,
|
||||
texW, texH,
|
||||
0,
|
||||
GL_RGB,
|
||||
texFormat,
|
||||
TEX0);
|
||||
if(!isMipMapped && glMipMap)
|
||||
glGenerateMipmapEXT(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
free(TEX0);
|
||||
|
||||
return texID;
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureFormat(unsigned char *HDR) {
|
||||
GLuint color = (GLuint)HDR[PVR_HDR_SIZE - 8];
|
||||
GLuint format = (GLuint)HDR[PVR_HDR_SIZE - 7];
|
||||
|
||||
GLboolean twiddled = format == 0x01;
|
||||
GLboolean compressed = (format == 0x10 || format == 0x03);
|
||||
|
||||
if(compressed) {
|
||||
if(twiddled) {
|
||||
switch(color) {
|
||||
case 0x0: {
|
||||
return GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS;
|
||||
} break;
|
||||
case 0x01: {
|
||||
return GL_COMPRESSED_RGB_565_VQ_TWID_KOS;
|
||||
} break;
|
||||
case 0x02: {
|
||||
return GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid texture format");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch(color) {
|
||||
case 0: {
|
||||
return GL_COMPRESSED_ARGB_1555_VQ_KOS;
|
||||
} break;
|
||||
case 1: {
|
||||
return GL_COMPRESSED_RGB_565_VQ_KOS;
|
||||
} break;
|
||||
case 2: {
|
||||
return GL_COMPRESSED_ARGB_4444_VQ_KOS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid texture format");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(color == 1) {
|
||||
return GL_UNSIGNED_SHORT_5_6_5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureWidth(unsigned char *HDR) {
|
||||
return (GLuint)HDR[PVR_HDR_SIZE - 4] | HDR[PVR_HDR_SIZE - 3] << 8;
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureHeight(unsigned char *HDR) {
|
||||
return (GLuint)HDR[PVR_HDR_SIZE - 2] | HDR[PVR_HDR_SIZE - 1] << 8;
|
||||
}
|
BIN
samples/multitexture_arrays/romdisk/FlareWS_256.pvr
Normal file
BIN
samples/multitexture_arrays/romdisk/FlareWS_256.pvr
Normal file
Binary file not shown.
0
samples/multitexture_arrays/romdisk/PLACEHOLDER
Normal file
0
samples/multitexture_arrays/romdisk/PLACEHOLDER
Normal file
BIN
samples/multitexture_arrays/romdisk/wp001vq.pvr
Normal file
BIN
samples/multitexture_arrays/romdisk/wp001vq.pvr
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user