Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
46e1a9bcc5 | ||
|
09789c9adc | ||
|
713fc0a396 | ||
|
299df08111 | ||
|
e8e0881db8 | ||
|
4d3858d0f0 | ||
|
b2a26e58b3 | ||
|
1baeba1c59 |
99
GL/clip.c
99
GL/clip.c
|
@ -1,4 +1,6 @@
|
|||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "clip.h"
|
||||
|
||||
ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, float* vout, float* t) {
|
||||
|
@ -32,3 +34,100 @@ ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, f
|
|||
return CLIP_RESULT_ALL_ON_PLANE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TriangleClipResult clipTriangleToNearZ(
|
||||
const float plane_dist,
|
||||
const pvr_vertex_t** vertices_in,
|
||||
const float* w_coordinates_in,
|
||||
pvr_vertex_t** vertices_out,
|
||||
float* w_coordinates_out,
|
||||
unsigned char* visible
|
||||
) {
|
||||
const pvr_vertex_t* v1 = vertices_in[0];
|
||||
const pvr_vertex_t* v2 = vertices_in[1];
|
||||
const pvr_vertex_t* v3 = vertices_in[2];
|
||||
|
||||
const float w1 = w_coordinates_in[0];
|
||||
const float w2 = w_coordinates_in[1];
|
||||
const float w3 = w_coordinates_in[2];
|
||||
|
||||
pvr_vertex_t* v1out = vertices_out[0];
|
||||
pvr_vertex_t* v2out = vertices_out[1];
|
||||
pvr_vertex_t* v3out = vertices_out[2];
|
||||
pvr_vertex_t* v4out = vertices_out[3];
|
||||
|
||||
float* w1out = w_coordinates_out[0];
|
||||
float* w2out = w_coordinates_out[1];
|
||||
float* w3out = w_coordinates_out[2];
|
||||
float* w4out = w_coordinates_out[3];
|
||||
|
||||
/* Fast out. Let's just see if everything is in front of the clip plane (and as in OpenGL Z comes out of the screen
|
||||
* we check to see if they are all < -dist
|
||||
*/
|
||||
|
||||
typedef unsigned char uint8;
|
||||
*visible = ((v1->z <= -plane_dist) ? 1 : 0) | ((v2->z <= -plane_dist) ? 2 : 0) | ((v3->z <= -plane_dist) ? 4 : 0);
|
||||
|
||||
switch(*visible) {
|
||||
case 0b000:
|
||||
/* If behind is zero, then none of the vertices are visible */
|
||||
return TRIANGLE_CLIP_RESULT_DROP_TRIANGLE;
|
||||
case 0b111:
|
||||
/* If behind is zero, then none of the vertices are visible */
|
||||
return TRIANGLE_CLIP_RESULT_NO_CHANGE;
|
||||
case 0b101:
|
||||
case 0b110:
|
||||
case 0b011: {
|
||||
/* Two vertices are visible */
|
||||
/* Tricky case. If two vertices are visible then manipulating the other one is going to change the shape of the
|
||||
* triangle. So we have to clip both lines, and output a new vertex.
|
||||
*/
|
||||
|
||||
return TRIANGLE_CLIP_RESULT_ALTERED_AND_CREATED_VERTEX;
|
||||
} break;
|
||||
default: {
|
||||
/* One vertex is visible */
|
||||
/* This is the "easy" case, we simply find the vertex which is visible, and clip the lines to the other 2 against the plane */
|
||||
pvr_vertex_t tmp1, tmp2;
|
||||
float t1, t2;
|
||||
|
||||
if(visible == 0b001) {
|
||||
clipLineToNearZ(&v1->x, &v2->x, plane_dist, &tmp1.x, &t1);
|
||||
clipLineToNearZ(&v1->x, &v3->x, plane_dist, &tmp2.x, &t2);
|
||||
|
||||
*v1out = *v1;
|
||||
*v2out = tmp1;
|
||||
*v3out = tmp2;
|
||||
|
||||
*w1out = w1;
|
||||
*w2out = w1 + ((w2 - w1) * t1);
|
||||
*w3out = w1 + ((w3 - w1) * t2);
|
||||
} else if(visible == 0b010) {
|
||||
clipLineToNearZ(&v2->x, &v1->x, plane_dist, &tmp1.x, &t1);
|
||||
clipLineToNearZ(&v2->x, &v3->x, plane_dist, &tmp2.x, &t2);
|
||||
|
||||
*v1out = tmp1;
|
||||
*v2out = *v2;
|
||||
*v3out = tmp2;
|
||||
|
||||
*w1out = w2 + ((w1 - w2) * t1);
|
||||
*w2out = w2;
|
||||
*w3out = w2 + ((w3 - w2) * t2);
|
||||
} else {
|
||||
clipLineToNearZ(&v3->x, &v1->x, plane_dist, &tmp1.x, &t1);
|
||||
clipLineToNearZ(&v3->x, &v2->x, plane_dist, &tmp2.x, &t2);
|
||||
|
||||
*v1out = tmp1;
|
||||
*v2out = tmp2;
|
||||
*v3out = *v3;
|
||||
|
||||
*w1out = w3 + ((w3 - w1) * t1);
|
||||
*w2out = w3 + ((w3 - w2) * t2);
|
||||
*w3out = w3;
|
||||
}
|
||||
|
||||
return TRIANGLE_CLIP_RESULT_ALTERED_VERTICES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
47
GL/clip.h
47
GL/clip.h
|
@ -5,6 +5,24 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* If we're not on the Dreamcast then define pvr_vertex_t
|
||||
* (this if for testing only)
|
||||
*/
|
||||
#ifndef _arch_dreamcast
|
||||
typedef struct {
|
||||
uint32 flags; /**< \brief TA command (vertex flags) */
|
||||
float x; /**< \brief X coordinate */
|
||||
float y; /**< \brief Y coordinate */
|
||||
float z; /**< \brief Z coordinate */
|
||||
float u; /**< \brief Texture U coordinate */
|
||||
float v; /**< \brief Texture V coordinate */
|
||||
uint32 argb; /**< \brief Vertex color */
|
||||
uint32 oargb; /**< \brief Vertex offset color */
|
||||
} pvr_vertex_t;
|
||||
#else
|
||||
#include <dc/pvr.h>
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CLIP_RESULT_ALL_IN_FRONT,
|
||||
CLIP_RESULT_ALL_BEHIND,
|
||||
|
@ -15,6 +33,35 @@ typedef enum {
|
|||
|
||||
ClipResult clipLineToNearZ(const float* v1, const float* v2, const float dist, float* vout, float* t);
|
||||
|
||||
|
||||
/* There are 4 possible situations we'll hit when clipping triangles:
|
||||
*
|
||||
* 1. The entire triangle was in front of the near plane, so we do nothing
|
||||
* 2. The entire triangle was behind the near plane, so we drop it completely
|
||||
* 3. One vertex was behind the clip plane. In this case we need to create a new vertex and an additional triangle
|
||||
* 4. Two vertices were behind the clip plane, we can simply move them so the triangle no longer intersects
|
||||
*/
|
||||
typedef enum {
|
||||
TRIANGLE_CLIP_RESULT_NO_CHANGE,
|
||||
TRIANGLE_CLIP_RESULT_DROP_TRIANGLE,
|
||||
TRIANGLE_CLIP_RESULT_ALTERED_AND_CREATED_VERTEX,
|
||||
TRIANGLE_CLIP_RESULT_ALTERED_VERTICES
|
||||
} TriangleClipResult;
|
||||
|
||||
/* Clips a triangle from a triangle strip to a near-z plane. Alternating triangles in a strip switch vertex ordering
|
||||
* so the number of the triangle must be passed in (vn - 2).
|
||||
*
|
||||
* Note that clipping a triangle with a plane may create a quadrilateral, so this function must have
|
||||
* a space to output the 4th vertex.
|
||||
*
|
||||
* The outputs can be the same as the inputs.
|
||||
*/
|
||||
TriangleClipResult clipTriangleToNearZ(
|
||||
const float plane_dist, const pvr_vertex_t** vertices_in, const float* w_coordinates_in,
|
||||
pvr_vertex_t* vertices_out, float* w_coordinates_out,
|
||||
unsigned char* visible
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
212
GL/draw.c
212
GL/draw.c
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../include/gl.h"
|
||||
#include "../include/glext.h"
|
||||
|
@ -70,20 +71,24 @@ static GLuint byte_size(GLenum type) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transformVertex(GLfloat* src, float* x, float* y, float* z) {
|
||||
register float __x __asm__("fr12");
|
||||
register float __y __asm__("fr13");
|
||||
register float __z __asm__("fr14");
|
||||
static GLfloat transformVertexWithoutPerspectiveDivide(GLfloat* src, float* x, float* y, float* z) {
|
||||
register float __x __asm__("fr12") = (src[0]);
|
||||
register float __y __asm__("fr13") = (src[1]);
|
||||
register float __z __asm__("fr14") = (src[2]);
|
||||
register float __w __asm__("fr15");
|
||||
|
||||
__x = src[0];
|
||||
__y = src[1];
|
||||
__z = src[2];
|
||||
|
||||
mat_trans_fv12()
|
||||
__asm__ __volatile__(
|
||||
"fldi1 fr15\n"
|
||||
"ftrv xmtrx, fv12\n"
|
||||
: "=f" (__x), "=f" (__y), "=f" (__z)
|
||||
: "0" (__x), "1" (__y), "2" (__z)
|
||||
);
|
||||
|
||||
*x = __x;
|
||||
*y = __y;
|
||||
*z = __z;
|
||||
|
||||
return __w;
|
||||
}
|
||||
|
||||
static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type) {
|
||||
|
@ -190,6 +195,8 @@ inline void transformNormalToEyeSpace(GLfloat* normal) {
|
|||
mat_trans_normal3(normal[0], normal[1], normal[2]);
|
||||
}
|
||||
|
||||
/* If this has a value other than zero, it must be positive! */
|
||||
#define NEAR_DEPTH 0.0001f
|
||||
|
||||
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||
static GLfloat normal[3] = {0.0f, 0.0f, -1.0f};
|
||||
|
@ -202,13 +209,18 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
|||
|
||||
const GLsizei elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count;
|
||||
|
||||
// Point dest at the first new vertex to populate. This is the size of the container before extending,
|
||||
// with the additional space for the header.
|
||||
GLsizei start_of_output = activePolyList()->vector.size + 1;
|
||||
|
||||
AlignedVector* list_vector = &activePolyList()->vector;
|
||||
|
||||
// Make room for the element + the header
|
||||
PVRCommand* dst = (PVRCommand*) aligned_vector_extend(&activePolyList()->vector, count + 1);
|
||||
PVRCommand* dst = (PVRCommand*) aligned_vector_extend(list_vector, count + 1);
|
||||
|
||||
// Store a pointer to the header
|
||||
pvr_poly_hdr_t* hdr = (pvr_poly_hdr_t*) dst;
|
||||
|
||||
// Point dest at the first new vertex to populate
|
||||
dst++;
|
||||
|
||||
// Compile
|
||||
|
@ -236,7 +248,26 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
|||
GLboolean lighting_enabled = isLightingEnabled();
|
||||
|
||||
GLushort i, last_vertex;
|
||||
for(i = first; i < count; ++i) {
|
||||
GLshort rel; // Has to be signed as we drop below zero so we can re-enter the loop at 1.
|
||||
|
||||
static AlignedVector w_coordinates;
|
||||
static GLboolean w_coordinates_initialized = GL_FALSE;
|
||||
if(!w_coordinates_initialized) {
|
||||
aligned_vector_init(&w_coordinates, sizeof(GLfloat));
|
||||
w_coordinates_initialized = GL_TRUE;
|
||||
}
|
||||
aligned_vector_resize(&w_coordinates, 0);
|
||||
|
||||
static struct {
|
||||
pvr_vertex_t* vin[3];
|
||||
GLfloat w[3];
|
||||
GLubyte vcount;
|
||||
} Triangle;
|
||||
|
||||
Triangle.vcount = 0;
|
||||
|
||||
/* Loop 1. Calculate vertex colours, transform, but don't apply perspective division */
|
||||
for(rel = 0, i = first; i < first + count; ++i, ++rel) {
|
||||
pvr_vertex_t* vertex = (pvr_vertex_t*) dst;
|
||||
vertex->u = vertex->v = 0.0f;
|
||||
vertex->argb = 0;
|
||||
|
@ -308,25 +339,158 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
|||
}
|
||||
|
||||
_applyRenderMatrix(); /* Apply the Render Matrix Stack */
|
||||
transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z);
|
||||
|
||||
/* The PVR doesn't support quads, only triangle strips, so we need to
|
||||
* swap the last two vertices of each set */
|
||||
if(last_vertex && mode == GL_QUADS) {
|
||||
/* This vertex becomes the previous vertex so store it*/
|
||||
pvr_vertex_t tmp = *vertex;
|
||||
tmp.flags = PVR_CMD_VERTEX;
|
||||
/* Perform transformation without perspective division. Perspective divide will occur
|
||||
* per-triangle after clipping */
|
||||
GLfloat W = transformVertexWithoutPerspectiveDivide(&vertex->x, &vertex->x, &vertex->y, &vertex->z);
|
||||
|
||||
/* Overwrite this vertex with the previous one, make it last */
|
||||
*vertex = *(vertex - 1);
|
||||
vertex->flags = PVR_CMD_VERTEX_EOL;
|
||||
Triangle.w[Triangle.vcount] = W;
|
||||
Triangle.vin[Triangle.vcount] = vertex;
|
||||
Triangle.vcount++;
|
||||
if(Triangle.vcount == 3) {
|
||||
pvr_vertex_t clipped[4];
|
||||
float clipped_w[4];
|
||||
GLubyte visible; /* Bitmask of which of the 3 input vertices are visible */
|
||||
|
||||
/* Now make the previous one the original last one */
|
||||
*(vertex - 1) = tmp;
|
||||
/* OK we have a whole triangle, we may have to clip */
|
||||
TriangleClipResult tri_result = clipTriangleToNearZ(
|
||||
NEAR_DEPTH,
|
||||
Triangle.vin,
|
||||
Triangle.w,
|
||||
clipped,
|
||||
clipped_w,
|
||||
&visible
|
||||
);
|
||||
|
||||
/* The potential 4 new vertices that can be output by clipping the triangle. Initialized in the below branches */
|
||||
pvr_vertex_t* vout[4];
|
||||
|
||||
if(tri_result == TRIANGLE_CLIP_RESULT_NO_CHANGE) {
|
||||
/* Nothing changed, we're fine */
|
||||
} else if(tri_result == TRIANGLE_CLIP_RESULT_DROP_TRIANGLE) {
|
||||
/* As we're dealing with triangle strips, we have the following situations:
|
||||
* 1. This is the first trangle. We can drop the first vertex, reverse the other two, subsequent
|
||||
* triangles will be formed from them. If there are no remaining vertices (i == count - 1) then
|
||||
* we can drop all three.
|
||||
* 2. This is the second+ triangle. We mark the second triangle vertex as the "last" vertex, then
|
||||
* push the second and third vertices again (reversed) to start the new triangle. If there are no
|
||||
* more vertices (i == count - 1) we can just drop the final vertex.
|
||||
* By first triangle, it means that rel == 2 or dst - 3 is marked as a "last" vertex.
|
||||
*/
|
||||
|
||||
/* Is this the first triangle in the strip? */
|
||||
GLboolean first_triangle = (rel == 2) || ((vertex - 3)->flags == PVR_CMD_VERTEX_EOL);
|
||||
if(first_triangle) {
|
||||
vout[0] = vertex - 2;
|
||||
vout[1] = vertex - 1;
|
||||
vout[2] = vertex;
|
||||
|
||||
if(rel == (count - 1)) {
|
||||
/* Lose all 3 vertices */
|
||||
aligned_vector_resize(list_vector, list_vector->size - 3);
|
||||
dst -= 3;
|
||||
vertex = (pvr_vertex_t*) dst;
|
||||
|
||||
/* Next triangle is a new one */
|
||||
Triangle.vcount = 0;
|
||||
} else {
|
||||
vout[0] = vout[2];
|
||||
/* vout[1] = vout[1]; no-op, just here as a comment so things make a bit more sense */
|
||||
|
||||
/* Rewind dst by one as we just lost a vertex */
|
||||
aligned_vector_resize(list_vector, list_vector->size - 1);
|
||||
dst--;
|
||||
vertex = (pvr_vertex_t*) dst;
|
||||
|
||||
/* Two vertices are populated for the current triangle now */
|
||||
Triangle.vcount = 2;
|
||||
}
|
||||
} else {
|
||||
if(rel == (count - 1)) {
|
||||
/* This is the last vertex in the strip and we're dropping this triangle so just drop a vertex*/
|
||||
aligned_vector_resize(list_vector, list_vector->size - 1);
|
||||
dst--;
|
||||
vertex = (pvr_vertex_t*) dst;
|
||||
} else {
|
||||
/* This is a bit weird. We're dropping a triangle, but we have to add an additional vertex. This is because
|
||||
* if this triangle is in the middle of the strip, and we drop the 3rd vertex then we break the following triangle.
|
||||
* so what we do is end the triangle strip at vertex 2 of the current triangle, then re-add vertex 2 and vertex 3
|
||||
* in reverse so that the next triangle works. This might seem wasteful but actually that triangle could be subsequently
|
||||
* dropped entirely as it'll be the "first_triangle" next time around. */
|
||||
|
||||
/* Make room at the end of the vector */
|
||||
aligned_vector_extend(list_vector, 1);
|
||||
|
||||
/* Deal with any realloc that just happened */
|
||||
dst = aligned_vector_at(list_vector, rel);
|
||||
vertex = (pvr_vertex_t*) dst;
|
||||
|
||||
/* Set up the output pointers */
|
||||
vout[0] = vertex - 2;
|
||||
vout[1] = vertex - 1;
|
||||
vout[2] = vertex;
|
||||
vout[3] = vertex + 3;
|
||||
|
||||
/* Mark second vertex as the end of the strip, duplicate the second vertex
|
||||
* to create the start of the next strip
|
||||
*/
|
||||
*vout[3] = *Triangle.vin[1];
|
||||
|
||||
vout[1]->flags = PVR_CMD_VERTEX_EOL;
|
||||
vout[2]->flags = PVR_CMD_VERTEX;
|
||||
vout[3]->flags = PVR_CMD_VERTEX;
|
||||
|
||||
dst = (PVRCommand*) vout[3];
|
||||
vertex = vout[3];
|
||||
|
||||
/* Current triangle has two vertices */
|
||||
Triangle.vcount = 2;
|
||||
}
|
||||
}
|
||||
} else if(tri_result == TRIANGLE_CLIP_RESULT_ALTERED_VERTICES) {
|
||||
/* We're here because a single vertex was visible, the other two vertices were changed */
|
||||
|
||||
|
||||
} else if(tri_result == TRIANGLE_CLIP_RESULT_ALTERED_AND_CREATED_VERTEX) {
|
||||
|
||||
}
|
||||
|
||||
/* Reset for the next triangle */
|
||||
Triangle.vin[0] = Triangle.vin[1];
|
||||
Triangle.vin[1] = Triangle.vin[2];
|
||||
Triangle.w[0] = Triangle.w[1];
|
||||
Triangle.w[1] = Triangle.w[2];
|
||||
Triangle.vcount = 2;
|
||||
}
|
||||
|
||||
++dst;
|
||||
}
|
||||
|
||||
pvr_vertex_t* v = (pvr_vertex_t*) aligned_vector_at(list_vector, start_of_output);
|
||||
|
||||
/* Loop 2: Perspective division */
|
||||
for(rel = 0, i = start_of_output; i < activePolyList()->vector.size; ++rel, ++i) {
|
||||
GLfloat* w = aligned_vector_at(&w_coordinates, rel);
|
||||
|
||||
register float __x __asm__("fr12") = (v->x);
|
||||
register float __y __asm__("fr13") = (v->y);
|
||||
register float __z __asm__("fr14") = (v->z);
|
||||
register float __w __asm__("fr15") = (*w);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"fldi1 fr14\n" \
|
||||
"fdiv fr15, fr14\n" \
|
||||
"fmul fr14, fr12\n" \
|
||||
"fmul fr14, fr13\n" \
|
||||
: "=f" (__x), "=f" (__y), "=f" (__z)
|
||||
: "0" (__x), "1" (__y), "2" (__z)
|
||||
);
|
||||
|
||||
v->x = __x;
|
||||
v->y = __y;
|
||||
v->z = __z;
|
||||
++v;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../include/gl.h"
|
||||
#include "../containers/aligned_vector.h"
|
||||
#include "../containers/named_array.h"
|
||||
|
||||
#include "./clip.h"
|
||||
|
||||
#define TRACE_ENABLED 0
|
||||
|
|
|
@ -14,3 +14,5 @@ all:
|
|||
$(KOS_MAKE) -C ortho2d all
|
||||
$(KOS_MAKE) -C lerabot01 all
|
||||
$(KOS_MAKE) -C zclip all
|
||||
$(KOS_MAKE) -C zclip1 all
|
||||
$(KOS_MAKE) -C zclip2 all
|
||||
|
|
29
samples/zclip1/Makefile
Normal file
29
samples/zclip1/Makefile
Normal file
|
@ -0,0 +1,29 @@
|
|||
TARGET = zclip1.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)
|
68
samples/zclip1/main.c
Normal file
68
samples/zclip1/main.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#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
|
||||
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
|
||||
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
/* Draw a triangle intersecting the screen with a single vertex visible */
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex3f(0.0f, 0.0f, -5.0f);
|
||||
glVertex3f(-0.5f, -1.0f, 5.0f);
|
||||
glVertex3f(0.5, -1.0f, 5.0f);
|
||||
glEnd();
|
||||
|
||||
// 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;
|
||||
}
|
0
samples/zclip1/romdisk/PLACEHOLDER
Normal file
0
samples/zclip1/romdisk/PLACEHOLDER
Normal file
29
samples/zclip2/Makefile
Normal file
29
samples/zclip2/Makefile
Normal file
|
@ -0,0 +1,29 @@
|
|||
TARGET = zclip2.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)
|
79
samples/zclip2/main.c
Normal file
79
samples/zclip2/main.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
#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_LESS); // The Type Of Depth Test To Do
|
||||
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
|
||||
|
||||
// draw a triangle
|
||||
glBegin(GL_POLYGON); // start drawing a polygon
|
||||
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
|
||||
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
glEnd(); // we're done with the polygon
|
||||
|
||||
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
|
||||
|
||||
// draw a square (quadrilateral)
|
||||
glBegin(GL_QUADS); // start drawing a polygon (4 sided)
|
||||
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
|
||||
|
||||
// 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;
|
||||
}
|
0
samples/zclip2/romdisk/PLACEHOLDER
Normal file
0
samples/zclip2/romdisk/PLACEHOLDER
Normal file
Loading…
Reference in New Issue
Block a user