Merge pull request #16 from Kazade/near-z-v2

Implement near-z clipping
This commit is contained in:
Luke Benstead 2018-07-15 19:54:34 +01:00 committed by GitHub
commit 7874f7862a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 636 additions and 63 deletions

289
GL/clip.c
View File

@ -1,5 +1,10 @@
#include <float.h>
#include <stdio.h>
#include <dc/pvr.h>
#include "clip.h"
#include "../containers/aligned_vector.h"
ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, float* vout, float* t) {
if(v1[2] < dist && v2[2] < dist) {
@ -32,3 +37,287 @@ ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, f
return CLIP_RESULT_ALL_ON_PLANE;
}
}
static void interpolateFloat(const float v1, const float v2, const float t, float* out) {
*out = v1 + (v2 - v1) * t;
}
static void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
out[0] = v1[0] + (v2[0] - v1[0]) * t;
out[1] = v1[1] + (v2[1] - v1[1]) * t;
}
static void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
out[0] = v1[0] + (v2[0] - v1[0]) * t;
out[1] = v1[1] + (v2[1] - v1[1]) * t;
out[2] = v1[2] + (v2[2] - v1[2]) * t;
}
static void interpolateColour(const uint32_t* c1, const uint32_t* c2, const float t, uint32_t* out) {
float r1 = (*c1 >> 16) & 0xFF;
float r2 = (*c2 >> 16) & 0xFF;
uint8_t r = (r1 + (r2 - r1) * t);
r1 = (*c1 >> 24) & 0xFF;
r2 = (*c2 >> 24) & 0xFF;
uint8_t a = (r1 + (r2 - r1) * t);
r1 = (*c1 >> 8) & 0xFF;
r2 = (*c2 >> 8) & 0xFF;
uint8_t g = (r1 + (r2 - r1) * t);
r1 = (*c1 >> 0) & 0xFF;
r2 = (*c2 >> 0) & 0xFF;
uint8_t b = (r1 + (r2 - r1) * t);
*out = (a << 24 | r << 16 | g << 8 | b);
}
const uint32_t VERTEX_CMD_EOL = 0xf0000000;
const uint32_t VERTEX_CMD = 0xe0000000;
void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
/* Clipping triangle strips is *hard* this is the algorithm we follow:
*
* - Treat each triangle in the strip individually.
* - If we find a triangle that needs clipping, treat it in isolation.
* - End the strip at the triangle
* - Generate a new single-triangle strip for it
* - Begin a new strip for the remainder of the strip
*
* There is probably more efficient way but there are so many different cases to handle that it's
* difficult to even write them down!
*/
/* FIXME: Why this value? This was copied from libGL because using zero wasn't working right.
*
* I think this is a hack. We should really be clipping against the W coordinate of each vertex... but I'm not sure
* how yet..
*/
const float CLIP_DISTANCE = -0.2;
uint32_t i;
for(i = 2; i < vertices->size; ++i) {
ClipVertex* sourceTriangle[3] = {
aligned_vector_at(vertices, i - 2),
aligned_vector_at(vertices, i - 1),
aligned_vector_at(vertices, i)
};
/* If we're on an odd vertex, we need to swap the order of the first two vertices, as that's what
* triangle strips do */
uint8_t even = i % 2 == 0;
ClipVertex* v1 = even ? sourceTriangle[0] : sourceTriangle[1];
ClipVertex* v2 = even ? sourceTriangle[1] : sourceTriangle[0];
ClipVertex* v3 = sourceTriangle[2];
uint8_t visible = ((v1->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v3->w > 0) ? 1 : 0);
uint8_t startOfStrip = (i == 2) || (outBuffer->size > 2 && ((ClipVertex*) aligned_vector_back(outBuffer))->flags == VERTEX_CMD_EOL);
/* All visible, we're fine! */
if(visible == 0b111) {
if(startOfStrip) {
aligned_vector_push_back(outBuffer, v1, 1);
aligned_vector_push_back(outBuffer, v2, 1);
}
aligned_vector_push_back(outBuffer, v3, 1);
} else if(visible == 0b000) {
/* Do nothing */
continue;
} else if(visible == 0b100) {
/* Only the first vertex is visible */
float t1 = 0, t2 = 0;
ClipVertex output[3];
clipLineToNearZ(v1->xyz, v2->xyz, CLIP_DISTANCE, output[1].xyz, &t1);
clipLineToNearZ(v1->xyz, v3->xyz, CLIP_DISTANCE, output[2].xyz, &t2);
interpolateFloat(v1->w, v2->w, t1, &output[1].w);
interpolateFloat(v1->w, v3->w, t2, &output[2].w);
output[0] = *v1;
/* Interpolate normals */
interpolateVec3(v1->nxyz, v2->nxyz, t1, output[1].nxyz);
interpolateVec3(v1->nxyz, v3->nxyz, t2, output[2].nxyz);
/* Interpolate texcoords */
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[1].argb);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 3);
} else if(visible == 0b010) {
/* Only the second vertex is visible */
float t1 = 0, t2 = 0;
ClipVertex output[3];
clipLineToNearZ(v2->xyz, v1->xyz, CLIP_DISTANCE, output[0].xyz, &t1);
clipLineToNearZ(v2->xyz, v3->xyz, CLIP_DISTANCE, output[2].xyz, &t2);
interpolateFloat(v2->w, v1->w, t1, &output[0].w);
interpolateFloat(v2->w, v3->w, t2, &output[2].w);
output[1] = *v2;
/* Interpolate normals */
interpolateVec3(v2->nxyz, v1->nxyz, t1, output[0].nxyz);
interpolateVec3(v2->nxyz, v3->nxyz, t2, output[2].nxyz);
/* Interpolate texcoords */
interpolateVec2(v2->uv, v1->uv, t1, output[0].uv);
interpolateVec2(v2->uv, v3->uv, t2, output[2].uv);
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v1->argb, t1, (uint32_t*) &output[0].argb);
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 3);
} else if(visible == 0b001) {
/* Only the third vertex is visible */
float t1 = 0, t2 = 0;
ClipVertex output[3];
clipLineToNearZ(v3->xyz, v1->xyz, CLIP_DISTANCE, output[0].xyz, &t1);
clipLineToNearZ(v3->xyz, v2->xyz, CLIP_DISTANCE, output[1].xyz, &t2);
interpolateFloat(v3->w, v1->w, t1, &output[0].w);
interpolateFloat(v3->w, v2->w, t2, &output[1].w);
output[2] = *v3;
/* Interpolate normals */
interpolateVec3(v3->nxyz, v1->nxyz, t1, output[0].nxyz);
interpolateVec3(v3->nxyz, v2->nxyz, t2, output[1].nxyz);
/* Interpolate texcoords */
interpolateVec2(v3->uv, v1->uv, t1, output[0].uv);
interpolateVec2(v3->uv, v2->uv, t2, output[1].uv);
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v1->argb, t1, (uint32_t*) &output[0].argb);
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v2->argb, t2, (uint32_t*) &output[1].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 3);
} else if(visible == 0b110) {
/* Third vertex isn't visible */
float t1 = 0, t2 = 0;
ClipVertex output[4];
clipLineToNearZ(v2->xyz, v3->xyz, CLIP_DISTANCE, output[2].xyz, &t1);
clipLineToNearZ(v1->xyz, v3->xyz, CLIP_DISTANCE, output[3].xyz, &t2);
interpolateFloat(v2->w, v3->w, t1, &output[2].w);
interpolateFloat(v1->w, v3->w, t2, &output[3].w);
output[0] = *v1;
output[1] = *v2;
/* Interpolate normals */
interpolateVec3(v2->nxyz, v3->nxyz, t1, output[2].nxyz);
interpolateVec3(v1->nxyz, v3->nxyz, t2, output[3].nxyz);
/* Interpolate texcoords */
interpolateVec2(v2->uv, v3->uv, t1, output[2].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[3].uv);
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v3->argb, t1, (uint32_t*) &output[2].argb);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[3].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD;
output[3].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 4);
} else if(visible == 0b011) {
/* First vertex isn't visible, so let's clip along the lines to the second and third */
float t1 = 0, t2 = 0;
ClipVertex output[4];
clipLineToNearZ(v1->xyz, v2->xyz, CLIP_DISTANCE, output[0].xyz, &t1);
clipLineToNearZ(v1->xyz, v3->xyz, CLIP_DISTANCE, output[2].xyz, &t2);
interpolateFloat(v1->w, v2->w, t1, &output[0].w);
interpolateFloat(v1->w, v3->w, t2, &output[2].w);
output[1] = *v2;
output[3] = *v3;
/* Interpolate normals */
interpolateVec3(v1->nxyz, v2->nxyz, t1, output[0].nxyz);
interpolateVec3(v1->nxyz, v3->nxyz, t2, output[2].nxyz);
/* Interpolate texcoords */
interpolateVec2(v1->uv, v2->uv, t1, output[0].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[0].argb);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD;
output[3].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 4);
} else if(visible == 0b101) {
/* Second vertex isn't visible */
float t1 = 0, t2 = 0;
ClipVertex output[4];
clipLineToNearZ(v1->xyz, v2->xyz, CLIP_DISTANCE, output[1].xyz, &t1);
clipLineToNearZ(v3->xyz, v2->xyz, CLIP_DISTANCE, output[3].xyz, &t2);
interpolateFloat(v1->w, v2->w, t1, &output[1].w);
interpolateFloat(v3->w, v2->w, t2, &output[3].w);
output[0] = *v1;
output[2] = *v3;
/* Interpolate normals */
interpolateVec3(v1->nxyz, v2->nxyz, t1, output[1].nxyz);
interpolateVec3(v3->nxyz, v2->nxyz, t2, output[3].nxyz);
/* Interpolate texcoords */
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
interpolateVec2(v3->uv, v2->uv, t2, output[3].uv);
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[1].argb);
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v2->argb, t2, (uint32_t*) &output[3].argb);
output[0].flags = VERTEX_CMD;
output[1].flags = VERTEX_CMD;
output[2].flags = VERTEX_CMD;
output[3].flags = VERTEX_CMD_EOL;
aligned_vector_push_back(outBuffer, output, 4);
}
}
}

