mygl.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 362 行
CPP
362 行
#include "StdAfx.h"
#include "myGL.h"
#include <GL/glu.h>
#include "Rendering/glFont.h"
#include <ostream>
#include <fstream>
#include "VertexArray.h"
#include "VertexArrayRange.h"
#include "FileSystem/FileHandler.h"
#include "Game/GameVersion.h"
#include "Rendering/Textures/Bitmap.h"
#include "Platform/errorhandler.h"
#include "LogOutput.h"
#include "FPUCheck.h"
#include <SDL.h>
#include "mmgr.h"
#include "IFramebuffer.h"
using namespace std;
static CVertexArray* vertexArray1 = 0;
static CVertexArray* vertexArray2 = 0;
static CVertexArray* currentVertexArray = 0;
static GLuint startupTexture = 0;
/******************************************************************************/
/******************************************************************************/
CVertexArray* GetVertexArray()
{
if(currentVertexArray==vertexArray1){
currentVertexArray=vertexArray2;
} else {
currentVertexArray=vertexArray1;
}
return currentVertexArray;
}
/******************************************************************************/
void LoadExtensions()
{
glewInit();
// log some useful version info
logOutput.Print("SDL: %d.%d.%d\n",
SDL_Linked_Version()->major,
SDL_Linked_Version()->minor,
SDL_Linked_Version()->patch);
logOutput.Print("GL: %s\n", glGetString(GL_VERSION));
logOutput.Print("GL: %s\n", glGetString(GL_VENDOR));
logOutput.Print("GL: %s\n", glGetString(GL_RENDERER));
logOutput.Print("GLEW: %s\n", glewGetString(GLEW_VERSION));
if(!GLEW_ARB_multitexture || !GLEW_ARB_texture_env_combine){
handleerror(0,"Needed extension GL_ARB_texture_env_combine not found","Update drivers",0);
exit(0);
}
if(!GLEW_ARB_texture_compression){
handleerror(0,"Needed extension GL_ARB_texture_compression not found","Update drivers",0);
exit(0);
}
vertexArray1=SAFE_NEW CVertexArray;
vertexArray2=SAFE_NEW CVertexArray;
std::string s= (char*)glGetString(GL_EXTENSIONS);
for (unsigned int i=0; i<s.length(); i++)
if (s[i]==' ') s[i]='\n';
std::ofstream ofs("ext.txt");
if (!ofs.bad() && ofs.is_open())
ofs.write(s.c_str(), s.length());
}
void UnloadExtensions()
{
delete vertexArray1;
delete vertexArray2;
}
/******************************************************************************/
static void AppendStringVec(vector<string>& dst, const vector<string>& src)
{
for (int i = 0; i < (int)src.size(); i++) {
dst.push_back(src[i]);
}
}
static string SelectPicture(const std::string& dir, const std::string& prefix)
{
vector<string> pics;
AppendStringVec(pics, CFileHandler::FindFiles(dir, prefix + "*.bmp"));
AppendStringVec(pics, CFileHandler::FindFiles(dir, prefix + "*.jpg"));
// add 'allside_' pictures if we have a prefix
if (!prefix.empty()) {
AppendStringVec(pics, CFileHandler::FindFiles(dir, "allside_*.bmp"));
AppendStringVec(pics, CFileHandler::FindFiles(dir, "allside_*.jpg"));
}
if (pics.empty()) {
return "";
}
return pics[gu->usRandInt() % pics.size()];
}
void LoadStartPicture(const std::string& sidePref)
{
const string picDir = "bitmaps/loadpictures/";
string name = "";
if (!sidePref.empty()) {
name = SelectPicture(picDir, sidePref + "_");
}
if (name.empty()) {
name = SelectPicture(picDir, "");
}
if (name.empty()) {
return; // no valid pictures
}
CBitmap bm;
if (!bm.Load(name)) {
throw content_error("Could not load startpicture from file " + name);
}
/* HACK Really big load pictures made a GLU choke. */
if ((bm.xsize > gu->viewSizeX) || (bm.ysize > gu->viewSizeY)) {
bm = bm.CreateRescaled(gu->viewSizeX, gu->viewSizeY);
}
startupTexture = bm.CreateTexture(false);
}
void UnloadStartPicture()
{
if (startupTexture) {
glDeleteTextures(1, &startupTexture);
}
startupTexture = 0;
}
/******************************************************************************/
void PrintLoadMsg(const char* text, bool swapbuffers)
{
static char prevText[100];
static unsigned startTicks;
PUSH_CODE_MODE;
// Stuff that needs to be done regularly while loading.
// Totally unrelated to the task the name of this function implies.
ENTER_MIXED;
// Check to prevent infolog spam by CPreGame which uses this function
// to render the screen background each frame.
if (strcmp(prevText, text)) {
unsigned ticks = SDL_GetTicks();
// if (prevText[0])
// logOutput.Print("Loading step `%s' took %g seconds", prevText, (ticks - startTicks) / 1000.0f);
logOutput.Print("%s",text);
strncpy(prevText, text, sizeof(prevText));
prevText[sizeof(prevText) - 1] = 0;
startTicks = ticks;
}
good_fpu_control_registers(text);
// Draw loading screen & print load msg.
ENTER_UNSYNCED;
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
gluOrtho2D(0,1,0,1);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
if(startupTexture){
glBindTexture(GL_TEXTURE_2D,startupTexture);
glBegin(GL_QUADS);
glTexCoord2f(0,1);glVertex2f(0,0);
glTexCoord2f(0,0);glVertex2f(0,1);
glTexCoord2f(1,0);glVertex2f(1,1);
glTexCoord2f(1,1);glVertex2f(1,0);
glEnd();
}
font->glPrintCentered (0.5f,0.48f, 2.0f, text);
font->glPrintCentered(0.5f,0.06f,1.0f,"Spring %s", VERSION_STRING);
font->glPrintCentered(0.5f,0.02f,0.6f,"This program is distributed under the GNU General Public License, see license.html for more info");
if (swapbuffers)
SDL_GL_SwapBuffers();
POP_CODE_MODE;
}
/******************************************************************************/
/**
* True if the program in DATADIR/shaders/filename is
* loadable and can run inside our graphics server.
*
* @param target glProgramStringARB target: GL_FRAGMENT_PROGRAM_ARB GL_VERTEX_PROGRAM_ARB
* @param filename Name of the file under shaders with the program in it.
*/
bool ProgramStringIsNative(GLenum target, const char* filename)
{
GLuint tempProg;
GLint errorPos, isNative;
if(!GLEW_ARB_vertex_program)
return false;
if(target==GL_FRAGMENT_PROGRAM_ARB && !GLEW_ARB_fragment_program)
return false;
CFileHandler VPFile(std::string("shaders/")+filename);
if (!VPFile.FileExists ())
{
logOutput << "Warning: ProgramStringIsNative couldn't find " << filename << ".\n";
return false;
}
char *VPbuf = SAFE_NEW char[VPFile.FileSize()];
VPFile.Read(VPbuf, VPFile.FileSize());
// clear any current GL errors so that the following check is valid
glClearErrors();
glGenProgramsARB( 1, &tempProg );
glBindProgramARB( target,tempProg);
glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB, VPFile.FileSize(), VPbuf);
if ( GL_INVALID_OPERATION == glGetError() )
{
return false;
}
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
glGetProgramivARB(target, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &isNative);
glSafeDeleteProgram( tempProg);
delete[] VPbuf;
if ((errorPos == -1) && (isNative == 1))
return true;
else
return false;
}
/**
* Presumes the last GL operation was to load a vertex or
* fragment program.
*
* If it was invalid, display an error
* message about what and where the problem in the program
* is, and exit.
*
* @param program_type Only substituted in the message.
* @param filename Only substituted in the message.
*/
static void CheckParseErrors(const char * program_type, const char * filename, const char* program)
{
if ( glGetError() != GL_INVALID_OPERATION )
return;
// Find the error position
GLint errPos;
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB,&errPos );
// Print implementation-dependent program
// errors and warnings string.
const GLubyte *errString=glGetString( GL_PROGRAM_ERROR_STRING_ARB);
char c[512];
SNPRINTF(c,512,"Error at position %d near \"%.30s\" when loading %s program file %s",
errPos, program+errPos, program_type, filename);
throw content_error(c);
}
static unsigned int LoadProgram(GLenum target, const char* filename, const char * program_type)
{
GLuint ret = 0;
if (!GLEW_ARB_vertex_program) {
return 0;
}
CFileHandler VPFile(std::string("shaders/")+filename);
if (!VPFile.FileExists ())
{
char c[512];
SNPRINTF(c,512,"Cannot find %s program file '%s'", program_type, filename);
throw content_error(c);
}
char *VPbuf = SAFE_NEW char[VPFile.FileSize()];
VPFile.Read(VPbuf, VPFile.FileSize());
glGenProgramsARB( 1, &ret );
glBindProgramARB( target,ret);
glProgramStringARB( target,GL_PROGRAM_FORMAT_ASCII_ARB,VPFile.FileSize(), VPbuf );
CheckParseErrors(program_type, filename, VPbuf);
delete[] VPbuf;
return ret;
}
unsigned int LoadVertexProgram(const char* filename)
{
return LoadProgram(GL_VERTEX_PROGRAM_ARB, filename, "vertex");
}
unsigned int LoadFragmentProgram(const char* filename)
{
return LoadProgram(GL_FRAGMENT_PROGRAM_ARB, filename, "fragment");
}
void glSafeDeleteProgram(GLuint program)
{
if (!GLEW_ARB_vertex_program || (program == 0)) {
return;
}
glDeleteProgramsARB(1, &program);
}
/******************************************************************************/
void glClearErrors()
{
int safety = 0;
while ((glGetError() != GL_NO_ERROR) && (safety < 1000)) {
safety++;
}
}
/******************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?