1
0
mirror of https://github.com/thes3m/XNI synced 2024-12-26 13:26:06 +01:00
XNI/Classes/Retronator/Xni/Framework/Graphics/ReachGraphicsDevice.m
Matej Jan d04d7bf8f3 All around update and fixes
git-svn-id: http://xni.googlecode.com/svn/XNI@104 ac433895-eea3-a490-d80a-17149a75e588
2012-05-14 08:40:49 +00:00

283 lines
9.6 KiB
Objective-C

//
// ReachGraphicsDevice.m
// XNI
//
// Created by Matej Jan on 27.7.10.
// Copyright 2010 Retronator. All rights reserved.
//
#import "ReachGraphicsDevice.h"
#import "Retronator.Xni.Framework.Graphics.h"
#import "VertexBuffer+Internal.h"
#import "IndexBuffer+Internal.h"
@interface ReachGraphicsDevice()
- (void) drawUserIndexedPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(void*)vertexData
vertexOffset:(int)vertexOffset
numVertices:(int)numVertices
indexData:(void*)indexData
indexOffset:(int)indexOffset
primitiveCount:(int)primitiveCount
vertexDeclaration:(VertexDeclaration*) vertexDeclaration
indexElementSize:(IndexElementSize)indexElementSize;
- (void) enableVertexBuffers;
- (void) disableVertexBuffers;
- (void) enableDeclaration:(VertexDeclaration*)vertexDeclaration forUserData:(void*)data;
- (void) enableDeclaration:(VertexDeclaration*)vertexDeclaration onStream:(int)stream useBuffers:(BOOL)useBuffers pointer:(void*)pointer;
- (void) disableDeclaration:(VertexDeclaration*)vertexDeclaration;
@end
@implementation ReachGraphicsDevice
- (id)initWithGame:(Game *)theGame {
self = [super initWithGame:theGame];
if (self) {
// Disable lights.
for (int i=0; i<8; i++) {
lightsActive[i] = false;
glDisable(GL_LIGHT0 + i);
}
}
return self;
}
- (EAGLContext*) createContext {
return [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1] autorelease];
}
- (void) drawPrimitivesOfType:(PrimitiveType)primitiveType
startVertex:(int)startVertex
primitiveCount:(int)primitiveCount
{
[self enableVertexBuffers];
int count = [GraphicsDevice getNumberOfVerticesForPrimitiveType:primitiveType primitiveCount:primitiveCount];
glDrawArrays(primitiveType, 0, count);
[self disableVertexBuffers];
}
- (void) drawIndexedPrimitivesOfType:(PrimitiveType)primitiveType
baseVertex:(int)baseVertex
minVertexIndex:(int)minVertexIndex
numVertices:(int)numVertices
startIndex:(int)startIndex
primitiveCount:(int)primitiveCount
{
[self enableVertexBuffers];
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices.bufferID);
int count = [GraphicsDevice getNumberOfVerticesForPrimitiveType:primitiveType primitiveCount:primitiveCount];
GLenum type = 0;
switch (indices.indexElementSize) {
case IndexElementSizeSixteenBits:
type = DataTypeUnsignedShort;
break;
}
void *startIndexPointer = (void*)(startIndex * indices.indexElementSize);
glDrawElements(primitiveType, count, type, startIndexPointer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
[self disableVertexBuffers];
}
- (void) drawUserPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(VertexArray*)vertexData
vertexOffset:(int)vertexOffset
primitiveCount:(int)primitiveCount
{
[self drawUserPrimitivesOfType:primitiveType
vertexData:vertexData.array
vertexOffset:vertexOffset
primitiveCount:primitiveCount
vertexDeclaration:vertexData.vertexDeclaration];
}
- (void) drawUserPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(void*)vertexData
vertexOffset:(int)vertexOffset
primitiveCount:(int)primitiveCount
vertexDeclaration:(VertexDeclaration*) vertexDeclaration
{
[self enableDeclaration:vertexDeclaration forUserData:(vertexData + vertexOffset * vertexDeclaration.vertexStride)];
int count = [GraphicsDevice getNumberOfVerticesForPrimitiveType:primitiveType primitiveCount:primitiveCount];
glDrawArrays(primitiveType, 0, count);
[self disableDeclaration:vertexDeclaration];
}
- (void) drawUserIndexedPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(VertexArray*)vertexData
vertexOffset:(int)vertexOffset
numVertices:(int)numVertices
indexData:(IndexArray*)indexData
indexOffset:(int)indexOffset
primitiveCount:(int)primitiveCount
{
[self drawUserIndexedPrimitivesOfType:primitiveType
vertexData:vertexData.array
vertexOffset:vertexOffset
numVertices:numVertices
indexData:indexData.array
indexOffset:indexOffset
primitiveCount:primitiveCount
vertexDeclaration:vertexData.vertexDeclaration
indexElementSize:indexData.indexElementSize];
}
- (void) drawUserIndexedPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(void*)vertexData
vertexOffset:(int)vertexOffset
numVertices:(int)numVertices
shortIndexData:(void*)indexData
indexOffset:(int)indexOffset
primitiveCount:(int)primitiveCount
vertexDeclaration:(VertexDeclaration*) vertexDeclaration
{
[self drawUserIndexedPrimitivesOfType:primitiveType
vertexData:vertexData
vertexOffset:vertexOffset
numVertices:numVertices
indexData:indexData
indexOffset:indexOffset
primitiveCount:primitiveCount
vertexDeclaration:vertexDeclaration
indexElementSize:IndexElementSizeSixteenBits];
}
- (void) drawUserIndexedPrimitivesOfType:(PrimitiveType)primitiveType
vertexData:(void*)vertexData
vertexOffset:(int)vertexOffset
numVertices:(int)numVertices
indexData:(void*)indexData
indexOffset:(int)indexOffset
primitiveCount:(int)primitiveCount
vertexDeclaration:(VertexDeclaration*) vertexDeclaration
indexElementSize:(IndexElementSize)indexElementSize
{
[self enableDeclaration:vertexDeclaration forUserData:(vertexData + vertexOffset * vertexDeclaration.vertexStride)];
int count = [GraphicsDevice getNumberOfVerticesForPrimitiveType:primitiveType primitiveCount:primitiveCount];
GLenum type = 0;
switch (indexElementSize) {
case IndexElementSizeSixteenBits:
type = DataTypeUnsignedShort;
break;
}
void *startIndex = indexData + indexOffset * indexElementSize;
glDrawElements(primitiveType, count, type, startIndex);
[self disableDeclaration:vertexDeclaration];
}
- (void)setLight:(uint)lightname to:(BOOL)value {
int index = lightname - GL_LIGHT0;
if (value != lightsActive[index]) {
lightsActive[index] = value;
if (value) {
glEnable(lightname);
} else {
glDisable(lightname);
}
}
}
// Private methods
- (void) enableVertexBuffers {
// We need to enable the declarations set on the vertex buffers.
for (int i=0;i<[vertices count];i++) {
VertexBufferBinding *binding = [vertices objectAtIndex:i];
[self enableDeclaration:binding.vertexBuffer.vertexDeclaration
onStream:i useBuffers:YES pointer:(void*)binding.vertexOffset];
}
}
- (void) enableDeclaration:(VertexDeclaration*)vertexDeclaration forUserData:(void*)data {
[self enableDeclaration:vertexDeclaration onStream:0 useBuffers:NO pointer:data];
}
- (void) enableDeclaration:(VertexDeclaration *)vertexDeclaration onStream:(int)stream useBuffers:(BOOL)useBuffers pointer:(void*)pointer {
NSArray *vertexElements = vertexDeclaration.vertexElements;
int stride = vertexDeclaration.vertexStride;
for (VertexElement *vertexElement in vertexElements) {
if (useBuffers) {
// Bind the buffer the vertex element is using.
VertexBufferBinding* binding = [vertices objectAtIndex:stream];
glBindBuffer(GL_ARRAY_BUFFER, binding.vertexBuffer.bufferID);
}
// Enable the state that the vertex element represents.
glEnableClientState(vertexElement.vertexElementUsage);
// Create the pointer to the vertex element data.
switch (vertexElement.vertexElementUsage) {
case VertexElementUsagePosition:
glVertexPointer([vertexElement getValueDimensions], [vertexElement getValueDataType],
stride, pointer + vertexElement.offset);
break;
case VertexElementUsageNormal:
glNormalPointer([vertexElement getValueDataType],
stride, pointer + vertexElement.offset);
break;
case VertexElementUsageTextureCoordinate:
glTexCoordPointer([vertexElement getValueDimensions], [vertexElement getValueDataType],
stride, pointer + vertexElement.offset);
break;
case VertexElementUsageColor:
glColorPointer([vertexElement getValueDimensions], [vertexElement getValueDataType],
stride, pointer + vertexElement.offset);
break;
case VertexElementUsagePointSize:
glPointSizePointerOES([vertexElement getValueDataType],
stride, pointer + vertexElement.offset);
break;
default:
[NSException raise:@"NotImplementedException"
format:@"The vertex element usage %i is not yet implemented.", vertexElement.vertexElementUsage];
break;
}
}
}
- (void) disableVertexBuffers {
// We need to disable the declarations set on the vertex buffers.
for (int i=0;i<[vertices count];i++) {
VertexBufferBinding *binding = [vertices objectAtIndex:i];
[self disableDeclaration:binding.vertexBuffer.vertexDeclaration];
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- (void) disableDeclaration:(VertexDeclaration*)vertexDeclaration {
NSArray *vertexElements = vertexDeclaration.vertexElements;
for (VertexElement *vertexElement in vertexElements) {
// Enable the state that the vertex element represents.
glDisableClientState(vertexElement.vertexElementUsage);
}
}
@end