View File

@ -1,6 +1,10 @@
#ifndef CLIP_H
#define CLIP_H
#include <stdint.h>
#include "../containers/aligned_vector.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -13,8 +17,34 @@ typedef enum {
CLIP_RESULT_BACK_TO_FRONT
} ClipResult;
typedef struct {
uint8_t a;
uint8_t r;
uint8_t g;
uint8_t b;
} ClipColour;
/* Note: This structure is the almost the same format as pvr_vertex_t aside from the offet
* (oargb) which is replaced by the floating point w value. This is so that we can
* simply zero it and memcpy the lot into the output */
typedef struct {
uint32_t flags;
float xyz[3];
float uv[2];
ClipColour argb;
float nxyz[3];
float w;
float xyzES[3]; /* Coordinate in eye space */
float nES[3]; /* Normal in eye space */
} ClipVertex;
ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, float* vout, float* t);
void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer);
#ifdef __cplusplus
}
#endif

View File

@ -150,6 +150,8 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) {
x = __x; y = __y; z = __z; \
}
/* FIXME: Is this right? Shouldn't it be fr12->15? */
#undef mat_trans_normal3
#define mat_trans_normal3(x, y, z) { \
register float __x __asm__("fr8") = (x); \
@ -165,42 +167,16 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) {
}
inline void transformToEyeSpace(GLfloat* point) {
static inline void transformToEyeSpace(GLfloat* point) {
_matrixLoadModelView();
mat_trans_single3_nodiv(point[0], point[1], point[2]);
}
inline void transformNormalToEyeSpace(GLfloat* normal) {
static inline void transformNormalToEyeSpace(GLfloat* normal) {
_matrixLoadNormal();
mat_trans_normal3(normal[0], normal[1], normal[2]);
}
typedef struct {
uint8_t a;
uint8_t r;
uint8_t g;
uint8_t b;
} Colour;
/* Note: This structure is the almost the same format as pvr_vertex_t aside from the offet
* (oargb) which is replaced by the floating point w value. This is so that we can
* simply zero it and memcpy the lot into the output */
typedef struct {
uint32_t flags;
float xyz[3];
float uv[2];
Colour argb;
float nxyz[3];
float w;
float xyzES[3]; /* Coordinate in eye space */
float nES[3]; /* Normal in eye space */
} ClipVertex;
static void swapVertex(ClipVertex* v1, ClipVertex* v2) {
ClipVertex tmp = *v1;
*v1 = *v2;
@ -300,9 +276,10 @@ static void transform(AlignedVector* vertices) {
register float __x __asm__("fr12") = (vertex->xyz[0]);
register float __y __asm__("fr13") = (vertex->xyz[1]);
register float __z __asm__("fr14") = (vertex->xyz[2]);
register float __w __asm__("fr15") = 1.0f;
register float __w __asm__("fr15");
__asm__ __volatile__(
"fldi1 fr15\n"
"ftrv xmtrx,fv12\n"
: "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w)
: "0" (__x), "1" (__y), "2" (__z), "3" (__w)
@ -317,6 +294,27 @@ static void transform(AlignedVector* vertices) {
static void clip(AlignedVector* vertices) {
/* Perform clipping, generating new vertices as necessary */
static AlignedVector* CLIP_BUFFER = NULL;
/* First entry into this, allocate the clip buffer */
if(!CLIP_BUFFER) {
CLIP_BUFFER = (AlignedVector*) malloc(sizeof(AlignedVector));
aligned_vector_init(CLIP_BUFFER, sizeof(ClipVertex));
}
/* Make sure we allocate roughly enough space */
aligned_vector_reserve(CLIP_BUFFER, vertices->size);
/* Start from empty */
aligned_vector_resize(CLIP_BUFFER, 0);
/* Now perform clipping! */
clipTriangleStrip(vertices, CLIP_BUFFER);
/* Copy the clip buffer over the vertices */
aligned_vector_resize(vertices, CLIP_BUFFER->size);
memcpy(vertices->data, CLIP_BUFFER->data, CLIP_BUFFER->size * CLIP_BUFFER->element_size);
}
static void mat_transform3(const float* xyz, const float* xyzOut, const uint32_t count, const uint32_t stride) {
@ -385,7 +383,7 @@ static void light(AlignedVector* vertices) {
}
uint32_t final = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]);
vertex->argb = *((Colour*) &final);
vertex->argb = *((ClipColour*) &final);
}
}
@ -465,8 +463,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
generate(buffer, mode, first, count, (GLubyte*) indices, type, vptr, vstride, cptr, cstride, uvptr, uvstride, nptr, nstride);
light(buffer);
transform(buffer);
clip(buffer);
divide(buffer);
push(buffer, activePolyList());
}

View File

@ -1,6 +1,7 @@
#include <string.h>
#include <dc/matrix.h>
#include <stdio.h>
#include "../include/gl.h"
#include "../containers/stack.h"
@ -19,7 +20,6 @@ static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_heig
static Stack MATRIX_STACKS[3]; // modelview, projection, texture
static matrix_t NORMAL_MATRIX __attribute__((aligned(32)));
static matrix_t SCREENVIEW_MATRIX __attribute__((aligned(32)));
static matrix_t RENDER_MATRIX __attribute__((aligned(32)));
static GLenum MATRIX_MODE = GL_MODELVIEW;
static GLubyte MATRIX_IDX = 0;
@ -163,9 +163,9 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right,
/* Ortho Matrix */
static matrix_t OrthoMatrix __attribute__((aligned(32))) = {
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
@ -275,27 +275,30 @@ void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
gl_viewport_width = width;
gl_viewport_height = height;
/* Calculate the viewport scale and offset */
gl_viewport_scale[0] = (GLfloat)width / 2.0f;
gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x;
gl_viewport_scale[1] = (GLfloat)height / 2.0f;
gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y;
gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f;
gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f;
GLfloat rw = x + width;
GLfloat lw = x;
GLfloat tw = y + height;
GLfloat bw = y;
gl_viewport_offset[2] += 0.0001f;
GLfloat hw = ((GLfloat) width) / 2.0f;
GLfloat hh = ((GLfloat) height) / 2.0f;
/* Set the Screenview Matrix based on the viewport */
SCREENVIEW_MATRIX[0][0] = gl_viewport_scale[0];
SCREENVIEW_MATRIX[1][1] = -gl_viewport_scale[1];
SCREENVIEW_MATRIX[2][2] = 1;
SCREENVIEW_MATRIX[3][0] = gl_viewport_offset[0];
SCREENVIEW_MATRIX[3][1] = vid_mode->height - gl_viewport_offset[1];
SCREENVIEW_MATRIX[0][0] = hw;
SCREENVIEW_MATRIX[1][1] = -hh;
SCREENVIEW_MATRIX[2][2] = 1; //(gl_depthrange_far - gl_depthrange_near) / 2.0f;
SCREENVIEW_MATRIX[3][0] = (rw + lw) / 2.0f;
SCREENVIEW_MATRIX[3][1] = (tw + bw) / 2.0f;
// SCREENVIEW_MATRIX[3][2] = (gl_depthrange_far + gl_depthrange_near) / 2.0f;
}
/* Set the depth range */
void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
/* clamp the values... */
/* FIXME: This currently does nothing because the SCREENVIEW_MATRIX is multiplied prior to perpective division
* and not after as traditional GL. See here for more info: http://www.thecodecrate.com/opengl-es/opengl-viewport-matrix/
*
* We probably need to make tweaks to the SCREENVIEW matrix or clipping or whatever to make this work
*/
if(n < 0.0f) n = 0.0f;
else if(n > 1.0f) n = 1.0f;
@ -304,10 +307,6 @@ void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
gl_depthrange_near = n;
gl_depthrange_far = f;
/* Adjust the viewport scale and offset for Z */
gl_viewport_scale[2] = ((f - n) / 2.0f);
gl_viewport_offset[2] = (n + f) / 2.0f;
}
/* Vector Cross Product - Used by glhLookAtf2 */
@ -386,11 +385,6 @@ void _applyRenderMatrix() {
mat_load(&SCREENVIEW_MATRIX);
mat_apply(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
mat_store(&RENDER_MATRIX);
}
void _matrixLoadRender() {
mat_load(&RENDER_MATRIX);
}
void _matrixLoadTexture() {

View File

@ -74,7 +74,6 @@ void initFramebuffers();
void _matrixLoadNormal();
void _matrixLoadModelView();
void _matrixLoadTexture();
void _matrixLoadRender();
void _applyRenderMatrix();
void wipeTextureOnFramebuffers(GLuint texture);

View File

@ -70,6 +70,10 @@ void* aligned_vector_at(const AlignedVector* vector, const unsigned int index) {
return &vector->data[index * vector->element_size];
}
void* aligned_vector_back(AlignedVector* vector) {
return aligned_vector_at(vector, vector->size - 1);
}
void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) {
const unsigned int current = vector->size;
aligned_vector_resize(vector, vector->size + additional_count);

View File

@ -23,6 +23,7 @@ void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional
void aligned_vector_clear(AlignedVector* vector);
void aligned_vector_shrink_to_fit(AlignedVector* vector);
void aligned_vector_cleanup(AlignedVector* vector);
void* aligned_vector_back(AlignedVector* vector);
#ifdef __cplusplus
}

View File

@ -14,3 +14,5 @@ all:
$(KOS_MAKE) -C ortho2d all
$(KOS_MAKE) -C lerabot01 all
$(KOS_MAKE) -C zclip all
$(KOS_MAKE) -C zclip_triangle all
$(KOS_MAKE) -C zclip_trianglestrip all

View File

@ -144,6 +144,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
@ -205,9 +206,9 @@ void RenderFloor() {
glBindTexture(GL_TEXTURE_2D, road.texID);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-100, 0, -0.0);
glVertex3f(-100, 0, 0);
glTexCoord2f(50.0f, 0.0f);
glVertex3f( 100, 0, -0.0);
glVertex3f( 100, 0, 0);
glTexCoord2f(50.0f, 100.0f);
glVertex3f( 100, 0, -200.0);
glTexCoord2f(0.0f, 100.0f);

View File

@ -0,0 +1,29 @@
TARGET = zclip_triangle.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,98 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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, 0.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
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glEnable(GL_TEXTURE_2D);
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);
glLoadIdentity();
}
/* 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);
}
/* The main drawing function. */
void DrawGLScene()
{
static GLfloat movement = 0.0f;
static GLboolean increasing = GL_TRUE;
if(movement > 10.0) {
increasing = GL_FALSE;
} else if(movement < -10.0f) {
increasing = GL_TRUE;
}
if(increasing) {
movement += 0.05f;
} else {
movement -= 0.05f;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glDisable(GL_CULL_FACE);
glPushMatrix();
glTranslatef(0.0f, -1.0f, movement);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, -5.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-2.5f, 0.0f, 5.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(2.5f, 0.0f, 5.0f);
glEnd();
glPopMatrix();
// swap buffers to display, since we're double buffered.
glKosSwapBuffers();
}
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
ReSizeGLScene(640, 480);
while(1) {
DrawGLScene();
}
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -0,0 +1,29 @@
TARGET = zclip_trianglestrip.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,99 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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, 0.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
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glEnable(GL_TEXTURE_2D);
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);
glLoadIdentity();
}
/* 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);
}
/* The main drawing function. */
void DrawGLScene()
{
static GLfloat movement = 0.0f;
static GLboolean increasing = GL_TRUE;
if(movement > 10.0) {
increasing = GL_FALSE;
} else if(movement < -10.0f) {
increasing = GL_TRUE;
}
if(increasing) {
movement += 0.05f;
} else {
movement -= 0.05f;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glPushMatrix();
glTranslatef(0.0f, -1.0f, movement);
glBegin(GL_TRIANGLE_STRIP);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-2.5f, 0.0f, -5.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-2.5f, 0.0f, 5.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(2.5f, 0.0f, -5.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(2.5f, 0.0f, 5.0f);
glEnd();
glPopMatrix();
// swap buffers to display, since we're double buffered.
glKosSwapBuffers();
}
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
ReSizeGLScene(640, 480);
while(1) {
DrawGLScene();
}
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB