Files
c-prime/application/source/engine/mesh.c

703 lines
12 KiB
C
Raw Normal View History

2025-11-17 10:28:09 +01:00
#define GL_GLEXT_PROTOTYPES
#include <GL/glext.h>
#include <GL/gl.h> // GL 1.1 functions
#include <GL/glx.h>
#include "block.h"
#include "shader.h"
#include "program.h"
#include "floatArray.h"
#include "unsignedIntegerArray.h"
class mesh{
struct program * program;
struct unsignedIntegerArray * indices;
struct floatArray * textureCoordinates;
struct floatArray * vertexCoordinates;
struct floatArray * normalCoordinates;
struct array * blocks = new array();
GLuint vertexArrayObject;
GLuint uniformBuffer;
GLuint indexBuffer;
GLuint vertexbuffer;
GLuint textureCoordinateBuffer;
GLuint meshIndexBuffer;
GLuint uvBuffer;
struct unsignedIntegerArray * uniformBuffers = new unsignedIntegerArray();
struct block * getUniformBlock( char * blockName ) {
int blockCount = this->blocks->length();
for ( int i = 0; i < blockCount; ++i )
{
struct block * currentBlock = this->blocks->get( i );
char * currentBlockName = currentBlock->name;
if( currentBlockName == blockName ) {
return currentBlock;
}
}
return NULL;
}
void bindBlock( struct block * blockInstance ) {
//printf("%s\n", blockInstance);
blockInstance->createBuffer();
this->blocks->add( blockInstance );
}
void setProgram( struct program * currentProgram ) {
this->program = currentProgram;
}
GLuint getGLTypeSize( GLuint type ) {
switch( type ) {
case GL_FLOAT:
return sizeof( GLfloat );
break;
case GL_INT:
return sizeof( GLint );
break;
case GL_UNSIGNED_INT:
return sizeof( GLuint );
break;
}
return 0;
}
GLuint getComponentType( GLuint type ) {
switch( type ) {
case GL_FLOAT:
return GL_FLOAT;
break;
case GL_FLOAT_VEC2:
return GL_FLOAT;
break;
case GL_FLOAT_VEC3:
return GL_FLOAT;
break;
case GL_FLOAT_VEC4:
return GL_FLOAT;
break;
case GL_INT:
return GL_INT;
break;
case GL_INT_VEC2:
return GL_INT;
break;
case GL_INT_VEC3:
return GL_INT;
break;
case GL_INT_VEC4:
return GL_INT;
break;
case GL_UNSIGNED_INT:
return GL_UNSIGNED_INT;
break;
case GL_UNSIGNED_INT_VEC2:
return GL_UNSIGNED_INT;
break;
case GL_UNSIGNED_INT_VEC3:
return GL_UNSIGNED_INT;
break;
case GL_UNSIGNED_INT_VEC4:
return GL_UNSIGNED_INT;
break;
}
return 0;
}
GLuint getItemSize( GLuint type ) {
switch( type ) {
case GL_FLOAT:
return 1;
break;
case GL_FLOAT_VEC2:
return 2;
break;
case GL_FLOAT_VEC3:
return 3;
break;
case GL_FLOAT_VEC4:
return 4;
break;
case GL_INT:
return 1;
break;
case GL_INT_VEC2:
return 2;
break;
case GL_INT_VEC3:
return 3;
break;
case GL_INT_VEC4:
return 4;
break;
case GL_UNSIGNED_INT:
return 1;
break;
case GL_UNSIGNED_INT_VEC2:
return 2;
break;
case GL_UNSIGNED_INT_VEC3:
return 3;
break;
case GL_UNSIGNED_INT_VEC4:
return 4;
break;
}
return 0;
}
GLuint createBuffer( char * attributeName, void * data, GLenum target, GLenum usage ) {
GLuint itemSize;
GLuint componentType;
GLuint componentSize;
GLuint attributeLocation;
//GLenum target;
GLuint isIndexBuffer = 0;
GLuint buffer;
glGenBuffers( 1, &buffer );
if( attributeName == "index" ) {
isIndexBuffer = 1;
componentType = GL_INT;
componentSize = this->getGLTypeSize( componentType );
target = GL_ELEMENT_ARRAY_BUFFER;
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffer );
} else {
attribute * attribute = this->program->getAttributeByName( attributeName );
if( attribute == NULL ) {
return 0;
}
itemSize = this->getItemSize( attribute->type );
componentType = this->getComponentType( attribute->type );
componentSize = this->getGLTypeSize( componentType );
attributeLocation = attribute->location;
target = GL_ARRAY_BUFFER;
glEnableVertexAttribArray( attribute->location );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
}
//printf("Name: %s itemSize: %i componentSize: %i ", attributeName, itemSize, componentSize);
int itemCount;
GLuint bufferSize;
if( componentType == GL_UNSIGNED_INT || componentType == GL_INT ) {
unsignedIntegerArray * test = ( unsignedIntegerArray * ) data;
itemCount = test->length();
bufferSize = itemCount * componentSize;
glBufferData( target, bufferSize, test->items, usage );
if( isIndexBuffer == NULL ) {
glVertexAttribIPointer( attributeLocation, itemSize, componentType, 0, ( void * ) 0 );
}
} else if( componentType == GL_FLOAT ) {
floatArray * test = ( floatArray * ) data;
itemCount = test->total;
bufferSize = itemCount * componentSize;
glBufferData( GL_ARRAY_BUFFER, bufferSize, test->items, usage );
if( isIndexBuffer == NULL ) {
glVertexAttribPointer( attributeLocation, itemSize, componentType, GL_FALSE, 0, ( void * ) 0 );
}
}
//printf("itemCount: %i\n\n", bufferSize);
GLint compareSize = 0;
glGetBufferParameteriv( target, GL_BUFFER_SIZE, &compareSize );
if( bufferSize != compareSize )
{
glDeleteBuffers(1, &buffer);
printf("ERROR: size error");
return 0;
}
return buffer;
}
void createBuffers( ) {
struct unsignedIntegerArray * indices = new unsignedIntegerArray();
struct floatArray * textureCoordinates = new floatArray();
struct floatArray * vertexCoordinates = new floatArray();
struct floatArray * normalCoordinates = new floatArray();
struct unsignedIntegerArray * meshIndices = new unsignedIntegerArray();
int subdivisionsDepth = 1;
int subdivisionsWidth = 1;
float width = 2;
float depth = 2;
int meshCount = 100 * 50;
int meshStartIndex = 0;
for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex)
{
meshStartIndex = meshIndices->length();
//printf("Number of vectex cnumVertsAcrossoordinates: %i\n\n", vertexCoordinates->length());
int numVertsAcross = subdivisionsWidth + 1;
for ( int z = 0; z < subdivisionsDepth; z++ ) {
for ( int x = 0; x < subdivisionsWidth; x++ ) {
// triangle 1 of quad
indices->add( ( z + 0 ) * numVertsAcross + x + meshStartIndex );
indices->add( ( z + 1 ) * numVertsAcross + x + meshStartIndex );
indices->add( ( z + 0 ) * numVertsAcross + x + 1 + meshStartIndex );
// triangle 2 of quad
indices->add( ( z + 1 ) * numVertsAcross + x + meshStartIndex );
indices->add( ( z + 1 ) * numVertsAcross + x + 1 + meshStartIndex );
indices->add( ( z + 0 ) * numVertsAcross + x + 1 + meshStartIndex );
}
}
for ( int z = 0; z <= subdivisionsDepth; z++ ) {
for ( int x = 0; x <= subdivisionsWidth; x++ ) {
float u = ( float ) x;// / subdivisionsWidth;
float v = ( float ) z;// / subdivisionsDepth;
textureCoordinates->add( u );
textureCoordinates->add( ( 1 - v ) );
vertexCoordinates->add( width * u - width * 0.5 );
vertexCoordinates->add( depth * v - depth * 0.5 );
vertexCoordinates->add( 0 );
normalCoordinates->add( 0 );
normalCoordinates->add( 0 );
normalCoordinates->add( 1 );
meshIndices->add( meshIndex );
}
}
}
glGenVertexArrays( 1, &this->vertexArrayObject );
glBindVertexArray( this->vertexArrayObject );
this->vertexbuffer = this->createBuffer( "position", vertexCoordinates, GL_ARRAY_BUFFER, GL_STATIC_DRAW );
this->textureCoordinateBuffer = this->createBuffer( "textureCoordinates", textureCoordinates, GL_ARRAY_BUFFER, GL_STATIC_DRAW );
this->vertexbuffer = this->createBuffer( "meshIndex", meshIndices, GL_ARRAY_BUFFER, GL_STATIC_DRAW );
this->indexBuffer = this->createBuffer( "index", indices, GL_ARRAY_BUFFER, GL_STATIC_DRAW );
//this->subMeshPositions = this->createBuffer( "subMeshPositions", indices, GL_SHADER_STORAGE_BUFFER, GL_STATIC_DRAW );
int blockCount = this->blocks->length();
for (int i = 0; i < blockCount; ++i)
{
block * currentBlock = this->blocks->get( i );
int size = currentBlock->bufferSize;
printf("Bind block %s bufferSize: %i bindingPoint: %i bufferType: %s \n\n", currentBlock->name, currentBlock->bufferSize, currentBlock->bindingPoint, currentBlock->getBufferTypeText( ) );
glBindBuffer( currentBlock->bufferType, currentBlock->buffer );
glBindBufferBase( currentBlock->bufferType, currentBlock->bindingPoint, currentBlock->buffer );
glBufferData( currentBlock->bufferType, currentBlock->bufferSize, 0, GL_DYNAMIC_DRAW );
}
glBindVertexArray( 0 );
/*
unsigned int uniformBufferSize = 152; // allocate 152 bytes of memory
glGenBuffers( 1, &this->uniformBuffer );
glBindBuffer( GL_UNIFORM_BUFFER, this->uniformBuffer );
glBufferData( GL_UNIFORM_BUFFER, uniformBufferSize, NULL, GL_DYNAMIC_DRAW );
glBindBuffer( GL_UNIFORM_BUFFER, this->uniformBuffer );
//glBufferData( this->uniformBuffer, size, data );
glBufferSubData( this->uniformBuffer, offset, size, data );
*/
//glBindBufferRange( GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4) );
/*
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glm::mat4 view = camera.GetViewMatrix();
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
glBindBuffer(GL_UNIFORM_BUFFER, 0); */
//glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, indexBufferSize, indices->items );
/*
int vertexCount = vertexCoordinates->length();
for (int i = 0; i < vertexCount; ++i)
{
float currentVertex = vertexCoordinates->get( i );
printf(" %i: %f \n", i, currentVertex);
}
int indexCount = indices->length();
printf("\n\n");
for (int i = 0; i < indexCount; ++i)
{
int currentIndex = indices->get( i );
printf(" %i: %i \n", i, currentIndex);
}
printf("number of indices: %i\n", indices->length());
*/
this->indices = indices;
this->textureCoordinates = textureCoordinates;
this->vertexCoordinates = vertexCoordinates;
this->normalCoordinates = normalCoordinates;
}
createOrderedTriangleStripQuad() {
/*
vector3 * a = new vector3(0.0, 0.0, 0.0);
vector3 * b = new vector3(0.0, 0.5, 0.0);
vector3 * c = new vector3(0.5, 0.0, 0.0);
vector3 * d = new vector3(0.5, 0.5, 0.0);
GLfloat g_vertex_buffer_data[ 12 * 2 ];
for (int i = 0; i < 2; ++i)
{
int vectorIndex = i * 3;
float index = 0.5 *i;
g_vertex_buffer_data[ vectorIndex + 0 ] = 0.0 - index;
g_vertex_buffer_data[ vectorIndex + 1 ] = 0.;
g_vertex_buffer_data[ vectorIndex + 2 ] = 0.0;
g_vertex_buffer_data[ vectorIndex + 3 ] = 0.0 - index;
g_vertex_buffer_data[ vectorIndex + 4 ] = 0.5;
g_vertex_buffer_data[ vectorIndex + 5 ] = 0.0;
g_vertex_buffer_data[ vectorIndex + 6 ] = 0.5 - index;
g_vertex_buffer_data[ vectorIndex + 7 ] = 0.0;
g_vertex_buffer_data[ vectorIndex + 8 ] = 0.0;
g_vertex_buffer_data[ vectorIndex + 9 ] = 0.5 - index;
g_vertex_buffer_data[ vectorIndex + 10 ] = 0.5;
g_vertex_buffer_data[ vectorIndex + 11 ] = 0.0;
}
GLfloat g_vertex_buffer_data[] = {
0.0, 0.0, 0.0f,
0.0, 0.5, 0.0f,
0.5f, 0.0f, 0.0f,
.5, 0.5, 0.0
};
*/
}
}