early screenblock commit

This commit is contained in:
Vincent Hamm 2003-08-30 17:58:33 +00:00
parent fbd8932a33
commit ea87aed73a
8 changed files with 357 additions and 6 deletions

View file

@ -42,6 +42,8 @@ public:
int x() const { return x_; }
int y() const { return y_; }
char * getData() { return data_[curr_image_]; }
~Bitmap();
private:

View file

@ -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++) {

View file

@ -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,

View file

@ -215,6 +215,12 @@
<File
RelativePath="scene.h">
</File>
<File
RelativePath="screen.cpp">
</File>
<File
RelativePath="screen.h">
</File>
<File
RelativePath="sound.cpp">
</File>

View file

@ -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();
}

View file

@ -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
View 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
View 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_