early screenblock commit
This commit is contained in:
parent
fbd8932a33
commit
ea87aed73a
8 changed files with 357 additions and 6 deletions
2
bitmap.h
2
bitmap.h
|
@ -42,6 +42,8 @@ public:
|
|||
int x() const { return x_; }
|
||||
int y() const { return y_; }
|
||||
|
||||
char * getData() { return data_[curr_image_]; }
|
||||
|
||||
~Bitmap();
|
||||
|
||||
private:
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <SDL_opengl.h>
|
||||
#include <SDL_timer.h>
|
||||
#include <assert.h>
|
||||
#include "screen.h"
|
||||
|
||||
Engine *Engine::instance_ = NULL;
|
||||
|
||||
|
@ -84,6 +85,8 @@ void Engine::mainLoop() {
|
|||
// Run asynchronous tasks
|
||||
lua_runtasks();
|
||||
|
||||
screenBlocksReset();
|
||||
|
||||
// Update actor costumes
|
||||
for (actor_list_type::iterator i = actors_.begin();
|
||||
i != actors_.end(); i++) {
|
||||
|
@ -96,6 +99,8 @@ void Engine::mainLoop() {
|
|||
// Draw the screen
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
screenBlocksBlitDirtyBlocks();
|
||||
|
||||
Bitmap::prepareGL();
|
||||
if (currScene_ != NULL)
|
||||
currScene_->drawBackground();
|
||||
|
@ -114,6 +119,8 @@ void Engine::mainLoop() {
|
|||
}
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// screenBlocksDrawDebug();
|
||||
|
||||
// Draw text
|
||||
for (text_list_type::iterator i = textObjects_.begin();
|
||||
i != textObjects_.end(); i++) {
|
||||
|
|
42
model.cpp
42
model.cpp
|
@ -25,6 +25,7 @@
|
|||
#include <cstring>
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#include "screen.h"
|
||||
|
||||
Model::Model(const char *filename, const char *data, int len,
|
||||
const Colormap &cmap) : Resource(filename)
|
||||
|
@ -485,7 +486,7 @@ void Model::HierNode::update() {
|
|||
void Model::Mesh::draw() const {
|
||||
for (int i = 0; i < numFaces_; i++)
|
||||
faces_[i].draw(vertices_, vertNormals_, textureVerts_);
|
||||
|
||||
/*
|
||||
// Yaz: debug
|
||||
// this draw the model node in red
|
||||
|
||||
|
@ -563,6 +564,7 @@ void Model::Mesh::draw() const {
|
|||
Matrix4 tempMatrix = matrix_;
|
||||
float* pVertices;
|
||||
int j;
|
||||
float bestDepth = 0;
|
||||
|
||||
for( j =0; j< faces_[i].numVertices_; j++ )
|
||||
{
|
||||
|
@ -588,9 +590,45 @@ void Model::Mesh::draw() const {
|
|||
if( winY > bottom )
|
||||
bottom = winY;
|
||||
|
||||
if( winZ> bestDepth )
|
||||
bestDepth = winZ;
|
||||
|
||||
}
|
||||
|
||||
screenBlocksAddRectangle( top, right, left, bottom, bestDepth );
|
||||
/*
|
||||
if( faces_[i].numVertices_ == 3 ) // triangle
|
||||
{
|
||||
float* pVertices0;
|
||||
float* pVertices1;
|
||||
float* pVertices2;
|
||||
|
||||
pVertices0 = vertices_ + 3 * faces_[i].vertices_[0];
|
||||
pVertices1 = vertices_ + 3 * faces_[i].vertices_[1];
|
||||
pVertices2 = vertices_ + 3 * faces_[i].vertices_[2];
|
||||
|
||||
// screenBlocksAddTriangle( pVertices0, pVertices1, pVertices2 );
|
||||
}
|
||||
else
|
||||
if( faces_[i].numVertices_ == 4 ) // quad
|
||||
{
|
||||
float* pVertices0;
|
||||
float* pVertices1;
|
||||
float* pVertices2;
|
||||
float* pVertices3;
|
||||
|
||||
pVertices0 = vertices_ + 3 * faces_[i].vertices_[0];
|
||||
pVertices1 = vertices_ + 3 * faces_[i].vertices_[1];
|
||||
pVertices2 = vertices_ + 3 * faces_[i].vertices_[2];
|
||||
pVertices3 = vertices_ + 3 * faces_[i].vertices_[3];
|
||||
|
||||
// screenBlocksAddTriangle( pVertices0, pVertices1, pVertices2, pVertices3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bad primitive !\n");
|
||||
} */
|
||||
/* }
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glPointSize( 3.f );
|
||||
|
@ -630,7 +668,7 @@ void Model::Mesh::draw() const {
|
|||
glEnd();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_TEXTURE_2D );
|
||||
glPopMatrix();
|
||||
glPopMatrix();*/
|
||||
}
|
||||
|
||||
void Model::Face::draw(float *vertices, float *vertNormals,
|
||||
|
|
|
@ -215,6 +215,12 @@
|
|||
<File
|
||||
RelativePath="scene.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="screen.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="screen.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sound.cpp">
|
||||
</File>
|
||||
|
|
10
scene.cpp
10
scene.cpp
|
@ -26,6 +26,7 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#include <cmath>
|
||||
#include "screen.h"
|
||||
|
||||
Scene::Scene(const char *name, const char *buf, int len) :
|
||||
name_(name) {
|
||||
|
@ -164,3 +165,12 @@ void Scene::Setup::setupCamera() const {
|
|||
interest_.x(), interest_.y(), interest_.z(),
|
||||
up_vec.x(), up_vec.y(), up_vec.z());
|
||||
}
|
||||
|
||||
void Scene::setSetup(int num)
|
||||
{
|
||||
currSetup_ = setups_ + num;
|
||||
if(currSetup_->bkgnd_zbm_)
|
||||
screenBlocksInit( currSetup_->bkgnd_zbm_->getData() );
|
||||
else
|
||||
screenBlocksInitEmpty();
|
||||
}
|
||||
|
|
2
scene.h
2
scene.h
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
const char *name() const { return name_.c_str(); }
|
||||
|
||||
void setSetup(int num) { currSetup_ = setups_ + num; }
|
||||
void setSetup(int num);
|
||||
int setup() const { return currSetup_ - setups_; }
|
||||
|
||||
// Sector access functions
|
||||
|
|
254
screen.cpp
Normal file
254
screen.cpp
Normal file
|
@ -0,0 +1,254 @@
|
|||
#include "screen.h"
|
||||
|
||||
unsigned short int dataTemp[640*480];
|
||||
|
||||
screenBlockDataStruct screenBlockData[NUM_SCREEN_BLOCK_WIDTH][NUM_SCREEN_BLOCK_HEIGHT];
|
||||
|
||||
void screenBlocksReset()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for( i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++ )
|
||||
{
|
||||
for( j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++ )
|
||||
{
|
||||
screenBlockData[i][j].isDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float getZbufferBlockDepth( char* zbuffer, int x, int y )
|
||||
{
|
||||
unsigned short int buffer[SCREEN_BLOCK_WIDTH * SCREEN_BLOCK_HEIGHT];
|
||||
char* readPtr;
|
||||
char* writePtr;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
writePtr = (char*)buffer;
|
||||
|
||||
for( i = 0; i <16; i++)
|
||||
{
|
||||
readPtr = zbuffer + (y*16+i) * 640 + (x*16);
|
||||
for(j=0; j<16; j++)
|
||||
{
|
||||
*(writePtr++) = *(readPtr++);
|
||||
*(writePtr++) = *(readPtr++);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned short int bDepth = 0xFFFF;
|
||||
|
||||
for( i = 0; i<SCREEN_BLOCK_SIZE; i++ )
|
||||
{
|
||||
if(bDepth > buffer[i])
|
||||
bDepth = buffer[i];
|
||||
}
|
||||
|
||||
return ((float)bDepth/65535);
|
||||
}
|
||||
|
||||
void screenBlocksInit(char* zbuffer)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
memcpy( dataTemp, zbuffer, 640*480*2);
|
||||
|
||||
for( i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++ )
|
||||
{
|
||||
for( j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++ )
|
||||
{
|
||||
screenBlockData[i][j].isDirty = false;
|
||||
screenBlockData[i][j].depth = getZbufferBlockDepth( zbuffer, i, j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void screenBlocksInitEmpty()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for( i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++ )
|
||||
{
|
||||
for( j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++ )
|
||||
{
|
||||
screenBlockData[i][j].isDirty = false;
|
||||
screenBlockData[i][j].depth = 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void screenBlocksAddRectangle( int top, int right, int left, int bottom, float depth )
|
||||
{
|
||||
// clip the rectange to the screen size
|
||||
|
||||
if(top<0)
|
||||
top = 0;
|
||||
if(top>=SCREEN_HEIGHT)
|
||||
top = SCREEN_HEIGHT-1;
|
||||
|
||||
if(bottom<0)
|
||||
bottom = 0;
|
||||
if(bottom>=SCREEN_HEIGHT)
|
||||
bottom = SCREEN_HEIGHT-1;
|
||||
|
||||
if(left<0)
|
||||
left = 0;
|
||||
if(left>=SCREEN_WIDTH)
|
||||
left = SCREEN_WIDTH-1;
|
||||
|
||||
if(right<0)
|
||||
right = 0;
|
||||
if(right>=SCREEN_WIDTH)
|
||||
right = SCREEN_WIDTH-1;
|
||||
|
||||
// exit in case of bad rectangle
|
||||
if((left > right) || (top > bottom))
|
||||
return;
|
||||
|
||||
int firstLeft;
|
||||
int firstTop;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
firstLeft = left / 16;
|
||||
firstTop = top /16;
|
||||
|
||||
width = (right - left) / 16;
|
||||
if((right-left)%16)
|
||||
width++;
|
||||
|
||||
height = (bottom - top) / 16;
|
||||
if((bottom - top)%16)
|
||||
height++;
|
||||
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for(i=firstLeft; i<firstLeft+width; i++)
|
||||
{
|
||||
for(j=firstTop; j<firstTop+height; j++)
|
||||
{
|
||||
if(screenBlockData[i][j].depth < depth)
|
||||
screenBlockData[i][j].isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void screenBlocksDrawDebug()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
GLdouble modelView[500];
|
||||
GLdouble projection[500];
|
||||
GLint viewPort[500];
|
||||
|
||||
glGetDoublev( GL_MODELVIEW_MATRIX, modelView );
|
||||
glGetDoublev( GL_PROJECTION_MATRIX, projection );
|
||||
glGetIntegerv( GL_VIEWPORT, viewPort);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glPointSize( 3.f );
|
||||
glColor4f( 1.f, 0.f, 1.f, 1.f );
|
||||
glDisable(GL_TEXTURE_2D );
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
GLdouble objx;
|
||||
GLdouble objy;
|
||||
GLdouble objz;
|
||||
|
||||
for(i=0;i<40;i++)
|
||||
{
|
||||
for(j=0;j<30;j++)
|
||||
{
|
||||
if(screenBlockData[i][j].isDirty)
|
||||
{
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
|
||||
|
||||
/*glColor3ub( 255, 255, 0 );
|
||||
glVertex2i(i*16,j*16);
|
||||
glVertex2i((i+1)*16,j*16);
|
||||
glVertex2i((i+1)*16,(j+1)*16);
|
||||
glVertex2i(i*16,(j+1)*16);
|
||||
*/
|
||||
|
||||
left = i*16;
|
||||
right = (i+1)*16;
|
||||
top = j*16;
|
||||
bottom = (j+1)*16;
|
||||
|
||||
|
||||
// top
|
||||
gluUnProject( left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
gluUnProject( right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
|
||||
// bottom
|
||||
gluUnProject( left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
gluUnProject( right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
|
||||
// left
|
||||
gluUnProject( left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
gluUnProject( left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
|
||||
// right
|
||||
gluUnProject( right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
gluUnProject( right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
|
||||
glVertex3f( objx, objy, objz );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_TEXTURE_2D );
|
||||
|
||||
}
|
||||
|
||||
void screenBlocksBlitDirtyBlocks()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for(i=0;i<40;i++)
|
||||
{
|
||||
for(j=0;j<30;j++)
|
||||
{
|
||||
// if(screenBlockData[i][j].isDirty)
|
||||
{
|
||||
glRasterPos2i(j*16, i*16);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_TRUE);
|
||||
/* This loop here is to prevent using PixelZoom that may be unoptimized for the 1.0 / -1.0 case
|
||||
in some drivers...
|
||||
*/
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
glRasterPos2i(j*16, i*16 + y + 1);
|
||||
glDrawPixels(16, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, dataTemp+((i*16 +y +1) * 640)+(j*16));
|
||||
}
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
screen.h
Normal file
34
screen.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef _SCREEN_H_
|
||||
#define _SCREEN_H_
|
||||
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
#define SCREEN_WIDTH 640
|
||||
#define SCREEN_HEIGHT 480
|
||||
|
||||
#define SCREEN_BLOCK_WIDTH 16
|
||||
#define SCREEN_BLOCK_HEIGHT 16
|
||||
|
||||
#define SCREEN_BLOCK_SIZE (SCREEN_BLOCK_WIDTH*SCREEN_BLOCK_HEIGHT)
|
||||
|
||||
// Yaz: warning, SCREEN_WIDTH must be divisible by SCREEN_BLOCK_WIDTH and SCREEN_HEIGHT by SCREEN_BLOCK_HEIGH
|
||||
// maybe we should check it with the precompiler...
|
||||
#define NUM_SCREEN_BLOCK_WIDTH (SCREEN_WIDTH / SCREEN_BLOCK_WIDTH)
|
||||
#define NUM_SCREEN_BLOCK_HEIGHT (SCREEN_HEIGHT / SCREEN_BLOCK_HEIGHT)
|
||||
|
||||
#define NUM_SCREEN_BLOCKS (NUM_SCREEN_BLOCK_WIDTH * NUM_SCREEN_BLOCK_HEIGHT)
|
||||
|
||||
struct screenBlockDataStruct
|
||||
{
|
||||
bool isDirty;
|
||||
float depth;
|
||||
};
|
||||
|
||||
void screenBlocksReset();
|
||||
void screenBlocksInit(char* zbuffer);
|
||||
void screenBlocksInitEmpty();
|
||||
void screenBlocksAddRectangle( int top, int right, int left, int bottom, float depth );
|
||||
void screenBlocksDrawDebug();
|
||||
void screenBlocksBlitDirtyBlocks();
|
||||
|
||||
#endif // _SCREEN_H_
|
Loading…
Add table
Add a link
Reference in a new issue