Merge branch 'master' into 'experimental'

Added a new blend/alpha test

See merge request simulant/GLdc!57
This commit is contained in:
Luke Benstead 2020-05-14 06:05:02 +00:00
commit 3945611509
19 changed files with 588 additions and 11 deletions

BIN
include/glkos.h.gch Normal file

Binary file not shown.

View File

@ -63,23 +63,29 @@ void DrawGLScene()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0, 0, -10.0f); // Move Left 1.5 Units And Into The Screen 6.0
glPushMatrix();
glTranslatef(-4.0, 0, -10);
DrawQuad(RED);
glPopMatrix();
glTranslatef(4.0, 0, 0);
// LEFT SECTION
// This should draw 2 quad, a red first, then and overlapping blue one.
// This section draw both quad at the same Z value
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Draw 3 overlapping quads, 2 of which should be totally transparent so the
* output should be the third */
DrawQuad(NONE);
DrawQuad(NONE);
DrawQuad(RED);
glTranslatef(1.0, 0, 0);
DrawQuad(BLUE);
glDisable(GL_BLEND);
glTranslatef(4.0, 0, 0);
// RIGHT SECTION
// This should draw 2 quad, a red first, then and overlapping blue one.
// This section uses a LOWER Z VALUE(-0.01f), so the blue quad should be in FRONT of the red quad.
// lerabot's note : changing the z value to positive gives the desired output.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawQuad(RED);
glTranslatef(1.0, 0, -0.01);
DrawQuad(BLUE);
glDisable(GL_BLEND);
glKosSwapBuffers();

View File

@ -0,0 +1,30 @@
TARGET = depth_funcs.elf
OBJS = main.o gl_png.o
KOS_CFLAGS += -std=c99
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)

View File

@ -0,0 +1,237 @@
#include <kos.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.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; }
GLfloat global_diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat global_ambient[] = {1.0, 1.0, 1.0, 1.0};
int dtex_to_gl_texture(texture *tex, char* filename) {
// Load Texture
Image *image;
// allocate space for texture
image = (Image *) malloc(sizeof(Image));
if (image == NULL) {
printf("No memory for .DTEX file\n");
return(0);
}
FILE* file = NULL;
// make sure the file is there.
if ((file = fopen(filename, "rb")) == NULL)
{
printf("File not found");
return 0;
}
struct {
char id[4]; // 'DTEX'
GLushort width;
GLushort height;
GLuint type;
GLuint size;
} header;
fread(&header, sizeof(header), 1, file);
GLboolean twiddled = (header.type & (1 << 26)) < 1;
GLboolean compressed = (header.type & (1 << 30)) > 0;
GLboolean mipmapped = (header.type & (1 << 31)) > 0;
GLboolean strided = (header.type & (1 << 25)) > 0;
GLuint format = (header.type >> 27) & 0b111;
image->data = (char *) malloc (header.size);
image->sizeX = header.width;
image->sizeY = header.height;
image->dataSize = header.size;
GLuint expected = 2 * header.width * header.height;
GLuint ratio = (GLuint) (((GLfloat) expected) / ((GLfloat) header.size));
fread(image->data, image->dataSize, 1, file);
fclose(file);
if(compressed) {
printf("Compressed - ");
if(twiddled) {
printf("Twiddled - ");
switch(format) {
case 0: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS;
} else {
image->internalFormat = GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS;
}
} break;
case 1: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS;
} else {
image->internalFormat = GL_COMPRESSED_RGB_565_VQ_TWID_KOS;
}
} break;
case 2: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_TWID_KOS;
} else {
image->internalFormat = GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS;
}
}
break;
default:
fprintf(stderr, "Invalid texture format");
return 0;
}
} else {
switch(format) {
case 0: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_KOS;
} else {
image->internalFormat = GL_COMPRESSED_ARGB_1555_VQ_KOS;
}
} break;
case 1: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_RGB_565_VQ_MIPMAP_KOS;
} else {
image->internalFormat = GL_COMPRESSED_RGB_565_VQ_KOS;
}
} break;
case 2: {
if(mipmapped) {
image->internalFormat = GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_KOS;
} else {
image->internalFormat = GL_COMPRESSED_ARGB_4444_VQ_KOS;
}
}
break;
default:
fprintf(stderr, "Invalid texture format");
return 0;
}
}
} else {
printf("Uncompressed - ");
//printf("Color:%u -", format);
switch(format) {
case 0:
image->internalFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS;
//image->internalFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case 1:
image->internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV;
break;
case 2:
image->internalFormat = GL_UNSIGNED_SHORT_4_4_4_4_REV;
break;
}
}
printf("\n");
// Create Texture
GLuint texture_id;
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id); // 2d texture (x and y size)
GLint newFormat = format;
GLint colorType = GL_RGB;
if (image->internalFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS ||
image->internalFormat == GL_UNSIGNED_SHORT_4_4_4_4_REV){
newFormat = GL_BGRA;
colorType = GL_RGBA;
printf("Reversing RGBA\n");
}
if (image->internalFormat == GL_UNSIGNED_SHORT_5_6_5_REV){
newFormat = GL_RGB;
colorType = GL_RGB;
printf("Reversing RGB\n");
}
glTexImage2D(GL_TEXTURE_2D, 0,
colorType, image->sizeX, image->sizeY, 0,
newFormat, image->internalFormat, image->data);
tex->id = texture_id;
tex->w = image->sizeX;
tex->h = image->sizeY;
tex->u = 0.f;
tex->v = 0.f;
tex->a = tex->light = 1;
tex->color[0] = tex->color[1] = tex->color[2] = 1.0f;
tex->uSize = tex->vSize = 1.0f;
tex->xScale = tex->yScale = 1.0f;
tex->format = image->internalFormat;
tex->min_filter = tex->mag_filter = GL_NEAREST;
tex->blend_source = GL_SRC_ALPHA;
tex->blend_dest = GL_ONE_MINUS_SRC_ALPHA;
strcpy(tex->path, filename);
printf("Texture size: %d x %d\n", image->sizeX, image->sizeY);
printf("Texture ratio: %d\n", ratio);
printf("Texture size: %d x %d\n", image->sizeX, image->sizeY);
printf("Texture %s loaded\n", tex->path);
return(1);
};
void draw_textured_quad(texture *tex) {
if(glIsTexture(tex->id)) {
GLfloat vertex_data[] = {
/* 2D Coordinate, texture coordinate */
0, 1, 0,
1, 1, 0,
1, 0, 0,
0, 0, 0
};
GLfloat uv_data[] = {
/* 2D Coordinate, texture coordinate */
0, 1,
1, 1,
1, 0,
0, 0
};
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
};
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex->id);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, vertex_data);
glTexCoordPointer (2, GL_FLOAT, 0, uv_data);
glNormalPointer (GL_FLOAT, 0, normal_data);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_TEXTURE_2D);
}
}

View File

@ -0,0 +1,42 @@
#ifndef __GL_PNG_H__
#define __GL_PNG_H__
#include <stdio.h>
#include <kos.h>
#include <GL/gl.h>
typedef struct _texture {
GLuint id;
GLenum format;
GLenum min_filter;
GLenum mag_filter;
GLenum blend_source;
GLenum blend_dest;
int loaded;
uint16_t w, h; // width / height of texture image
int size[2];
float u, v; //uv COORD
float uSize, vSize; // uvSize
float xScale, yScale; //render scale
float a; //alpha
float light; //alpha
float color[3];
char path[32];
} texture;
/* DTEX Image type - contains height, width, and data */
typedef struct Image {
unsigned long sizeX;
unsigned long sizeY;
char *data;
GLenum internalFormat;
GLboolean mipmapped;
unsigned int dataSize;
} Image;
int dtex_to_gl_texture(texture *tex, char* filename);
void draw_textured_quad(texture *tex);
#endif

Binary file not shown.

View File

@ -0,0 +1,110 @@
#include "gl.h"
#include "glu.h"
#include "glkos.h"
#include "gl_png.h"
//$KOS_BASE/utils/texconv/texconv --in disk.png --format ARGB4444 --preview disk_preview.png --out disk.dtex
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
texture t;
int blendActive = -1;
/* floats for x rotation, y rotation, z rotation */
float xrot, yrot, zrot;
/* 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.
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height == 0) // Prevent A Divide By Zero If The Window Is Too Small
Height = 1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
void DrawSquare(float width, float r, float g, float b, float z) {
width /= 2;
glColor3f(r, g, b);
glBegin(GL_QUADS); // start drawing a polygon (4 sided)
glVertex3f(-width, width, z); // Top Left
glVertex3f( width, width, z); // Top Right
glVertex3f( width,-width, z); // Bottom Right
glVertex3f(-width,-width, z); // Bottom Left
glEnd(); // done with the polygon
}
/* The main drawing function. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
//First Batch is alpha blending
glTranslated(-1 ,0, -5);
for (int i = 0; i < 5; i++) {
glTranslated(0.5, 0, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
draw_textured_quad(&t);
glDisable(GL_BLEND);
}
//Second batch is depth testing
//Changing the translate Z value doesn't change anything?
glLoadIdentity();
glTranslated(-1 , -1, -5);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_FUNC);
for (int i = 0; i < 5; i++) {
glTranslated(0.5, 0, -0.2);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
draw_textured_quad(&t);
glDisable(GL_BLEND);
}
glDisable(GL_DEPTH_TEST);
// swap buffers to display, since we're double buffered.
glKosSwapBuffers();
}
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
//loads a dtex texture. see the /romdisk folder for more files
dtex_to_gl_texture(&t, "/rd/disk_1555.dtex");
ReSizeGLScene(640, 480);
DrawGLScene();
while(1) {
DrawGLScene();
}
return 0;
}

View File

@ -0,0 +1,17 @@
#! /bin/sh
FILE=$1
FILE_FLIP="$1_flip.png"
FILE_PATH=${FILE%/*}
echo $FILE_PATH
convert $FILE -flip $FILE_FLIP
$KOS_BASE/utils/texconv/texconv --in $FILE_FLIP --format ARGB1555 --preview $FILE_PATH/preview_1555.png --out $FILE_PATH/disk_1555.dtex
$KOS_BASE/utils/texconv/texconv --in $FILE_FLIP --format RGB565 --preview $FILE_PATH/preview_565.png --out $FILE_PATH/disk_565.dtex
$KOS_BASE/utils/texconv/texconv --in $FILE_FLIP --format ARGB4444 --preview $FILE_PATH/preview_4444.png --out $FILE_PATH/disk_4444.dtex
rm $FILE_FLIP
#rm $FILE_FLIP

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,29 @@
TARGET = blend_test.elf
OBJS = main.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)

View File

@ -0,0 +1,106 @@
/*
* This sample is to demonstrate a bug where rendering an unblended
* polygon, before a series of blended ones would result in no blended
* output and incorrect depth testing
*/
#include "gl.h"
#include "glu.h"
#include "glkos.h"
/* 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.
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glDisable(GL_BLEND);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height == 0) // Prevent A Divide By Zero If The Window Is Too Small
Height = 1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
void DrawQuad(const float* colour) {
glBegin(GL_QUADS);
glColor4fv(colour);
glVertex3f(-1.0,-1.0, 0.0);
glVertex3f( 1.0,-1.0, 0.0);
glVertex3f( 1.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
}
/* The main drawing function. */
void DrawGLScene()
{
const float RED [] = {1.0, 0, 0, 0.5};
const float BLUE [] = {0.0, 0, 1, 0.5};
const float NONE [] = {0, 0, 0, 0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(-4.0, 0, -10);
// LEFT SECTION
// This should draw 2 quad, a red first, then and overlapping blue one.
// This section draw both quad at the same Z value
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawQuad(RED);
glTranslatef(1.0, 0, 0);
DrawQuad(BLUE);
glDisable(GL_BLEND);
glTranslatef(4.0, 0, 0);
// RIGHT SECTION
// This should draw 2 quad, a red first, then and overlapping blue one.
// This section uses a LOWER Z VALUE(-0.01f), so the blue quad should be in FRONT of the red quad.
// lerabot's note : changing the z value to positive gives the desired output.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawQuad(RED);
glTranslatef(1.0, 0, -0.01);
DrawQuad(BLUE);
glDisable(GL_BLEND);
glKosSwapBuffers();
}
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
ReSizeGLScene(640, 480);
while(1) {
DrawGLScene();
}
return 0;
}